Skip to content

Commit bf89de2

Browse files
committed
feat: experimental simple routes typings code generation
1 parent afdcc77 commit bf89de2

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

packages/engine/src/dev/dev.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
type GracileHandler,
99
} from '../server/request.js';
1010
import type { GracileConfig } from '../user-config.js';
11+
import { generateRoutesTypings } from './route-typings.js';
1112

1213
export async function createDevHandler({
1314
vite,
@@ -24,6 +25,11 @@ export async function createDevHandler({
2425

2526
const routes = await collectRoutes(root, gracileConfig.routes?.exclude);
2627

28+
if (gracileConfig.experimental?.generateRoutesTypings)
29+
generateRoutesTypings(root, routes).catch((error) =>
30+
logger.error(String(error)),
31+
);
32+
2733
vite.watcher.on('all', (event, file) => {
2834
// console.log({ event });
2935
if (
@@ -33,6 +39,11 @@ export async function createDevHandler({
3339
collectRoutes(root, gracileConfig.routes?.exclude)
3440
.then(() => {
3541
vite.hot.send('vite:invalidate');
42+
43+
if (gracileConfig.experimental?.generateRoutesTypings)
44+
generateRoutesTypings(root, routes).catch((error) =>
45+
logger.error(String(error)),
46+
);
3647
})
3748
.catch((e) => logger.error(String(e)));
3849
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { mkdir } from 'node:fs/promises';
2+
import { join } from 'node:path';
3+
4+
import { writeFile } from 'fs/promises';
5+
6+
import type { RoutesManifest } from '../routes/route.js';
7+
8+
export async function generateRoutesTypings(
9+
root: string,
10+
routes: RoutesManifest,
11+
) {
12+
// NOTE: For future, we'll provide parameters like:
13+
// `route('/blog/:id', { id: 'foo' })`.
14+
//
15+
// export const route: (path: string, params?: Params) => string;
16+
//
17+
18+
const typings = `declare module 'gracile:route' {
19+
export const route: (path: Route) => string;
20+
}
21+
22+
export type Route =
23+
| ${[...routes]
24+
.map(
25+
([v]) =>
26+
`\`${v
27+
.replace(
28+
/\{:(.*)\}/,
29+
// eslint-disable-next-line no-template-curly-in-string
30+
'${string}',
31+
)
32+
.replace(
33+
/:(.*?)\*\//,
34+
// eslint-disable-next-line no-template-curly-in-string
35+
'${string}',
36+
)}\``,
37+
)
38+
.join('\n | ')};
39+
`;
40+
41+
await mkdir(join(root, '.gracile')).catch(() => null);
42+
await writeFile(join(root, '.gracile/routes.d.ts'), typings);
43+
}

packages/engine/src/plugin.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,37 @@ export const gracile = (config?: GracileConfig): any /* Plugin */[] => {
5555
isClientBuilt = true;
5656

5757
return [
58+
{
59+
name: 'gracile-routes-codegen',
60+
61+
// watchChange(change) {
62+
// console.log({ change });
63+
// },
64+
65+
resolveId(id) {
66+
const virtualModuleId = 'gracile:route';
67+
const resolvedVirtualModuleId = `\0${virtualModuleId}`;
68+
69+
if (id === virtualModuleId) {
70+
return resolvedVirtualModuleId;
71+
}
72+
return null;
73+
},
74+
75+
load(id) {
76+
const virtualModuleId = 'gracile:route';
77+
const resolvedVirtualModuleId = `\0${virtualModuleId}`;
78+
79+
if (id === resolvedVirtualModuleId) {
80+
return `
81+
export function route(input){
82+
return input;
83+
}`;
84+
}
85+
return null;
86+
},
87+
},
88+
5889
{
5990
name: 'vite-plugin-gracile-serve-middleware',
6091

@@ -117,7 +148,7 @@ export const gracile = (config?: GracileConfig): any /* Plugin */[] => {
117148
root: viteConfig.root || process.cwd(),
118149

119150
server: { middlewareMode: true },
120-
// NOTE: Stub
151+
// NOTE: Stub. KEEP IT!
121152
optimizeDeps: { include: [] },
122153
});
123154

packages/engine/src/user-config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,14 @@ export interface GracileConfig {
6161
*/
6262
exclude?: string[];
6363
};
64+
65+
/**
66+
* Future, unstable features flags.
67+
*/
68+
experimental?: {
69+
/**
70+
* Exclude routes with an array of patterns. Useful for debugging.
71+
*/
72+
generateRoutesTypings?: boolean;
73+
};
6474
}

0 commit comments

Comments
 (0)