first commit
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Typed-routes codegen. From the scanned page routes, emit `app/routes.gen.ts`
|
||||
* with a `Routes` map (path → param types) and an `href()` builder — so links
|
||||
* are checked at compile time (unknown path or missing param = type error).
|
||||
*/
|
||||
|
||||
import type { Route } from "./match.ts";
|
||||
|
||||
export function generateRoutesFile(pages: Route[]): string {
|
||||
const seen = new Set<string>();
|
||||
const entries: string[] = [];
|
||||
for (const page of [...pages].sort((a, b) => a.raw.localeCompare(b.raw))) {
|
||||
if (seen.has(page.raw)) continue;
|
||||
seen.add(page.raw);
|
||||
const type = page.paramNames.length
|
||||
? `{ ${page.paramNames.map((n) => `${JSON.stringify(n)}: string`).join("; ")} }`
|
||||
: "Record<string, never>";
|
||||
entries.push(` ${JSON.stringify(page.raw)}: ${type};`);
|
||||
}
|
||||
|
||||
return `// AUTO-GENERATED by \`wrnexus dev\` — do not edit.
|
||||
// Typed routes: a compile-time map of every page path to its [param] types,
|
||||
// plus an href() builder that fills params and rejects unknown paths.
|
||||
|
||||
export interface Routes {
|
||||
${entries.join("\n") || " [path: string]: Record<string, string>;"}
|
||||
}
|
||||
|
||||
export type RoutePath = keyof Routes;
|
||||
|
||||
export function href<P extends RoutePath>(
|
||||
path: P,
|
||||
...args: Routes[P] extends Record<string, never> ? [] : [params: Routes[P]]
|
||||
): string {
|
||||
const params = (args[0] ?? {}) as Record<string, string>;
|
||||
return String(path)
|
||||
.split("/")
|
||||
.map((seg) =>
|
||||
seg.startsWith("[") && seg.endsWith("]")
|
||||
? encodeURIComponent(params[seg.slice(1, -1)] ?? "")
|
||||
: seg,
|
||||
)
|
||||
.join("/");
|
||||
}
|
||||
`;
|
||||
}
|
||||
Reference in New Issue
Block a user