aboutsummaryrefslogtreecommitdiff
path: root/packages/integrations/node/test/fixtures
diff options
context:
space:
mode:
authorGravatar github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 2025-06-05 14:25:23 +0000
committerGravatar github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 2025-06-05 14:25:23 +0000
commite586d7d704d475afe3373a1de6ae20d504f79d6d (patch)
tree7e3fa24807cebd48a86bd40f866d792181191ee9 /packages/integrations/node/test/fixtures
downloadastro-e586d7d704d475afe3373a1de6ae20d504f79d6d.tar.gz
astro-e586d7d704d475afe3373a1de6ae20d504f79d6d.tar.zst
astro-e586d7d704d475afe3373a1de6ae20d504f79d6d.zip
Sync from a8e1c0a7402940e0fc5beef669522b315052df1blatest
Diffstat (limited to 'packages/integrations/node/test/fixtures')
-rw-r--r--packages/integrations/node/test/fixtures/api-route/astro.config.mjs7
-rw-r--r--packages/integrations/node/test/fixtures/api-route/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/astro-redirect.astro3
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts11
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts16
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/recipes.js24
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/redirect.ts5
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/response-redirect.ts5
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/streaming.ts22
-rw-r--r--packages/integrations/node/test/fixtures/bad-urls/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/bad-urls/src/pages/index.astro1
-rw-r--r--packages/integrations/node/test/fixtures/encoded/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/encoded/src/pages/blog/什么.md1
-rw-r--r--packages/integrations/node/test/fixtures/encoded/src/pages/什么.astro1
-rw-r--r--packages/integrations/node/test/fixtures/errors/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/errors/src/pages/generator.astro11
-rw-r--r--packages/integrations/node/test/fixtures/errors/src/pages/in-stream.astro13
-rw-r--r--packages/integrations/node/test/fixtures/errors/src/pages/offshoot-promise-rejection.astro2
-rw-r--r--packages/integrations/node/test/fixtures/headers/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-cookies-multi.astro5
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-cookies-single.astro4
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-response-cookie-multi.astro7
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-response-cookie-single.astro5
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/astro/component-response-cookies-multi.astro5
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/astro/component-response-cookies-single.astro4
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-cookies-multi.ts9
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-cookies-single.ts8
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-response-cookie-multi.ts11
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-response-cookie-single.ts9
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/kitchen-sink.ts11
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-cookies-multi.ts7
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-cookies-single.ts6
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-empty-headers-object.ts4
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-undefined-headers-object.ts3
-rw-r--r--packages/integrations/node/test/fixtures/headers/src/pages/endpoints/simple.ts6
-rw-r--r--packages/integrations/node/test/fixtures/image/package.json16
-rw-r--r--packages/integrations/node/test/fixtures/image/src/assets/file.txt1
-rw-r--r--packages/integrations/node/test/fixtures/image/src/assets/some_penguin.pngbin0 -> 285628 bytes
-rw-r--r--packages/integrations/node/test/fixtures/image/src/pages/[...catchall].astro8
-rw-r--r--packages/integrations/node/test/fixtures/image/src/pages/text-file.astro14
-rw-r--r--packages/integrations/node/test/fixtures/locals/astro.config.mjs7
-rw-r--r--packages/integrations/node/test/fixtures/locals/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/locals/src/middleware.ts6
-rw-r--r--packages/integrations/node/test/fixtures/locals/src/pages/api.js10
-rw-r--r--packages/integrations/node/test/fixtures/locals/src/pages/from-astro-middleware.astro4
-rw-r--r--packages/integrations/node/test/fixtures/locals/src/pages/from-node-middleware.astro4
-rw-r--r--packages/integrations/node/test/fixtures/node-middleware/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/node-middleware/src/pages/404.astro13
-rw-r--r--packages/integrations/node/test/fixtures/node-middleware/src/pages/index.astro11
-rw-r--r--packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts7
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/package.json10
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css3
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts17
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts17
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro5
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro6
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro4
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/pages/static.astro12
-rw-r--r--packages/integrations/node/test/fixtures/prerender/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/prerender/src/middleware.ts5
-rw-r--r--packages/integrations/node/test/fixtures/prerender/src/pages/one.astro10
-rw-r--r--packages/integrations/node/test/fixtures/prerender/src/pages/third.astro15
-rw-r--r--packages/integrations/node/test/fixtures/prerender/src/pages/two.astro11
-rw-r--r--packages/integrations/node/test/fixtures/prerender/src/shared.ts1
-rw-r--r--packages/integrations/node/test/fixtures/preview-headers/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/preview-headers/src/pages/index.astro1
-rw-r--r--packages/integrations/node/test/fixtures/sessions/astro.config.mjs6
-rw-r--r--packages/integrations/node/test/fixtures/sessions/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/sessions/src/actions/index.ts36
-rw-r--r--packages/integrations/node/test/fixtures/sessions/src/middleware.ts49
-rw-r--r--packages/integrations/node/test/fixtures/sessions/src/pages/api.ts13
-rw-r--r--packages/integrations/node/test/fixtures/sessions/src/pages/cart.astro24
-rw-r--r--packages/integrations/node/test/fixtures/sessions/src/pages/destroy.ts6
-rw-r--r--packages/integrations/node/test/fixtures/sessions/src/pages/index.astro13
-rw-r--r--packages/integrations/node/test/fixtures/sessions/src/pages/regenerate.ts6
-rw-r--r--packages/integrations/node/test/fixtures/sessions/src/pages/update.ts10
-rw-r--r--packages/integrations/node/test/fixtures/trailing-slash/astro.config.mjs8
-rw-r--r--packages/integrations/node/test/fixtures/trailing-slash/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/trailing-slash/public/one.css1
-rw-r--r--packages/integrations/node/test/fixtures/trailing-slash/src/assets/bitgeneva12.woff2bin0 -> 5196 bytes
-rw-r--r--packages/integrations/node/test/fixtures/trailing-slash/src/pages/index.astro17
-rw-r--r--packages/integrations/node/test/fixtures/trailing-slash/src/pages/one.astro11
-rw-r--r--packages/integrations/node/test/fixtures/url/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/url/src/pages/index.astro9
-rw-r--r--packages/integrations/node/test/fixtures/well-known-locations/package.json9
-rw-r--r--packages/integrations/node/test/fixtures/well-known-locations/public/.hidden/file.json1
-rw-r--r--packages/integrations/node/test/fixtures/well-known-locations/public/.well-known/apple-app-site-association3
87 files changed, 774 insertions, 0 deletions
diff --git a/packages/integrations/node/test/fixtures/api-route/astro.config.mjs b/packages/integrations/node/test/fixtures/api-route/astro.config.mjs
new file mode 100644
index 000000000..3eada8758
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/astro.config.mjs
@@ -0,0 +1,7 @@
+import { defineConfig} from "astro/config";
+
+export default defineConfig({
+ security: {
+ checkOrigin: false
+ }
+}) \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/api-route/package.json b/packages/integrations/node/test/fixtures/api-route/package.json
new file mode 100644
index 000000000..3fdb79cfe
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/nodejs-api-route",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/astro-redirect.astro b/packages/integrations/node/test/fixtures/api-route/src/pages/astro-redirect.astro
new file mode 100644
index 000000000..65a8765e8
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/astro-redirect.astro
@@ -0,0 +1,3 @@
+---
+return Astro.redirect('/destination', 303);
+---
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts b/packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts
new file mode 100644
index 000000000..b1c7ce263
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts
@@ -0,0 +1,11 @@
+
+export async function POST({ request }: { request: Request }) {
+ let body = await request.arrayBuffer();
+ let data = new Uint8Array(body);
+ let r = data.reverse();
+ return new Response(r, {
+ headers: {
+ 'Content-Type': 'application/octet-stream'
+ }
+ });
+}
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts b/packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts
new file mode 100644
index 000000000..3f1b236de
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts
@@ -0,0 +1,16 @@
+import crypto from 'node:crypto';
+
+export async function POST({ request }: { request: Request }) {
+ const hash = crypto.createHash('sha256');
+
+ const iterable = request.body as unknown as AsyncIterable<Uint8Array>;
+ for await (const chunk of iterable) {
+ hash.update(chunk);
+ }
+
+ return new Response(hash.digest(), {
+ headers: {
+ 'Content-Type': 'application/octet-stream'
+ }
+ });
+}
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/recipes.js b/packages/integrations/node/test/fixtures/api-route/src/pages/recipes.js
new file mode 100644
index 000000000..7297b9643
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/recipes.js
@@ -0,0 +1,24 @@
+
+export async function POST({ request }) {
+ let body = await request.json();
+ const recipes = [
+ {
+ id: 1,
+ name: 'Potato Soup'
+ },
+ {
+ id: 2,
+ name: 'Broccoli Soup'
+ }
+ ];
+
+ let out = recipes.filter(r => {
+ return r.id === body.id;
+ });
+
+ return new Response(JSON.stringify(out), {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });
+}
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/redirect.ts b/packages/integrations/node/test/fixtures/api-route/src/pages/redirect.ts
new file mode 100644
index 000000000..36f0e8cf4
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/redirect.ts
@@ -0,0 +1,5 @@
+import type { APIContext } from 'astro';
+
+export async function GET({ redirect }: APIContext) {
+ return redirect('/destination');
+}
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/response-redirect.ts b/packages/integrations/node/test/fixtures/api-route/src/pages/response-redirect.ts
new file mode 100644
index 000000000..cf16fb941
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/response-redirect.ts
@@ -0,0 +1,5 @@
+import type { APIContext } from 'astro';
+
+export async function GET({ url: requestUrl }: APIContext) {
+ return Response.redirect(new URL('/destination', requestUrl), 307);
+}
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/streaming.ts b/packages/integrations/node/test/fixtures/api-route/src/pages/streaming.ts
new file mode 100644
index 000000000..9ecb884bf
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/streaming.ts
@@ -0,0 +1,22 @@
+export const GET = ({ locals }) => {
+ let sentChunks = 0;
+
+ const readableStream = new ReadableStream({
+ async pull(controller) {
+ if (sentChunks === 3) return controller.close();
+ else sentChunks++;
+
+ await new Promise(resolve => setTimeout(resolve, 1000));
+ controller.enqueue(new TextEncoder().encode('hello\n'));
+ },
+ cancel() {
+ locals.cancelledByTheServer = true;
+ }
+ });
+
+ return new Response(readableStream, {
+ headers: {
+ "Content-Type": "text/event-stream"
+ }
+ });
+}
diff --git a/packages/integrations/node/test/fixtures/bad-urls/package.json b/packages/integrations/node/test/fixtures/bad-urls/package.json
new file mode 100644
index 000000000..8769aab8f
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/bad-urls/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/nodejs-badurls",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/bad-urls/src/pages/index.astro b/packages/integrations/node/test/fixtures/bad-urls/src/pages/index.astro
new file mode 100644
index 000000000..10ddd6d25
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/bad-urls/src/pages/index.astro
@@ -0,0 +1 @@
+Hello!
diff --git a/packages/integrations/node/test/fixtures/encoded/package.json b/packages/integrations/node/test/fixtures/encoded/package.json
new file mode 100644
index 000000000..53eb38989
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/encoded/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/nodejs-encoded",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/encoded/src/pages/blog/什么.md b/packages/integrations/node/test/fixtures/encoded/src/pages/blog/什么.md
new file mode 100644
index 000000000..2820cf17e
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/encoded/src/pages/blog/什么.md
@@ -0,0 +1 @@
+# 什么
diff --git a/packages/integrations/node/test/fixtures/encoded/src/pages/什么.astro b/packages/integrations/node/test/fixtures/encoded/src/pages/什么.astro
new file mode 100644
index 000000000..c8473f594
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/encoded/src/pages/什么.astro
@@ -0,0 +1 @@
+<h1>什么</h1>
diff --git a/packages/integrations/node/test/fixtures/errors/package.json b/packages/integrations/node/test/fixtures/errors/package.json
new file mode 100644
index 000000000..427e6f723
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/errors/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/nodejs-errors",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/errors/src/pages/generator.astro b/packages/integrations/node/test/fixtures/errors/src/pages/generator.astro
new file mode 100644
index 000000000..65b8ae62c
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/errors/src/pages/generator.astro
@@ -0,0 +1,11 @@
+---
+function * generator () {
+ yield 1
+ throw Error('ohnoes')
+}
+---
+<h1>Astro</h1>
+{generator()}
+<footer>
+ Footer
+</footer> \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/errors/src/pages/in-stream.astro b/packages/integrations/node/test/fixtures/errors/src/pages/in-stream.astro
new file mode 100644
index 000000000..b7ee6b4ef
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/errors/src/pages/in-stream.astro
@@ -0,0 +1,13 @@
+---
+---
+<html>
+ <head>
+ <title>One</title>
+ </head>
+ <body>
+ <h1>One</h1>
+ <p>
+ {Promise.reject('Error in the stream')}
+ </p>
+ </body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/errors/src/pages/offshoot-promise-rejection.astro b/packages/integrations/node/test/fixtures/errors/src/pages/offshoot-promise-rejection.astro
new file mode 100644
index 000000000..be702d5ef
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/errors/src/pages/offshoot-promise-rejection.astro
@@ -0,0 +1,2 @@
+{new Promise(async _ => (await {}, Astro.props.undefined.alsoAPropertyOfUndefined))}
+{Astro.props.undefined.propertyOfUndefined} \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/headers/package.json b/packages/integrations/node/test/fixtures/headers/package.json
new file mode 100644
index 000000000..3a663d062
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/nodejs-headers",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-cookies-multi.astro b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-cookies-multi.astro
new file mode 100644
index 000000000..a9ff193df
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-cookies-multi.astro
@@ -0,0 +1,5 @@
+---
+Astro.cookies.set('from1', 'astro1');
+Astro.cookies.set('from2', 'astro2');
+---
+<p>hello world</p> \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-cookies-single.astro b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-cookies-single.astro
new file mode 100644
index 000000000..c469fd66f
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-cookies-single.astro
@@ -0,0 +1,4 @@
+---
+Astro.cookies.set('from1', 'astro1');
+---
+<p>hello world</p> \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-response-cookie-multi.astro b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-response-cookie-multi.astro
new file mode 100644
index 000000000..91244e838
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-response-cookie-multi.astro
@@ -0,0 +1,7 @@
+---
+Astro.response.headers.append('set-cookie', 'from1=response1');
+Astro.response.headers.append('set-cookie', 'from2=response2');
+Astro.cookies.set('from3', 'astro1');
+Astro.cookies.set('from4', 'astro2');
+---
+<p>hello world</p> \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-response-cookie-single.astro b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-response-cookie-single.astro
new file mode 100644
index 000000000..97719dfa9
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-astro-response-cookie-single.astro
@@ -0,0 +1,5 @@
+---
+Astro.response.headers.append('set-cookie', 'from1=response1');
+Astro.cookies.set('from1', 'astro1');
+---
+<p>hello world</p> \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-response-cookies-multi.astro b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-response-cookies-multi.astro
new file mode 100644
index 000000000..133cbd423
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-response-cookies-multi.astro
@@ -0,0 +1,5 @@
+---
+Astro.response.headers.append('set-cookie', 'from1=value1');
+Astro.response.headers.append('set-cookie', 'from2=value2');
+---
+<p>hello world</p> \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-response-cookies-single.astro b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-response-cookies-single.astro
new file mode 100644
index 000000000..dc76082db
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/astro/component-response-cookies-single.astro
@@ -0,0 +1,4 @@
+---
+Astro.response.headers.append('set-cookie', 'from1=value1');
+---
+<p>hello world</p> \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-cookies-multi.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-cookies-multi.ts
new file mode 100644
index 000000000..aaae88e59
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-cookies-multi.ts
@@ -0,0 +1,9 @@
+import type { APIContext } from 'astro';
+
+export async function GET({ request, cookies }: APIContext) {
+ const headers = new Headers();
+ headers.append('content-type', 'text/plain;charset=utf-8');
+ cookies.set('from1', 'astro1');
+ cookies.set('from2', 'astro2');
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-cookies-single.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-cookies-single.ts
new file mode 100644
index 000000000..03e74c604
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-cookies-single.ts
@@ -0,0 +1,8 @@
+import type { APIContext } from 'astro';
+
+export async function GET({ request, cookies }: APIContext) {
+ const headers = new Headers();
+ headers.append('content-type', 'text/plain;charset=utf-8');
+ cookies.set('from1', 'astro1');
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-response-cookie-multi.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-response-cookie-multi.ts
new file mode 100644
index 000000000..36906da3a
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-response-cookie-multi.ts
@@ -0,0 +1,11 @@
+import type { APIContext } from 'astro';
+
+export async function GET({ request, cookies }: APIContext) {
+ const headers = new Headers();
+ headers.append('content-type', 'text/plain;charset=utf-8');
+ headers.append('set-cookie', 'from1=response1');
+ headers.append('set-cookie', 'from2=response2');
+ cookies.set('from3', 'astro1');
+ cookies.set('from4', 'astro2');
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-response-cookie-single.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-response-cookie-single.ts
new file mode 100644
index 000000000..3c1fc4775
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/astro-response-cookie-single.ts
@@ -0,0 +1,9 @@
+import type { APIContext } from 'astro';
+
+export async function GET({ request, cookies }: APIContext) {
+ const headers = new Headers();
+ headers.append('content-type', 'text/plain;charset=utf-8');
+ headers.append('set-cookie', 'from1=response1');
+ cookies.set('from1', 'astro1');
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/kitchen-sink.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/kitchen-sink.ts
new file mode 100644
index 000000000..fb7c30cbc
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/kitchen-sink.ts
@@ -0,0 +1,11 @@
+export async function GET({ request }: { request: Request }) {
+ const headers = new Headers();
+ headers.append('content-type', 'text/plain;charset=utf-8');
+ headers.append('x-SINGLE', 'single');
+ headers.append('X-triple', 'one');
+ headers.append('x-Triple', 'two');
+ headers.append('x-TRIPLE', 'three');
+ headers.append('SET-cookie', 'hello1=world1');
+ headers.append('Set-Cookie', 'hello2=world2');
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-cookies-multi.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-cookies-multi.ts
new file mode 100644
index 000000000..d974737ee
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-cookies-multi.ts
@@ -0,0 +1,7 @@
+export async function GET({ request }: { request: Request }) {
+ const headers = new Headers();
+ headers.append('content-type', 'text/plain;charset=utf-8');
+ headers.append('Set-Cookie', 'hello1=world1');
+ headers.append('SET-COOKIE', 'hello2=world2');
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-cookies-single.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-cookies-single.ts
new file mode 100644
index 000000000..f543ae062
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-cookies-single.ts
@@ -0,0 +1,6 @@
+export async function GET({ request }: { request: Request }) {
+ const headers = new Headers();
+ headers.append('content-type', 'text/plain;charset=utf-8');
+ headers.append('Set-Cookie', 'hello1=world1');
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-empty-headers-object.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-empty-headers-object.ts
new file mode 100644
index 000000000..b8a9e122e
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-empty-headers-object.ts
@@ -0,0 +1,4 @@
+export async function GET({ request }: { request: Request }) {
+ const headers = new Headers();
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-undefined-headers-object.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-undefined-headers-object.ts
new file mode 100644
index 000000000..72f7af071
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/response-undefined-headers-object.ts
@@ -0,0 +1,3 @@
+export async function GET({ request }: { request: Request }) {
+ return new Response('hello world', { headers: undefined });
+}
diff --git a/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/simple.ts b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/simple.ts
new file mode 100644
index 000000000..9c6bcacaa
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/headers/src/pages/endpoints/simple.ts
@@ -0,0 +1,6 @@
+export async function GET({ request }: { request: Request }) {
+ const headers = new Headers();
+ headers.append('content-type', 'text/plain;charset=utf-8');
+ headers.append('X-HELLO', 'world');
+ return new Response('hello world', { headers });
+}
diff --git a/packages/integrations/node/test/fixtures/image/package.json b/packages/integrations/node/test/fixtures/image/package.json
new file mode 100644
index 000000000..e21388c8a
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/image/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@test/nodejs-image",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ },
+ "peerDependencies": {
+ "sharp": "^0.33.5"
+ },
+ "scripts": {
+ "build": "astro build",
+ "preview": "astro preview"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/image/src/assets/file.txt b/packages/integrations/node/test/fixtures/image/src/assets/file.txt
new file mode 100644
index 000000000..e9ea42a12
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/image/src/assets/file.txt
@@ -0,0 +1 @@
+this is a text file
diff --git a/packages/integrations/node/test/fixtures/image/src/assets/some_penguin.png b/packages/integrations/node/test/fixtures/image/src/assets/some_penguin.png
new file mode 100644
index 000000000..a09d7f894
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/image/src/assets/some_penguin.png
Binary files differ
diff --git a/packages/integrations/node/test/fixtures/image/src/pages/[...catchall].astro b/packages/integrations/node/test/fixtures/image/src/pages/[...catchall].astro
new file mode 100644
index 000000000..44edaee73
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/image/src/pages/[...catchall].astro
@@ -0,0 +1,8 @@
+---
+import { Image } from "astro:assets";
+import penguin from "../assets/some_penguin.png";
+export const prerender = false;
+---
+
+<Image src={penguin} alt="Penguins" width={50} />
+<Image src="https://images.unsplash.com/photo-1707229190979-f2d99f7823a8?q=80&w=800&auto=format&fit=crop" alt="Cornwall" width={400} height={300} />
diff --git a/packages/integrations/node/test/fixtures/image/src/pages/text-file.astro b/packages/integrations/node/test/fixtures/image/src/pages/text-file.astro
new file mode 100644
index 000000000..893250360
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/image/src/pages/text-file.astro
@@ -0,0 +1,14 @@
+---
+import txt from '../assets/file.txt?url';
+---
+<html>
+ <head>
+ <title>Testing</title>
+ </head>
+ <body>
+ <h1>Testing</h1>
+ <main>
+ <a href={txt} download>Download text file</a>
+ </main>
+ </body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/locals/astro.config.mjs b/packages/integrations/node/test/fixtures/locals/astro.config.mjs
new file mode 100644
index 000000000..3cdf86221
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/locals/astro.config.mjs
@@ -0,0 +1,7 @@
+import {defineConfig} from "astro/config";
+
+export default defineConfig({
+ security: {
+ checkOrigin:false
+ }
+}) \ No newline at end of file
diff --git a/packages/integrations/node/test/fixtures/locals/package.json b/packages/integrations/node/test/fixtures/locals/package.json
new file mode 100644
index 000000000..1591b3f30
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/locals/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/locals",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/locals/src/middleware.ts b/packages/integrations/node/test/fixtures/locals/src/middleware.ts
new file mode 100644
index 000000000..e349ca41d
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/locals/src/middleware.ts
@@ -0,0 +1,6 @@
+import { defineMiddleware } from 'astro:middleware';
+
+export const onRequest = defineMiddleware(({ url, locals }, next) => {
+ if (url.pathname === "/from-astro-middleware") locals.foo = "baz";
+ return next();
+})
diff --git a/packages/integrations/node/test/fixtures/locals/src/pages/api.js b/packages/integrations/node/test/fixtures/locals/src/pages/api.js
new file mode 100644
index 000000000..3c279e37b
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/locals/src/pages/api.js
@@ -0,0 +1,10 @@
+
+export async function POST({ locals }) {
+ const out = { ...locals };
+
+ return new Response(JSON.stringify(out), {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });
+}
diff --git a/packages/integrations/node/test/fixtures/locals/src/pages/from-astro-middleware.astro b/packages/integrations/node/test/fixtures/locals/src/pages/from-astro-middleware.astro
new file mode 100644
index 000000000..224a875ec
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/locals/src/pages/from-astro-middleware.astro
@@ -0,0 +1,4 @@
+---
+const { foo } = Astro.locals;
+---
+<h1>{foo}</h1>
diff --git a/packages/integrations/node/test/fixtures/locals/src/pages/from-node-middleware.astro b/packages/integrations/node/test/fixtures/locals/src/pages/from-node-middleware.astro
new file mode 100644
index 000000000..224a875ec
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/locals/src/pages/from-node-middleware.astro
@@ -0,0 +1,4 @@
+---
+const { foo } = Astro.locals;
+---
+<h1>{foo}</h1>
diff --git a/packages/integrations/node/test/fixtures/node-middleware/package.json b/packages/integrations/node/test/fixtures/node-middleware/package.json
new file mode 100644
index 000000000..22ea41869
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/node-middleware/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/node-middleware",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/node-middleware/src/pages/404.astro b/packages/integrations/node/test/fixtures/node-middleware/src/pages/404.astro
new file mode 100644
index 000000000..79f4944bc
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/node-middleware/src/pages/404.astro
@@ -0,0 +1,13 @@
+---
+---
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>404</title>
+</head>
+<body>Page does not exist</body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/node-middleware/src/pages/index.astro b/packages/integrations/node/test/fixtures/node-middleware/src/pages/index.astro
new file mode 100644
index 000000000..28ff7d223
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/node-middleware/src/pages/index.astro
@@ -0,0 +1,11 @@
+---
+---
+
+<html lang="en">
+<head><title>node-middleware</title></head>
+<style>
+</style>
+<body>
+<div>1</div>
+</body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts b/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts
new file mode 100644
index 000000000..423db341a
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts
@@ -0,0 +1,7 @@
+export async function GET() {
+ let number = Math.random();
+ return Response.json({
+ number,
+ message: `Here's a random number: ${number}`,
+ });
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/package.json b/packages/integrations/node/test/fixtures/prerender-404-500/package.json
new file mode 100644
index 000000000..6b8433d59
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "@test/nodejs-prerender-404-500",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css b/packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css
new file mode 100644
index 000000000..5f331948a
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css
@@ -0,0 +1,3 @@
+body {
+ background-color: ivory;
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts b/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts
new file mode 100644
index 000000000..1795c26b0
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts
@@ -0,0 +1,17 @@
+// This module is only used by the prerendered 404.astro.
+// It exhibits different behavior if it's called more than once,
+// which is detected by a test and interpreted as a failure.
+
+let usedOnce = false
+let dynamicMessage = "Page was not prerendered"
+
+export default function () {
+ if (usedOnce === false) {
+ usedOnce = true
+ return "Page does not exist"
+ }
+
+ dynamicMessage += "+"
+
+ return dynamicMessage
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts b/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts
new file mode 100644
index 000000000..8f8024a60
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts
@@ -0,0 +1,17 @@
+// This module is only used by the prerendered 500.astro.
+// It exhibits different behavior if it's called more than once,
+// which is detected by a test and interpreted as a failure.
+
+let usedOnce = false
+let dynamicMessage = "Page was not prerendered"
+
+export default function () {
+ if (usedOnce === false) {
+ usedOnce = true
+ return "Something went wrong"
+ }
+
+ dynamicMessage += "+"
+
+ return dynamicMessage
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro
new file mode 100644
index 000000000..37fd1c1d3
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro
@@ -0,0 +1,5 @@
+---
+import message from "../nondeterminism-404"
+export const prerender = true;
+---
+{message()}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro
new file mode 100644
index 000000000..ef91ad0ff
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro
@@ -0,0 +1,6 @@
+---
+import "../external-stylesheet.css"
+import message from "../nondeterminism-500"
+export const prerender = true
+---
+<h1>{message()}</h1>
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro
new file mode 100644
index 000000000..99d103567
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro
@@ -0,0 +1,4 @@
+---
+return new Response(null, { status: 500 })
+---
+<p>This html will not be served</p>
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/static.astro b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/static.astro
new file mode 100644
index 000000000..af6bad2fb
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/static.astro
@@ -0,0 +1,12 @@
+---
+export const prerender = true;
+---
+
+<html>
+<head>
+ <title>Static Page</title>
+</head>
+ <body>
+ <h1>Hello world!</h1>
+ </body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/prerender/package.json b/packages/integrations/node/test/fixtures/prerender/package.json
new file mode 100644
index 000000000..0c1fa7d3e
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/nodejs-prerender",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/prerender/src/middleware.ts b/packages/integrations/node/test/fixtures/prerender/src/middleware.ts
new file mode 100644
index 000000000..3083acd24
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender/src/middleware.ts
@@ -0,0 +1,5 @@
+import { shared } from './shared';
+export const onRequest = (ctx, next) => {
+ ctx.locals.name = shared;
+ return next();
+};
diff --git a/packages/integrations/node/test/fixtures/prerender/src/pages/one.astro b/packages/integrations/node/test/fixtures/prerender/src/pages/one.astro
new file mode 100644
index 000000000..f3a26721d
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender/src/pages/one.astro
@@ -0,0 +1,10 @@
+---
+---
+<html>
+ <head>
+ <title>One</title>
+ </head>
+ <body>
+ <h1>One</h1>
+ </body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/prerender/src/pages/third.astro b/packages/integrations/node/test/fixtures/prerender/src/pages/third.astro
new file mode 100644
index 000000000..e29377d88
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender/src/pages/third.astro
@@ -0,0 +1,15 @@
+---
+import { shared} from "../shared";
+export const prerender = false;
+
+const shared = Astro.locals.name;
+---
+
+<html>
+<head>
+ <title>One</title>
+</head>
+<body>
+<h1>{shared}</h1>
+</body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/prerender/src/pages/two.astro b/packages/integrations/node/test/fixtures/prerender/src/pages/two.astro
new file mode 100644
index 000000000..beb6e8d78
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender/src/pages/two.astro
@@ -0,0 +1,11 @@
+---
+export const prerender = true;
+---
+<html>
+ <head>
+ <title>Two</title>
+ </head>
+ <body>
+ <h1>Two</h1>
+ </body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/prerender/src/shared.ts b/packages/integrations/node/test/fixtures/prerender/src/shared.ts
new file mode 100644
index 000000000..cd35843de
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender/src/shared.ts
@@ -0,0 +1 @@
+export const shared = 'shared';
diff --git a/packages/integrations/node/test/fixtures/preview-headers/package.json b/packages/integrations/node/test/fixtures/preview-headers/package.json
new file mode 100644
index 000000000..cee2f790f
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/preview-headers/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/nodejs-preview-headers",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/preview-headers/src/pages/index.astro b/packages/integrations/node/test/fixtures/preview-headers/src/pages/index.astro
new file mode 100644
index 000000000..10ddd6d25
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/preview-headers/src/pages/index.astro
@@ -0,0 +1 @@
+Hello!
diff --git a/packages/integrations/node/test/fixtures/sessions/astro.config.mjs b/packages/integrations/node/test/fixtures/sessions/astro.config.mjs
new file mode 100644
index 000000000..bcd1aed24
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/astro.config.mjs
@@ -0,0 +1,6 @@
+// @ts-check
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({
+
+});
diff --git a/packages/integrations/node/test/fixtures/sessions/package.json b/packages/integrations/node/test/fixtures/sessions/package.json
new file mode 100644
index 000000000..e6fc29588
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/node-sessions",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/sessions/src/actions/index.ts b/packages/integrations/node/test/fixtures/sessions/src/actions/index.ts
new file mode 100644
index 000000000..856f68ba8
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/src/actions/index.ts
@@ -0,0 +1,36 @@
+import { defineAction } from 'astro:actions';
+import { z } from 'astro:schema';
+
+export const server = {
+ addToCart: defineAction({
+ accept: 'form',
+ input: z.object({ productId: z.string() }),
+ handler: async (input, context) => {
+ const cart: Array<string> = (await context.session.get('cart')) || [];
+ cart.push(input.productId);
+ await context.session.set('cart', cart);
+ return { cart, message: 'Product added to cart at ' + new Date().toTimeString() };
+ },
+ }),
+ getCart: defineAction({
+ handler: async (input, context) => {
+ return await context.session.get('cart');
+ },
+ }),
+ clearCart: defineAction({
+ accept: 'json',
+ handler: async (input, context) => {
+ await context.session.set('cart', []);
+ return { cart: [], message: 'Cart cleared at ' + new Date().toTimeString() };
+ },
+ }),
+ addUrl: defineAction({
+ input: z.object({ favoriteUrl: z.string().url() }),
+ handler: async (input, context) => {
+ const previousFavoriteUrl = await context.session.get<URL>('favoriteUrl');
+ const url = new URL(input.favoriteUrl);
+ context.session.set('favoriteUrl', url);
+ return { message: 'Favorite URL set to ' + url.href + ' from ' + (previousFavoriteUrl?.href ?? "nothing") };
+ }
+ })
+}
diff --git a/packages/integrations/node/test/fixtures/sessions/src/middleware.ts b/packages/integrations/node/test/fixtures/sessions/src/middleware.ts
new file mode 100644
index 000000000..7f56f11f3
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/src/middleware.ts
@@ -0,0 +1,49 @@
+import { defineMiddleware } from 'astro:middleware';
+import { getActionContext } from 'astro:actions';
+
+const ACTION_SESSION_KEY = 'actionResult'
+
+export const onRequest = defineMiddleware(async (context, next) => {
+ // Skip requests for prerendered pages
+ if (context.isPrerendered) return next();
+
+ const { action, setActionResult, serializeActionResult } =
+ getActionContext(context);
+
+ console.log(action?.name)
+
+ const actionPayload = await context.session.get(ACTION_SESSION_KEY);
+
+ if (actionPayload) {
+ setActionResult(actionPayload.actionName, actionPayload.actionResult);
+ context.session.delete(ACTION_SESSION_KEY);
+ return next();
+ }
+
+ // If an action was called from an HTML form action,
+ // call the action handler and redirect to the destination page
+ if (action?.calledFrom === "form") {
+ const actionResult = await action.handler();
+
+ context.session.set(ACTION_SESSION_KEY, {
+ actionName: action.name,
+ actionResult: serializeActionResult(actionResult),
+ });
+
+
+ // Redirect back to the previous page on error
+ if (actionResult.error) {
+ const referer = context.request.headers.get("Referer");
+ if (!referer) {
+ throw new Error(
+ "Internal: Referer unexpectedly missing from Action POST request.",
+ );
+ }
+ return context.redirect(referer);
+ }
+ // Redirect to the destination page on success
+ return context.redirect(context.originPathname);
+ }
+
+ return next();
+});
diff --git a/packages/integrations/node/test/fixtures/sessions/src/pages/api.ts b/packages/integrations/node/test/fixtures/sessions/src/pages/api.ts
new file mode 100644
index 000000000..21793c78a
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/src/pages/api.ts
@@ -0,0 +1,13 @@
+import type { APIRoute } from 'astro';
+
+export const GET: APIRoute = async (context) => {
+ const url = new URL(context.url, 'http://localhost');
+ let value = url.searchParams.get('set');
+ if (value) {
+ context.session.set('value', value);
+ } else {
+ value = await context.session.get('value');
+ }
+ const cart = await context.session.get('cart');
+ return Response.json({ value, cart });
+};
diff --git a/packages/integrations/node/test/fixtures/sessions/src/pages/cart.astro b/packages/integrations/node/test/fixtures/sessions/src/pages/cart.astro
new file mode 100644
index 000000000..e69a9e5e1
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/src/pages/cart.astro
@@ -0,0 +1,24 @@
+---
+import { actions } from "astro:actions";
+
+const result = Astro.getActionResult(actions.addToCart);
+
+const cart = result?.data?.cart ?? await Astro.session.get('cart');
+const message = result?.data?.message ?? 'Add something to your cart!';
+---
+<p>Cart: <span id="cart">{JSON.stringify(cart)}</span></p>
+<p id="message">{message}</p>
+<form action={actions.addToCart} method="POST">
+ <input type="text" name="productId" value="shoe" />
+ <button type="submit">Add to Cart</button>
+</form>
+<input type="button" value="Clear Cart" id="clearCart" />
+<script>
+ import { actions } from "astro:actions";
+ async function clearCart() {
+ const result = await actions.clearCart({});
+ document.getElementById('cart').textContent = JSON.stringify(result.data.cart);
+ document.getElementById('message').textContent = result.data.message;
+ }
+ document.getElementById('clearCart').addEventListener('click', clearCart);
+</script>
diff --git a/packages/integrations/node/test/fixtures/sessions/src/pages/destroy.ts b/packages/integrations/node/test/fixtures/sessions/src/pages/destroy.ts
new file mode 100644
index 000000000..e83f6e4b6
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/src/pages/destroy.ts
@@ -0,0 +1,6 @@
+import type { APIRoute } from 'astro';
+
+export const GET: APIRoute = async (context) => {
+ await context.session.destroy();
+ return Response.json({});
+};
diff --git a/packages/integrations/node/test/fixtures/sessions/src/pages/index.astro b/packages/integrations/node/test/fixtures/sessions/src/pages/index.astro
new file mode 100644
index 000000000..30d6a1618
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/src/pages/index.astro
@@ -0,0 +1,13 @@
+---
+const value = await Astro.session.get('value');
+---
+<html lang="en">
+<head>
+ <meta charset="utf-8" />
+ <title>Hi</title>
+</head>
+
+<h1>Hi</h1>
+<p>{value}</p>
+<a href="/cart" style="font-size: 36px">🛒</a>
+</html>
diff --git a/packages/integrations/node/test/fixtures/sessions/src/pages/regenerate.ts b/packages/integrations/node/test/fixtures/sessions/src/pages/regenerate.ts
new file mode 100644
index 000000000..6f2240588
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/src/pages/regenerate.ts
@@ -0,0 +1,6 @@
+import type { APIRoute } from 'astro';
+
+export const GET: APIRoute = async (context) => {
+ await context.session.regenerate();
+ return Response.json({});
+};
diff --git a/packages/integrations/node/test/fixtures/sessions/src/pages/update.ts b/packages/integrations/node/test/fixtures/sessions/src/pages/update.ts
new file mode 100644
index 000000000..71b058e75
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/sessions/src/pages/update.ts
@@ -0,0 +1,10 @@
+import type { APIRoute } from 'astro';
+
+export const GET: APIRoute = async (context) => {
+ const previousObject = await context.session.get("key") ?? { value: "none" };
+ const previousValue = previousObject.value;
+ const sessionData = { value: "expected" };
+ context.session.set("key", sessionData);
+ sessionData.value = "unexpected";
+ return Response.json({previousValue});
+};
diff --git a/packages/integrations/node/test/fixtures/trailing-slash/astro.config.mjs b/packages/integrations/node/test/fixtures/trailing-slash/astro.config.mjs
new file mode 100644
index 000000000..acf78132b
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/trailing-slash/astro.config.mjs
@@ -0,0 +1,8 @@
+import node from '@astrojs/node'
+
+export default {
+ base: '/some-base',
+ output: 'static',
+ trailingSlash: 'never',
+ adapter: node({ mode: 'standalone' })
+};
diff --git a/packages/integrations/node/test/fixtures/trailing-slash/package.json b/packages/integrations/node/test/fixtures/trailing-slash/package.json
new file mode 100644
index 000000000..e8e15f58e
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/trailing-slash/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/node-trailingslash",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/trailing-slash/public/one.css b/packages/integrations/node/test/fixtures/trailing-slash/public/one.css
new file mode 100644
index 000000000..5ce768ca5
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/trailing-slash/public/one.css
@@ -0,0 +1 @@
+h1 { color: red; }
diff --git a/packages/integrations/node/test/fixtures/trailing-slash/src/assets/bitgeneva12.woff2 b/packages/integrations/node/test/fixtures/trailing-slash/src/assets/bitgeneva12.woff2
new file mode 100644
index 000000000..7c5c2567e
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/trailing-slash/src/assets/bitgeneva12.woff2
Binary files differ
diff --git a/packages/integrations/node/test/fixtures/trailing-slash/src/pages/index.astro b/packages/integrations/node/test/fixtures/trailing-slash/src/pages/index.astro
new file mode 100644
index 000000000..495eb989b
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/trailing-slash/src/pages/index.astro
@@ -0,0 +1,17 @@
+<html>
+ <head>
+ <title>Index</title>
+ </head>
+ <body>
+ <h1>Index</h1>
+ </body>
+</html>
+<style>
+ @font-face {
+ font-family: 'Geneva';
+ src: url('../assets/bitgeneva12.woff2') format('woff2');
+ }
+ h1 {
+ font-family: 'Geneva', sans-serif;
+ }
+</style>
diff --git a/packages/integrations/node/test/fixtures/trailing-slash/src/pages/one.astro b/packages/integrations/node/test/fixtures/trailing-slash/src/pages/one.astro
new file mode 100644
index 000000000..aa370d18d
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/trailing-slash/src/pages/one.astro
@@ -0,0 +1,11 @@
+---
+export const prerender = true;
+---
+<html>
+ <head>
+ <title>One</title>
+ </head>
+ <body>
+ <h1>One</h1>
+ </body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/url/package.json b/packages/integrations/node/test/fixtures/url/package.json
new file mode 100644
index 000000000..e9bc15a3e
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/url/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/url",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/url/src/pages/index.astro b/packages/integrations/node/test/fixtures/url/src/pages/index.astro
new file mode 100644
index 000000000..003429f52
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/url/src/pages/index.astro
@@ -0,0 +1,9 @@
+---
+---
+
+<html lang="en">
+ <head>
+ <title>URL</title>
+ </head>
+ <body>{Astro.url.href}</body>
+</html>
diff --git a/packages/integrations/node/test/fixtures/well-known-locations/package.json b/packages/integrations/node/test/fixtures/well-known-locations/package.json
new file mode 100644
index 000000000..9182445aa
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/well-known-locations/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/well-known-locations",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/node/test/fixtures/well-known-locations/public/.hidden/file.json b/packages/integrations/node/test/fixtures/well-known-locations/public/.hidden/file.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/well-known-locations/public/.hidden/file.json
@@ -0,0 +1 @@
+{}
diff --git a/packages/integrations/node/test/fixtures/well-known-locations/public/.well-known/apple-app-site-association b/packages/integrations/node/test/fixtures/well-known-locations/public/.well-known/apple-app-site-association
new file mode 100644
index 000000000..daae260f1
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/well-known-locations/public/.well-known/apple-app-site-association
@@ -0,0 +1,3 @@
+{
+ "applinks": {}
+}