-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-routes.ts
67 lines (56 loc) · 2.25 KB
/
build-routes.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
/**
* This script generates the routes file at build time.
* It scans the routes directory and generates the routes file with the necessary imports and exports.
* This is useful for production builds where the routes are bundled at compile time.
*/
import { Glob } from 'bun';
import { createHash } from 'crypto';
import { basename, dirname, extname } from 'path';
const computeSHA256 = (input: string) => createHash('sha256').update(input).digest('hex');
const lines = [
'// This file is generated at build time, please do not modify it manually',
'// @author: skitsanos',
'import type { Hono } from \'hono\';',
'// @ts-ignore',
'import type { UpgradeWebSocket } from \'hono/dist/types/helper/websocket\';'
];
const glob = new Glob('src/routes/**/*.ts');
const handlers: Record<string, any> = {};
const processFile = async (file: string) => {
const urlPath = dirname(file.replace(/\\/g, '/'));
const pathParsed = urlPath.replace(/\$/g, ':').replace(/^src\/routes/, '') || '/';
const fileExtension = extname(file);
const method = basename(file, fileExtension);
const handlerName = `handler${computeSHA256(file)}`;
lines.push(`import ${handlerName} from '@/${file.replace(/^src\//, '')}';`);
handlers[handlerName] = {
method,
handlerName,
url: pathParsed,
handler: await import(file)
};
};
// Process files sequentially to avoid potential issues with concurrent imports
for await (const file of glob.scan('.')) {
await processFile(file);
}
const generateRouteCode = (
{ method, url, handler, handlerName }: { method: string; url: string; handler: any; handlerName: string }
): string => {
if (method === 'ws') {
return ` instance.app.on('GET', '${url}', instance.upgradeWebSocket(${handlerName}));`;
}
if (Array.isArray(handler.default)) {
return ` instance.app.${method}('${url}', ...${handlerName});`;
}
return ` instance.app.${method}('${url}', ${handlerName});`;
};
lines.push(`
export interface HonoApp {
app: Hono,
upgradeWebSocket: UpgradeWebSocket
}
export const parseRoutesAtBuildTime = async (instance: HonoApp) => {
${Object.values(handlers).map(generateRouteCode).join('\n')}
};`);
await Bun.write('src/.routes/index.ts', lines.join('\n'));