From 9cfe0da3d839e5cd3b22643ac4cc80a046f0b119 Mon Sep 17 00:00:00 2001 From: Wei Zhu Date: Thu, 12 Dec 2024 04:50:31 +1030 Subject: [PATCH] fix: route ids were merged incorrectly --- src/build.ts | 19 ++++---- src/template.ts | 12 +++-- tests/__snapshots__/build.test.ts.snap | 64 +++++++++++++++----------- tests/fixture.ts | 12 +++++ 4 files changed, 65 insertions(+), 42 deletions(-) diff --git a/src/build.ts b/src/build.ts index 4ff4ba31..c43d6517 100644 --- a/src/build.ts +++ b/src/build.ts @@ -11,15 +11,15 @@ interface Options { } type RoutesInfo = Record export const DEFAULT_OUTPUT_DIR_PATH = './.react-router/types' -async function buildHelpers(config: RequiredReactRouterConfig): Promise { +async function buildHelpers(config: RequiredReactRouterConfig): Promise<[RoutesInfo, string[]]> { const routesInfo: RoutesInfo = {}; + const routeIds: string[] = []; const handleRoutesRecursive = ( parentId?: string, parentPath: RouteManifestEntry[] = [], @@ -29,9 +29,9 @@ async function buildHelpers(config: RequiredReactRouterConfig): Promise { let currentPath = parentPath; + routeIds.push(route.id); if (route.id === 'root') { routesInfo['/'] = { - id: route.id, fileName: route.file, params: [], }; @@ -46,7 +46,6 @@ async function buildHelpers(config: RequiredReactRouterConfig): Promise ({ - id, + routeIds, + routes: Object.entries(routesInfo).map(([route, { fileName, params }]) => ({ route, params, fileName: slash(fileName.replace(/\.tsx?$/, '')), diff --git a/src/template.ts b/src/template.ts index 38c34732..f221133f 100644 --- a/src/template.ts +++ b/src/template.ts @@ -1,8 +1,8 @@ interface Context { strict?: boolean; relativeAppDirPath: string; + routeIds: string[]; routes: Array<{ - id: string, route: string; params: string[]; fileName: string; @@ -21,9 +21,8 @@ function exportedQuery(ctx: Context) { } function routes(ctx: Context) { - const routes = ctx.routes.map(({ id, route, params, fileName }) => + const routes = ctx.routes.map(({ route, params, fileName }) => `"${route}": { - id: '${id}', params: ${params.length > 0 ? `{${params.map(param => `${param}: string | number`).join('; ')}}` : 'never'}, query: ExportedQuery, }` @@ -34,6 +33,11 @@ function routes(ctx: Context) { }` } +function routeIds(ctx: Context) { + return `export type RouteId = + | ${ctx.routeIds.map(routeId => `'${routeId}'`).join(`\n${indent(6)}| `)};`; +} + export function template(ctx: Context) { return `declare module "safe-routes" { type URLSearchParamsInit = string | string[][] | Record | URLSearchParams; @@ -51,7 +55,7 @@ export function template(ctx: Context) { }[keyof Routes] >; - export type RouteId = Routes[keyof Routes]['id']; + ${routeIds(ctx)} export function $path< Route extends keyof Routes, diff --git a/tests/__snapshots__/build.test.ts.snap b/tests/__snapshots__/build.test.ts.snap index f77f3a0c..12f6add9 100644 --- a/tests/__snapshots__/build.test.ts.snap +++ b/tests/__snapshots__/build.test.ts.snap @@ -10,137 +10,114 @@ exports[`gen route types 1`] = ` export interface Routes { "/": { - id: 'root', params: never, query: ExportedQuery, }, "/:lang?/about": { - id: 'routes/($lang).about', params: {lang?: string | number}, query: ExportedQuery, }, "/admin": { - id: 'routes/admin._index', params: never, query: ExportedQuery, }, "/admin/episodes": { - id: 'routes/admin.episodes._index', params: never, query: ExportedQuery, }, "/admin/episodes/:id": { - id: 'routes/admin.episodes.$id._index', params: {id: string | number}, query: ExportedQuery, }, "/admin/episodes/:id/comments": { - id: 'routes/admin.episodes.$id.comments', params: {id: string | number}, query: ExportedQuery, }, "/admin/episodes/new": { - id: 'routes/admin.episodes.new', params: never, query: ExportedQuery, }, "/api/:id.json": { - id: 'routes/api.$id[.]json', params: {id: string | number}, query: ExportedQuery, }, "/auth": { - id: 'routes/auth._auth', params: never, query: ExportedQuery, }, "/auth/login": { - id: 'routes/auth._auth.login', params: never, query: ExportedQuery, }, + "/blog": { + params: never, + query: ExportedQuery, + }, "/blog/rss.xml": { - id: 'routes/blog.rss[.]xml', params: never, query: ExportedQuery, }, "/chats/:season/:episode": { - id: 'routes/chats_.$season.$episode', params: {season: string | number; episode: string | number}, query: ExportedQuery, }, "/chats/:season/:episode/:slug": { - id: 'routes/chats_.$season.$episode.$slug', params: {season: string | number; episode: string | number; slug: string | number}, query: ExportedQuery, }, "/credits": { - id: 'routes/credits', params: never, query: ExportedQuery, }, "/home": { - id: 'routes/(static).home', params: never, query: ExportedQuery, }, "/jokes": { - id: 'routes/jokes._index', params: never, query: ExportedQuery, }, "/jokes/:jokeId": { - id: 'routes/jokes.$jokeId', params: {jokeId: string | number}, query: ExportedQuery, }, "/people/:personId": { - id: 'routes/people.$personId', params: {personId: string | number}, query: ExportedQuery, }, "/people/:personId/:planId/remove-plan": { - id: 'routes/people.$personId.$planId.remove-plan', params: {personId: string | number; planId: string | number}, query: ExportedQuery, }, "/posts": { - id: 'routes/posts._index', params: never, query: ExportedQuery, }, "/posts/:id": { - id: 'routes/posts.$id', params: {id: string | number}, query: ExportedQuery, }, "/posts/*": { - id: 'routes/posts.$', params: {"*": string | number}, query: ExportedQuery, }, "/posts/delete": { - id: 'routes/posts.delete', params: never, query: ExportedQuery, }, "/s/:query": { - id: 'routes/s.$query', params: {query: string | number}, query: ExportedQuery, }, "/sign-in/*": { - id: 'routes/sign-in.$', params: {"*": string | number}, query: ExportedQuery, }, "/somewhere/cool/*": { - id: 'catchall', params: {"*": string | number}, query: ExportedQuery, }, "/static/home": { - id: 'routes/(static).home', params: never, query: ExportedQuery, } @@ -153,7 +130,38 @@ exports[`gen route types 1`] = ` }[keyof Routes] >; - export type RouteId = Routes[keyof Routes]['id']; + export type RouteId = + | 'root' + | 'routes/chats_.$season.$episode' + | 'routes/chats_.$season.$episode.$slug' + | 'routes/people.$personId' + | 'routes/people.$personId.$planId.remove-plan' + | 'routes/api.$id[.]json' + | 'routes/blog.rss[.]xml' + | 'routes/($lang).about' + | 'routes/(static).home' + | 'routes/posts._index' + | 'routes/posts.delete' + | 'routes/auth._auth' + | 'routes/auth._auth.login' + | 'routes/posts.$id' + | 'routes/sign-in.$' + | 'routes/s.$query' + | 'routes/credits' + | 'routes/posts.$' + | 'routes/admin' + | 'routes/admin.episodes._index' + | 'routes/admin.episodes.$id' + | 'routes/admin.episodes.$id.comments' + | 'routes/admin.episodes.$id._index' + | 'routes/admin.episodes.new' + | 'routes/admin._index' + | 'routes/jokes' + | 'routes/jokes.$jokeId' + | 'routes/jokes._index' + | 'routes/blog' + | 'routes/blog._index' + | 'catchall'; export function $path< Route extends keyof Routes, diff --git a/tests/fixture.ts b/tests/fixture.ts index 23f6b6b6..aa676412 100644 --- a/tests/fixture.ts +++ b/tests/fixture.ts @@ -172,6 +172,18 @@ export const testRoutes = path: "jokes", parentId: "root", }, + "routes/blog": { + file: "routes/blog.tsx", + id: "routes/blog", + path: "blog", + parentId: "root", + }, + "routes/blog._index": { + file: "routes/blog._index.tsx", + id: "routes/blog._index", + path: undefined, + parentId: "routes/blog", + }, catchall: { path: "/somewhere/cool/*", index: undefined,