-
Notifications
You must be signed in to change notification settings - Fork 1
/
oak.ts
85 lines (75 loc) · 2.28 KB
/
oak.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
import * as colors from "https://deno.land/[email protected]/fmt/colors.ts";
import * as oak from "https://deno.land/x/[email protected]/mod.ts";
import * as health from "./health.ts";
// TODO: add https://github.com/marcopacini/ts-prometheus based /metrics route
// TODO: add https://github.com/singhcool/deno-swagger-doc based OpenAPI generator
export interface HealthRouteSupplier {
readonly serviceVersion: () => string;
readonly endpoint: () => Promise<health.HealthServiceStatusEndpoint>;
}
export function registerHealthRoute(
app: oak.Application,
supplier: HealthRouteSupplier,
): void {
const router = new oak.Router()
.get("/health", async (ctx) => {
const ep = await supplier.endpoint();
Object.entries(ep.headers).forEach((e) =>
ctx.response.headers.set(e[0], e[1])
);
ctx.response.body = ep.body;
})
.get("/health/version", (ctx) => {
ctx.response.body = supplier.serviceVersion;
});
app.use(router.routes());
}
export const responseTimeHeaderName = "X-Response-Time";
export interface AccessReport {
readonly responseTime: number;
}
export interface AccessReporter {
(ctx: oak.Context<Record<string, unknown>>, report: AccessReport): void;
}
export function defaultAccessReporter(
ctx: oak.Context<Record<string, unknown>>,
report: AccessReport,
): void {
console.log(
`${colors.green(ctx.request.method)} ${
colors.brightBlue(ctx.response.status.toString())
} ${colors.yellow(ctx.request.url.toString())} - ${
colors.gray(report.responseTime.toString())
}`,
);
}
export interface TypicalMiddlewareOptions {
readonly accessReporter?: AccessReporter;
}
export function registerTypicalMiddleware(
app: oak.Application,
options?: {
accessReporter?: AccessReporter;
},
): void {
if (options?.accessReporter) {
const reporter = options?.accessReporter;
app.use(async (ctx, next) => {
await next();
reporter(
ctx,
{
responseTime: Number.parseInt(
ctx.response.headers.get(responseTimeHeaderName) || "-1",
),
},
);
});
}
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const responseTime = Date.now() - start;
ctx.response.headers.set(responseTimeHeaderName, `${responseTime}`);
});
}