mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
fix(middleware): instantiate locals if the adapter does not (#8800)
This commit is contained in:
parent
3bef32f81c
commit
391729686b
7 changed files with 67 additions and 18 deletions
5
.changeset/large-colts-jump.md
Normal file
5
.changeset/large-colts-jump.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixed an issue where attempting to assign a variable onto locals threw an error.
|
|
@ -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);
|
||||
}
|
||||
},
|
||||
get locals() {
|
||||
let locals = Reflect.get(request, clientLocalsSymbol)
|
||||
|
||||
if (locals === undefined) {
|
||||
locals = {}
|
||||
Reflect.set(request, clientLocalsSymbol, locals)
|
||||
}
|
||||
|
||||
return Reflect.get(request, clientAddressSymbol);
|
||||
|
||||
if (typeof locals !== 'object') {
|
||||
throw new AstroError(AstroErrorData.LocalsNotAnObject);
|
||||
}
|
||||
|
||||
return locals;
|
||||
},
|
||||
} 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);
|
||||
},
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
6
packages/integrations/node/test/fixtures/locals/src/middleware.ts
vendored
Normal file
6
packages/integrations/node/test/fixtures/locals/src/middleware.ts
vendored
Normal file
|
@ -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();
|
||||
})
|
|
@ -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: {
|
||||
|
|
4
packages/integrations/node/test/fixtures/locals/src/pages/from-node-middleware.astro
vendored
Normal file
4
packages/integrations/node/test/fixtures/locals/src/pages/from-node-middleware.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
const { foo } = Astro.locals;
|
||||
---
|
||||
<h1>{foo}</h1>
|
|
@ -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({
|
||||
|
|
Loading…
Reference in a new issue