Public
Script
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
import ServeRouter from "https://esm.sh/serve-router@1.1.0";
import { parseRequestBody } from "https://esm.sh/serve-router@1.1.0/utils";
export const app = ServeRouter({
onError(error) {
console.log(error);
},
});
const _registered: Array<{ method: string; path: string }> = [];
export const registered: Readonly<typeof _registered> = _registered;
export const handler = (req: Request) => app.fetch(req);
export interface Context {
request: Request;
params: Record<string, string | undefined>;
next: () => Promise<Response>;
}
export function get(path: string) {
return (
target: (query: Record<string, string>, ctx: Context) => unknown,
_context: ClassMethodDecoratorContext,
) => {
_registered.push({ method: "GET", path });
app.get(path, async (request: Request, { params, next }) => {
const resp = await target(Object.fromEntries(new URL(request.url).searchParams.entries()), {
request,
params,
next,
});
if (resp instanceof Response) return resp;
if (resp == undefined) return next();
return Response.json(resp);
});
};
}
export function post(path: string) {
return (target: (body: any, ctx: Context) => unknown, _context: ClassMethodDecoratorContext) => {
_registered.push({ method: "POST", path });
app.post(path, async (request: Request, { params, next }) => {
const resp = await target(await parseRequestBody(request, "application/json"), { request, params, next });
if (resp instanceof Response) return resp;
if (resp == undefined) return next();
return Response.json(resp);
});
};
}
export function all(path: string) {
return (target: (ctx: Context) => unknown, _context: ClassMethodDecoratorContext) => {
_registered.push({ method: "*", path });
app.all(path, async (request: Request, { params, next }) => {
const resp = await target({ request, params, next });
if (resp instanceof Response) return resp;
if (resp == undefined) return next();
return Response.json(resp);
});
};
}
export function use(path: string) {
return (target: (ctx: Context) => unknown, _context: ClassMethodDecoratorContext) => {
app.use(path, async (request: Request, { params, next }) => {
const resp = await target({ request, params, next });
if (resp instanceof Response) return resp;
if (resp == undefined) return next();
return Response.json(resp);
});
};
}
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
May 16, 2024
So cool!
Thanks @stevekrouse! However, I've noticed that currently, decorators can only be applied to methods. If we had parameter decorators and function decorators, we could do much more!