-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.ts
89 lines (74 loc) · 2.33 KB
/
example.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
import { compose, Context, createHandler, createRoute } from "./mod.ts";
// You can optionally extend the default `Context` object or pass a `State` type.
export class Ctx extends Context<{ start: number }> {
pathname = this.url.pathname;
}
function date(ctx: Ctx) {
ctx.state.start = Date.now();
return ctx;
}
function verify(ctx: Ctx) {
const authHeader = ctx.request.headers.get("Authorization");
if (!authHeader) throw new Error("Unauthorized");
return ctx;
}
function greet(ctx: Ctx) {
ctx.response = new Response(`Hello World!`);
return ctx;
}
function welcome(ctx: Ctx) {
const name = ctx.result.pathname.groups.name;
if (name) ctx.response = new Response(`Welcome, ${name}!`);
return ctx;
}
function sub(ctx: Ctx) {
ctx.response = new Response(
`What's up ${ctx.result.hostname.groups.subdomain}?`,
);
return ctx;
}
function fix(ctx: Ctx) {
console.error(ctx.error?.message);
ctx.response = new Response("Unauthorized", { status: 401 });
return ctx;
}
function setHeader(ctx: Ctx) {
const ms = Date.now() - ctx.state.start;
ctx.response.headers.set("X-Response-Time", `${ms}ms`);
return ctx;
}
function log(ctx: Ctx) {
const rt = ctx.response.headers.get("X-Response-Time");
console.log(
`${ctx.request.method} ${ctx.request.url} [${ctx.response.status}] - ${
String(rt)
}`,
);
return ctx;
}
// This is just a showcase. You can compose all of it to much fewer lines of code.
const routeGet = createRoute("GET");
const routeAllAndEverything = createRoute("ALL")({ pathname: "*" });
const routePrivate = createRoute("DELETE", "POST")({ pathname: "/private/*" });
const greetOrWelcome = compose(welcome, greet);
const getSubdomain = routeGet({
hostname: `{:subdomain.}+localhost`,
pathname: "*",
});
const handleWelcome = routeGet({ pathname: "/{:name}?" })(greetOrWelcome);
const handleDate = routeAllAndEverything(date);
const handleVerify = routePrivate(verify);
const handleSubdomain = getSubdomain(sub);
const tryMiddleware = compose(
handleSubdomain,
handleWelcome,
handleVerify,
handleDate,
// deno-lint-ignore no-explicit-any
) as any; // TS WTF!
const catchMiddleware = routeAllAndEverything(fix);
const finallyMiddleware = routeAllAndEverything(log, setHeader);
const handler = createHandler(Ctx)(tryMiddleware)(catchMiddleware)(
finallyMiddleware,
);
Deno.serve(handler);