0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-03 22:57:08 -05:00

qol(routing): warn when api route method doesn't match the casing of an export (#9497)

* fix(routing): improve messaging for getting the case wrong

* add changeset

* lint: no shadowing

* remove old APIRoute signature

* Apply suggestions from code review

Co-authored-by: Voxel <voxelmc@hotmail.com>

---------

Co-authored-by: Voxel <voxelmc@hotmail.com>
This commit is contained in:
Arsh 2023-12-27 17:56:10 +00:00 committed by GitHub
parent a171c22f37
commit 7f7a7f1aea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 32 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Adds a helpful warning message for when an exported API Route is not uppercase.

View file

@ -2237,7 +2237,7 @@ export type APIRoute<Props extends Record<string, any> = Record<string, any>> =
) => Response | Promise<Response>;
export interface EndpointHandler {
[method: string]: APIRoute | ((params: Params, request: Request) => Response);
[method: string]: APIRoute;
}
export type Props = Record<string, unknown>;

View file

@ -2,18 +2,6 @@ import { bold } from 'kleur/colors';
import type { APIContext, EndpointHandler, Params } from '../../@types/astro.js';
import type { Logger } from '../../core/logger/core.js';
function getHandlerFromModule(mod: EndpointHandler, method: string) {
// If there was an exact match on `method`, return that function.
if (mod[method]) {
return mod[method];
}
if (mod['ALL']) {
return mod['ALL'];
}
// Otherwise, no handler found.
return undefined;
}
/** Renders an endpoint request to completion, returning the body. */
export async function renderEndpoint(
mod: EndpointHandler,
@ -23,38 +11,34 @@ export async function renderEndpoint(
) {
const { request, url } = context;
const chosenMethod = request.method?.toUpperCase();
const handler = getHandlerFromModule(mod, chosenMethod);
if (!ssr && ssr === false && chosenMethod && chosenMethod !== 'GET') {
const method = request.method.toUpperCase();
// use the exact match on `method`, fallback to ALL
const handler = mod[method] ?? mod['ALL'];
if (!ssr && ssr === false && method !== 'GET') {
logger.warn(
null,
"router",
`${url.pathname} ${bold(
chosenMethod
method
)} requests are not available for a static site. Update your config to \`output: 'server'\` or \`output: 'hybrid'\` to enable.`
);
}
if (!handler || typeof handler !== 'function') {
if (typeof handler !== 'function') {
logger.warn(
'router',
`No API Route handler exists for the method "${method}" for the route ${url.pathname}.\n` +
`Found handlers: ${Object.keys(mod).map(exp => JSON.stringify(exp)).join(', ')}\n` +
('all' in mod ? `One of the exported handlers is "all" (lowercase), did you mean to export 'ALL'?\n` : '')
);
// No handler found, so this should be a 404. Using a custom header
// to signal to the renderer that this is an internal 404 that should
// be handled by a custom 404 route if possible.
let response = new Response(null, {
return new Response(null, {
status: 404,
headers: {
'X-Astro-Response': 'Not-Found',
},
});
return response;
}
const proxy = new Proxy(context, {
get(target, prop) {
if (prop in target) {
return Reflect.get(target, prop);
} else {
return undefined;
}
},
}) as APIContext & Params;
return handler.call(mod, proxy, request);
return handler.call(mod, context);
}