deno.land / x / lume@v2.1.4 / middlewares / on_demand.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
import { posix } from "../deps/path.ts";import { contentType } from "../deps/media_types.ts";
import type { Middleware } from "../core/server.ts";import type Site from "../core/site.ts";
export type Router = (url: URL) => string | undefined;
export interface Options { site: Site; router?: Router;}
/** Render pages on demand */export default function onDemand(options: Options): Middleware { const site = options.site; let router = options.router;
const { routesFile, extraData } = (site._data.on_demand || {}) as MiddlewareOptions;
return async (request, next) => { const response = await next(request);
if (response.status !== 404) { return response; }
if (!router) { router = await createDefaultRouter( routesFile || site.root("/_routes.json"), ); }
const url = new URL(request.url); const file = router(url);
if (!file) { return response; }
const data = await extraData?.(request) ?? {}; const page = await site.renderPage(file, data);
if (!page) { return response; }
// Redirect /example to /example/ const pageUrl = page.data.url; if (!url.pathname.endsWith("/") && pageUrl.endsWith("/")) { return new Response(null, { status: 301, headers: { "location": posix.join(url.pathname, "/"), }, }); }
const pageResponse = new Response( page.content, { status: 200 }, );
const type = contentType(posix.extname(page.outputPath));
if (type) { pageResponse.headers.set("content-type", type); }
return pageResponse; };}
async function createDefaultRouter(file: string): Promise<Router> { const routes: Record<string, string> = JSON.parse( await Deno.readTextFile(file), ); return getRouter(new Map(Object.entries(routes)));}
export function getRouter(routes: Map<string, string>): Router { return function match(url: URL): string | undefined { const { pathname } = url; const path = routes.get(pathname);
// Handle urls like /example as /example/ if (!path && !pathname.endsWith("/")) { return routes.get(pathname + "/"); }
return path; };}
export interface MiddlewareOptions { extraData?: (request: Request) => Record<string, unknown>; routesFile?: string;}
lume

Version Info

Tagged at
a month ago