1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
import type { APIContext, EndpointHandler, Params } from '../../@types/astro';
import { type LogOptions, warn } from '../../core/logger/core.js';
function getHandlerFromModule(mod: EndpointHandler, method: string, logging: LogOptions) {
const lowerCaseMethod = method.toLowerCase();
// TODO: remove in Astro 4.0
if (mod[lowerCaseMethod]) {
warn(
logging,
'astro',
`Lower case endpoint names are deprecated and will not be supported in Astro 4.0. Rename the endpoint ${lowerCaseMethod} to ${method}.`
);
}
// If there was an exact match on `method`, return that function.
if (mod[method]) {
return mod[method];
}
// TODO: remove in Astro 4.0
if (mod[lowerCaseMethod]) {
return mod[lowerCaseMethod];
}
// TODO: remove in Astro 4.0
// Handle `del` instead of `delete`, since `delete` is a reserved word in JS.
if (method === 'delete' && mod['del']) {
return mod['del'];
}
// TODO: remove in Astro 4.0
// If a single `all` handler was used, return that function.
if (mod['all']) {
return mod['all'];
}
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,
context: APIContext,
ssr: boolean,
logging: LogOptions
) {
const { request } = context;
const chosenMethod = request.method?.toUpperCase();
const handler = getHandlerFromModule(mod, chosenMethod, logging);
// TODO: remove the 'get' check in Astro 4.0
if (!ssr && ssr === false && chosenMethod && chosenMethod !== 'GET' && chosenMethod !== 'get') {
// eslint-disable-next-line no-console
console.warn(`
${chosenMethod} requests are not available when building a static site. Update your config to \`output: 'server'\` or \`output: 'hybrid'\` with an \`export const prerender = false\` to handle ${chosenMethod} requests.`);
}
if (!handler || typeof handler !== 'function') {
// 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, {
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);
}
|