fix(middleware): emit warning if next is called and nothing is returned (#7010)

* fix(middleware): emit warning if `next` is called and nothing is returned

* chore: add test case

* chore: changeset

* chore: restore code, ooops!

* chore: change logic

* change namespace
This commit is contained in:
Emanuele Stoppa 2023-05-05 18:20:33 +01:00 committed by GitHub
parent 890c8b3ea7
commit e9f0dd9b47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 82 additions and 37 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Call `next()` without return anything should work, with a warning

View file

@ -1,13 +1,9 @@
/// <reference types="astro/client" />
declare global {
namespace AstroMiddleware {
interface Locals {
user: {
name: string;
surname: string;
};
}
declare namespace App {
interface Locals {
user: {
name: string;
surname: string;
};
}
}
export {};

View file

@ -63,9 +63,7 @@ const validation = defineMiddleware(async (context, next) => {
return context.redirect('/admin');
}
}
// we don't really care about awaiting the response in this case
next();
return;
return next();
});
export const onRequest = sequence(validation, minifier);

View file

@ -1,18 +0,0 @@
import { APIRoute } from 'astro';
export const post: APIRoute = async ({ request }) => {
const data = await request.formData();
const username = data.get('username');
const password = data.get('password');
return new Response(
JSON.stringify({
username,
password,
}),
{
headers: {
'content-type': 'application/json',
},
}
);
};

View file

@ -46,9 +46,11 @@ export async function callMiddleware<R>(
});
let nextCalled = false;
let responseFunctionPromise: Promise<R> | undefined = undefined;
const next: MiddlewareNext<R> = async () => {
nextCalled = true;
return await responseFunction();
responseFunctionPromise = responseFunction();
return responseFunctionPromise;
};
let middlewarePromise = onRequest(apiContext, next);
@ -74,8 +76,11 @@ export async function callMiddleware<R>(
/**
* Here we handle the case where `next` was called and returned nothing.
*/
const responseResult = await responseFunction();
return responseResult;
if (responseFunctionPromise) {
return responseFunctionPromise;
} else {
throw new AstroError(AstroErrorData.MiddlewareNotAResponse);
}
}
} else if (typeof value === 'undefined') {
/**

View file

@ -34,7 +34,7 @@ const third = defineMiddleware(async (context, next) => {
} else if (context.request.url.includes('/does-nothing')) {
return undefined;
}
next();
return next();
});
export const onRequest = sequence(first, second, third);

View file

@ -0,0 +1,11 @@
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
// https://astro.build/config
export default defineConfig({
integrations: [tailwind()],
experimental: {
middleware: true,
}
});

View file

@ -0,0 +1,9 @@
{
"name": "@test/middleware-tailwind",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*",
"@astrojs/tailwind": "workspace:*"
}
}

View file

@ -0,0 +1,3 @@
export const onRequest = (_, next) => {
next();
}

View file

@ -0,0 +1,7 @@
<h1 class="text-blue-500 text-2xl font-bold">Hello world</h1>
<style>
p {
color: red;
}
</style>

View file

@ -77,8 +77,6 @@ describe('Middleware in DEV mode', () => {
describe('Middleware in PROD mode, SSG', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
/** @type {import('./test-utils').PreviewServer} */
let previewServer;
before(async () => {
fixture = await loadFixture({
@ -200,3 +198,25 @@ describe('Middleware API in PROD mode, SSR', () => {
expect($('title').html()).to.not.equal('MiddlewareNoDataReturned');
});
});
describe('Middleware with tailwind', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
before(async () => {
fixture = await loadFixture({
root: './fixtures/middleware-tailwind/',
});
await fixture.build();
});
it('should correctly emit the tailwind CSS file', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
const bundledCSSHREF = $('link[rel=stylesheet][href^=/_astro/]').attr('href');
const bundledCSS = (await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/')))
.replace(/\s/g, '')
.replace('/n', '');
expect(bundledCSS.includes('--tw-content')).to.be.true;
});
});

View file

@ -2771,6 +2771,15 @@ importers:
specifier: workspace:*
version: link:../../..
packages/astro/test/fixtures/middleware-tailwind:
dependencies:
'@astrojs/tailwind':
specifier: workspace:*
version: link:../../../../integrations/tailwind
astro:
specifier: workspace:*
version: link:../../..
packages/astro/test/fixtures/multiple-renderers:
dependencies:
'@test/astro-renderer-one':