summaryrefslogtreecommitdiff
path: root/packages/astro/src/runtime/server/endpoint.ts
blob: 9780d6599cb5f53765de9610c18f925bf3c565fc (plain) (blame)
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
import type { APIContext, EndpointHandler, Params } from '../../@types/astro';

function getHandlerFromModule(mod: EndpointHandler, method: string) {
	// If there was an exact match on `method`, return that function.
	if (mod[method]) {
		return mod[method];
	}
	// Handle `del` instead of `delete`, since `delete` is a reserved word in JS.
	if (method === 'delete' && mod['del']) {
		return mod['del'];
	}
	// If a single `all` handler was used, return that function.
	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) {
	const { request, params, locals } = context;
	const chosenMethod = request.method?.toLowerCase();
	const handler = getHandlerFromModule(mod, chosenMethod);
	if (!ssr && ssr === false && chosenMethod && 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' 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);
}