summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Arsh <69170106+lilnasy@users.noreply.github.com> 2023-10-12 14:36:34 +0000
committerGravatar GitHub <noreply@github.com> 2023-10-12 09:36:34 -0500
commit391729686bcc8404a7dd48c5987ee380daf3200f (patch)
tree8cf8caf8dfa39f533228887ef70730735f88290f
parent3bef32f81c56bc600ca307f1bd40787e23e625a5 (diff)
downloadastro-391729686bcc8404a7dd48c5987ee380daf3200f.tar.gz
astro-391729686bcc8404a7dd48c5987ee380daf3200f.tar.zst
astro-391729686bcc8404a7dd48c5987ee380daf3200f.zip
fix(middleware): instantiate locals if the adapter does not (#8800)
-rw-r--r--.changeset/large-colts-jump.md5
-rw-r--r--packages/astro/src/core/endpoint/index.ts33
-rw-r--r--packages/integrations/node/test/fixtures/locals/src/middleware.ts6
-rw-r--r--packages/integrations/node/test/fixtures/locals/src/pages/api.js4
-rw-r--r--packages/integrations/node/test/fixtures/locals/src/pages/from-astro-middleware.astro (renamed from packages/integrations/node/test/fixtures/locals/src/pages/foo.astro)0
-rw-r--r--packages/integrations/node/test/fixtures/locals/src/pages/from-node-middleware.astro4
-rw-r--r--packages/integrations/node/test/locals.test.js33
7 files changed, 67 insertions, 18 deletions
diff --git a/.changeset/large-colts-jump.md b/.changeset/large-colts-jump.md
new file mode 100644
index 000000000..faa265319
--- /dev/null
+++ b/.changeset/large-colts-jump.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixed an issue where attempting to assign a variable onto locals threw an error.
diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts
index b62ba8bed..7e6128c37 100644
--- a/packages/astro/src/core/endpoint/index.ts
+++ b/packages/astro/src/core/endpoint/index.ts
@@ -57,7 +57,9 @@ export function createAPIContext({
ResponseWithEncoding,
url: new URL(request.url),
get clientAddress() {
- if (!(clientAddressSymbol in request)) {
+ if (clientAddressSymbol in request) {
+ return Reflect.get(request, clientAddressSymbol) as string;
+ }
if (adapterName) {
throw new AstroError({
...AstroErrorData.ClientAddressNotAvailable,
@@ -66,26 +68,31 @@ export function createAPIContext({
} else {
throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
}
- }
-
- return Reflect.get(request, clientAddressSymbol);
},
- } as APIContext;
-
- // We define a custom property, so we can check the value passed to locals
- Object.defineProperty(context, 'locals', {
- enumerable: true,
- get() {
- return Reflect.get(request, clientLocalsSymbol);
+ get locals() {
+ let locals = Reflect.get(request, clientLocalsSymbol)
+
+ if (locals === undefined) {
+ locals = {}
+ Reflect.set(request, clientLocalsSymbol, locals)
+ }
+
+ if (typeof locals !== 'object') {
+ throw new AstroError(AstroErrorData.LocalsNotAnObject);
+ }
+
+ return locals;
},
- set(val) {
+ // We define a custom property, so we can check the value passed to locals
+ set locals(val) {
if (typeof val !== 'object') {
throw new AstroError(AstroErrorData.LocalsNotAnObject);
} else {
Reflect.set(request, clientLocalsSymbol, val);
}
},
- });
+ } satisfies APIContext;
+
return context;
}
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
index 8b209c582..3c279e37b 100644
--- a/packages/integrations/node/test/fixtures/locals/src/pages/api.js
+++ b/packages/integrations/node/test/fixtures/locals/src/pages/api.js
@@ -1,6 +1,6 @@
-export async function post({ locals }) {
- let out = { ...locals };
+export async function POST({ locals }) {
+ const out = { ...locals };
return new Response(JSON.stringify(out), {
headers: {
diff --git a/packages/integrations/node/test/fixtures/locals/src/pages/foo.astro b/packages/integrations/node/test/fixtures/locals/src/pages/from-astro-middleware.astro
index 224a875ec..224a875ec 100644
--- a/packages/integrations/node/test/fixtures/locals/src/pages/foo.astro
+++ b/packages/integrations/node/test/fixtures/locals/src/pages/from-astro-middleware.astro
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/locals.test.js b/packages/integrations/node/test/locals.test.js
index f7fc6b73f..b593f3eb9 100644
--- a/packages/integrations/node/test/locals.test.js
+++ b/packages/integrations/node/test/locals.test.js
@@ -15,11 +15,10 @@ describe('API routes', () => {
await fixture.build();
});
- it('Can render locals in page', async () => {
+ it('Can use locals added by node middleware', async () => {
const { handler } = await import('./fixtures/locals/dist/server/entry.mjs');
let { req, res, text } = createRequestAndResponse({
- method: 'POST',
- url: '/foo',
+ url: '/from-node-middleware',
});
let locals = { foo: 'bar' };
@@ -32,6 +31,34 @@ describe('API routes', () => {
expect(html).to.contain('<h1>bar</h1>');
});
+ it('Throws an error when provided non-objects as locals', async () => {
+ const { handler } = await import('./fixtures/locals/dist/server/entry.mjs');
+ let { req, res, done } = createRequestAndResponse({
+ url: '/from-node-middleware',
+ });
+
+ handler(req, res, undefined, "locals");
+ req.send();
+
+ await done;
+ expect(res).to.deep.include({ statusCode: 500 });
+ });
+
+ it('Can use locals added by astro middleware', async () => {
+ const { handler } = await import('./fixtures/locals/dist/server/entry.mjs');
+
+ const { req, res, text } = createRequestAndResponse({
+ url: '/from-astro-middleware',
+ });
+
+ handler(req, res, () => {});
+ req.send();
+
+ const html = await text();
+
+ expect(html).to.contain('<h1>baz</h1>');
+ });
+
it('Can access locals in API', async () => {
const { handler } = await import('./fixtures/locals/dist/server/entry.mjs');
let { req, res, done } = createRequestAndResponse({