-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
endpoint.ts
107 lines (95 loc) · 3.21 KB
/
endpoint.ts
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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, params } = 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;
}
// TODO: Remove support for old API in Astro 3.0
if (handler.length > 1) {
// eslint-disable-next-line no-console
console.warn(`
API routes with 2 arguments have been deprecated. Instead they take a single argument in the form of:
export function get({ params, request }) {
//...
}
Update your code to remove this warning.`);
}
const proxy = new Proxy(context, {
get(target, prop) {
if (prop in target) {
return Reflect.get(target, prop);
} else if (prop in params) {
// TODO: Remove support for old API in Astro 3.0
// eslint-disable-next-line no-console
console.warn(`
API routes no longer pass params as the first argument. Instead an object containing a params property is provided in the form of:
export function get({ params }) {
// ...
}
Update your code to remove this warning.`);
return Reflect.get(params, prop);
} else {
return undefined;
}
},
}) as APIContext & Params;
return handler.call(mod, proxy, request);
}