@tanstack/router-cli 0.0.1-beta.190 → 0.0.1-beta.192

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -157,7 +157,12 @@ async function generator(config) {
157
157
  }
158
158
 
159
159
  // Ensure that new FileRoute(anything?) is replace with FileRoute(${node.routePath})
160
- const replaced = routeCode.replace(fileRouteRegex, `new FileRoute('${node.routePath}')`);
160
+ // routePath can contain $ characters, which have special meaning when used in replace
161
+ // so we have to escape it by turning all $ into $$. But since we do it through a replace call
162
+ // we have to double escape it into $$$$. For more information, see
163
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement
164
+ const escapedRoutePath = node.routePath?.replaceAll('$', '$$$$') ?? '';
165
+ const replaced = routeCode.replace(fileRouteRegex, `new FileRoute('${escapedRoutePath}')`);
161
166
  if (replaced !== routeCode) {
162
167
  await fs__default["default"].writeFile(node.fullPath, replaced);
163
168
  }
@@ -180,7 +185,7 @@ async function generator(config) {
180
185
  return `'${routeNode.routePath}': {
181
186
  parentRoute: typeof ${routeNode.parent?.variableName ?? 'root'}Route
182
187
  }`;
183
- }).join('\n')}
188
+ }).join('\n')}
184
189
  }
185
190
  }`;
186
191
  const routeOptions = routeNodes.map(routeNode => {
@@ -268,7 +273,8 @@ function hasParentRoute(routes, routeToCheck) {
268
273
  if (!routeToCheck || routeToCheck === "/") {
269
274
  return null;
270
275
  }
271
- for (const route of routes) {
276
+ const sortedNodes = multiSortBy(routes, [d => d.routePath.length * -1, d => d.variableName]).filter(d => d.routePath !== `/${rootPathId}`);
277
+ for (const route of sortedNodes) {
272
278
  if (route.routePath === '/') continue;
273
279
  if (routeToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routeToCheck) {
274
280
  return route;
@@ -282,6 +288,7 @@ function hasParentRoute(routes, routeToCheck) {
282
288
 
283
289
  exports.fileRouteRegex = fileRouteRegex;
284
290
  exports.generator = generator;
291
+ exports.hasParentRoute = hasParentRoute;
285
292
  exports.multiSortBy = multiSortBy;
286
293
  exports.removeExt = removeExt;
287
294
  exports.rootPathId = rootPathId;
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\nimport * as prettier from 'prettier'\nimport { Config } from './config'\nimport { cleanPath, trimPathLeft } from '@tanstack/router-core'\n\nlet latestTask = 0\nexport const rootPathId = '__root'\nexport const fileRouteRegex = /new\\s+FileRoute\\(([^)]*)\\)/g\n\nexport type RouteNode = {\n filePath: string\n fullPath: string\n variableName: string\n routePath?: string\n cleanedPath?: string\n path?: string\n isNonPath?: boolean\n isNonLayout?: boolean\n isRoot?: boolean\n children?: RouteNode[]\n parent?: RouteNode\n}\n\nasync function getRouteNodes(config: Config) {\n const { routeFilePrefix, routeFileIgnorePrefix } = config\n\n let routeNodes: RouteNode[] = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fs.readdir(fullDir)\n\n dirList = dirList.filter((d) => {\n if (\n d.startsWith('.') ||\n (routeFileIgnorePrefix && d.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.startsWith(routeFilePrefix)\n }\n\n return true\n })\n\n await Promise.all(\n dirList.map(async (fileName) => {\n const fullPath = path.join(fullDir, fileName)\n const relativePath = path.join(dir, fileName)\n const stat = await fs.stat(fullPath)\n\n if (stat.isDirectory()) {\n await recurse(relativePath)\n } else {\n const filePath = path.join(dir, fileName)\n const filePathNoExt = removeExt(filePath)\n let routePath = replaceBackslash(cleanPath(`/${filePathNoExt.split('.').join('/')}`)) ?? ''\n const variableName = fileToVariable(routePath)\n\n // Remove the index from the route path and\n // if the route path is empty, use `/'\n if (routePath === 'index') {\n routePath = '/'\n } else if (routePath.endsWith('/index')) {\n routePath = routePath.replace(/\\/index$/, '/')\n }\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n return routeNodes\n}\n\nlet first = false\nlet skipMessage = false\n\nexport async function generator(config: Config) {\n console.log()\n\n if (!first) {\n console.log('🔄 Generating routes...')\n first = true\n } else if (skipMessage) {\n skipMessage = false\n } else {\n console.log('♻️ Regenerating routes...')\n }\n\n const taskId = latestTask + 1\n latestTask = taskId\n\n const checkLatest = () => {\n if (latestTask !== taskId) {\n skipMessage = true\n return false\n }\n\n return true\n }\n\n const start = Date.now()\n\n let routeNodes = await getRouteNodes(config)\n\n routeNodes = multiSortBy(routeNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n const routeTree: RouteNode[] = []\n\n // Loop over the flat list of routeNodes and\n // build up a tree based on the routeNodes' routePath\n routeNodes.forEach((node) => {\n // routeNodes.forEach((existingNode) => {\n // if (\n // node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)\n // // node.routePath.length > existingNode.routePath!.length\n // ) {\n // node.parent = existingNode\n // }\n // })\n const parentRoute = hasParentRoute(routeNodes, node.routePath)\n if (parentRoute) node.parent = parentRoute\n\n node.path = node.parent\n ? node.routePath?.replace(node.parent.routePath!, '') || '/'\n : node.routePath\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath?.split('/') ?? []\n let first = split[0] ?? trimmedPath ?? ''\n\n node.isNonPath = first.startsWith('_')\n node.isNonLayout = first.endsWith('_')\n\n node.cleanedPath = removeUnderscores(node.path) ?? ''\n\n if (node.parent) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n } else {\n routeTree.push(node)\n }\n })\n\n async function buildRouteConfig(\n nodes: RouteNode[],\n depth = 1,\n ): Promise<string> {\n const children = nodes.map(async (node) => {\n const routeCode = await fs.readFile(node.fullPath, 'utf-8')\n\n // Ensure the boilerplate for the route exists\n if (node.isRoot) {\n return\n }\n\n // Ensure that new FileRoute(anything?) is replace with FileRoute(${node.routePath})\n const replaced = routeCode.replace(\n fileRouteRegex,\n `new FileRoute('${node.routePath}')`,\n )\n\n if (replaced !== routeCode) {\n await fs.writeFile(node.fullPath, replaced)\n }\n\n const route = `${node.variableName}Route`\n\n if (node.children?.length) {\n const childConfigs = await buildRouteConfig(node.children, depth + 1)\n return `${route}.addChildren([${spaces(depth * 4)}${childConfigs}])`\n }\n\n return route\n })\n\n return (await Promise.all(children)).filter(Boolean).join(`,`)\n }\n\n const routeConfigChildrenText = await buildRouteConfig(routeTree)\n\n const routeImports = [\n `import { route as rootRoute } from './${sanitize(path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, rootPathId)))}'`,\n ...multiSortBy(routeNodes, [\n (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(\"index'\") ? -1 : 1),\n (d) => d,\n ]).map((node) => {\n return `import { route as ${node.variableName}Route } from './${sanitize(removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, node.filePath),\n ),\n ))}'`\n }),\n ].join('\\n')\n\n const routeTypes = `declare module '@tanstack/react-router' {\n interface FileRoutesByPath {\n ${routeNodes\n .map((routeNode) => {\n return `'${routeNode.routePath}': {\n parentRoute: typeof ${routeNode.parent?.variableName ?? 'root'}Route\n }`\n })\n .join('\\n')} \n }\n}`\n\n const routeOptions = routeNodes\n .map((routeNode) => {\n return `Object.assign(${routeNode.variableName ?? 'root'}Route.options, {\n ${[\n routeNode.isNonPath\n ? `id: '${routeNode.cleanedPath}'`\n : `path: '${routeNode.cleanedPath}'`,\n `getParentRoute: () => ${routeNode.parent?.variableName ?? 'root'\n }Route`,\n // `\\n// ${JSON.stringify(\n // {\n // ...routeNode,\n // parent: undefined,\n // children: undefined,\n // fullPath: undefined,\n // variableName: undefined,\n // },\n // null,\n // 2,\n // )\n // .split('\\n')\n // .join('\\n// ')}`,\n ]\n .filter(Boolean)\n .join(',')}\n })`\n })\n .join('\\n\\n')\n\n const routeConfig = `export const routeTree = rootRoute.addChildren([${routeConfigChildrenText}])`\n\n const routeConfigFileContent = await prettier.format(\n [routeImports, routeTypes, routeOptions, routeConfig].join('\\n\\n'),\n {\n semi: false,\n parser: 'typescript',\n },\n )\n\n const routeTreeContent = await fs\n .readFile(path.resolve(config.generatedRouteTree), 'utf-8')\n .catch((err: any) => {\n if (err.code === 'ENOENT') {\n return undefined\n }\n throw err\n })\n\n if (!checkLatest()) return\n\n if (routeTreeContent !== routeConfigFileContent) {\n await fs.ensureDir(path.dirname(path.resolve(config.generatedRouteTree)))\n if (!checkLatest()) return\n await fs.writeFile(\n path.resolve(config.generatedRouteTree),\n routeConfigFileContent,\n )\n }\n\n console.log(\n `🌲 Processed ${routeNodes.length} routes in ${Date.now() - start}ms`,\n )\n}\n\nfunction fileToVariable(d: string): string {\n return (\n removeUnderscores(d)\n ?.replace(/\\$/g, '')\n ?.split(/[/-]/g)\n .map((d, i) => (i > 0 ? capitalize(d) : d))\n .join('')\n .replace(/([^a-zA-Z0-9]|[\\.])/gm, '') ?? ''\n )\n}\n\nexport function removeExt(d: string) {\n return d.substring(0, d.lastIndexOf('.')) || d\n}\n\nfunction spaces(d: number): string {\n return Array.from({ length: d })\n .map(() => ' ')\n .join('')\n}\n\nexport function multiSortBy<T>(\n arr: T[],\n accessors: ((item: T) => any)[] = [(d) => d],\n): T[] {\n return arr\n .map((d, i) => [d, i] as const)\n .sort(([a, ai], [b, bi]) => {\n for (const accessor of accessors) {\n const ao = accessor(a)\n const bo = accessor(b)\n\n if (typeof ao === 'undefined') {\n if (typeof bo === 'undefined') {\n continue\n }\n return 1\n }\n\n if (ao === bo) {\n continue\n }\n\n return ao > bo ? 1 : -1\n }\n\n return ai - bi\n })\n .map(([d]) => d)\n}\n\nfunction capitalize(s: string) {\n if (typeof s !== 'string') return ''\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nfunction sanitize(s?: string) {\n return replaceBackslash(s?.replace(/\\\\index/gi, ''))\n}\n\nfunction removeUnderscores(s?: string) {\n return s?.replace(/(^_|_$)/, '').replace(/(\\/_|_\\/)/, '/');\n}\n\nfunction replaceBackslash(s?: string) {\n return s?.replace(/\\\\/gi, '/')\n}\n\nfunction hasParentRoute(routes: RouteNode[], routeToCheck: string | undefined): RouteNode | null {\n if (!routeToCheck || routeToCheck === \"/\") {\n return null;\n }\n for (const route of routes) {\n if (route.routePath === '/') continue;\n if (routeToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routeToCheck) {\n return route;\n }\n }\n const segments = routeToCheck.split(\"/\");\n segments.pop(); // Remove the last segment\n const parentRoute = segments.join(\"/\");\n return hasParentRoute(routes, parentRoute);\n}\n"],"names":["latestTask","rootPathId","fileRouteRegex","getRouteNodes","config","routeFilePrefix","routeFileIgnorePrefix","routeNodes","recurse","dir","fullDir","path","resolve","routesDirectory","dirList","fs","readdir","filter","d","startsWith","Promise","all","map","fileName","fullPath","join","relativePath","stat","isDirectory","filePath","filePathNoExt","removeExt","routePath","replaceBackslash","cleanPath","split","variableName","fileToVariable","endsWith","replace","push","first","skipMessage","generator","console","log","taskId","checkLatest","start","Date","now","multiSortBy","length","routeTree","forEach","node","parentRoute","hasParentRoute","parent","trimmedPath","trimPathLeft","isNonPath","isNonLayout","cleanedPath","removeUnderscores","children","buildRouteConfig","nodes","depth","routeCode","readFile","isRoot","replaced","writeFile","route","childConfigs","spaces","Boolean","routeConfigChildrenText","routeImports","sanitize","relative","dirname","generatedRouteTree","includes","routeTypes","routeNode","routeOptions","routeConfig","routeConfigFileContent","prettier","format","semi","parser","routeTreeContent","catch","err","code","undefined","ensureDir","i","capitalize","substring","lastIndexOf","Array","from","arr","accessors","sort","a","ai","b","bi","accessor","ao","bo","s","charAt","toUpperCase","slice","routes","routeToCheck","segments","pop"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,IAAIA,UAAU,GAAG,CAAC,CAAA;AACX,MAAMC,UAAU,GAAG,SAAQ;AAC3B,MAAMC,cAAc,GAAG,8BAA6B;AAgB3D,eAAeC,aAAaA,CAACC,MAAc,EAAE;EAC3C,MAAM;IAAEC,eAAe;AAAEC,IAAAA,qBAAAA;AAAsB,GAAC,GAAGF,MAAM,CAAA;EAEzD,IAAIG,UAAuB,GAAG,EAAE,CAAA;EAEhC,eAAeC,OAAOA,CAACC,GAAW,EAAE;IAClC,MAAMC,OAAO,GAAGC,wBAAI,CAACC,OAAO,CAACR,MAAM,CAACS,eAAe,EAAEJ,GAAG,CAAC,CAAA;IACzD,IAAIK,OAAO,GAAG,MAAMC,sBAAE,CAACC,OAAO,CAACN,OAAO,CAAC,CAAA;AAEvCI,IAAAA,OAAO,GAAGA,OAAO,CAACG,MAAM,CAAEC,CAAC,IAAK;AAC9B,MAAA,IACEA,CAAC,CAACC,UAAU,CAAC,GAAG,CAAC,IAChBb,qBAAqB,IAAIY,CAAC,CAACC,UAAU,CAACb,qBAAqB,CAAE,EAC9D;AACA,QAAA,OAAO,KAAK,CAAA;AACd,OAAA;AAEA,MAAA,IAAID,eAAe,EAAE;AACnB,QAAA,OAAOa,CAAC,CAACC,UAAU,CAACd,eAAe,CAAC,CAAA;AACtC,OAAA;AAEA,MAAA,OAAO,IAAI,CAAA;AACb,KAAC,CAAC,CAAA;IAEF,MAAMe,OAAO,CAACC,GAAG,CACfP,OAAO,CAACQ,GAAG,CAAC,MAAOC,QAAQ,IAAK;MAC9B,MAAMC,QAAQ,GAAGb,wBAAI,CAACc,IAAI,CAACf,OAAO,EAAEa,QAAQ,CAAC,CAAA;MAC7C,MAAMG,YAAY,GAAGf,wBAAI,CAACc,IAAI,CAAChB,GAAG,EAAEc,QAAQ,CAAC,CAAA;MAC7C,MAAMI,IAAI,GAAG,MAAMZ,sBAAE,CAACY,IAAI,CAACH,QAAQ,CAAC,CAAA;AAEpC,MAAA,IAAIG,IAAI,CAACC,WAAW,EAAE,EAAE;QACtB,MAAMpB,OAAO,CAACkB,YAAY,CAAC,CAAA;AAC7B,OAAC,MAAM;QACL,MAAMG,QAAQ,GAAGlB,wBAAI,CAACc,IAAI,CAAChB,GAAG,EAAEc,QAAQ,CAAC,CAAA;AACzC,QAAA,MAAMO,aAAa,GAAGC,SAAS,CAACF,QAAQ,CAAC,CAAA;QACzC,IAAIG,SAAS,GAAGC,gBAAgB,CAACC,oBAAS,CAAE,CAAA,CAAA,EAAGJ,aAAa,CAACK,KAAK,CAAC,GAAG,CAAC,CAACV,IAAI,CAAC,GAAG,CAAE,CAAC,CAAA,CAAC,CAAC,IAAI,EAAE,CAAA;AAC3F,QAAA,MAAMW,YAAY,GAAGC,cAAc,CAACL,SAAS,CAAC,CAAA;;AAE9C;AACA;QACA,IAAIA,SAAS,KAAK,OAAO,EAAE;AACzBA,UAAAA,SAAS,GAAG,GAAG,CAAA;SAChB,MAAM,IAAIA,SAAS,CAACM,QAAQ,CAAC,QAAQ,CAAC,EAAE;UACvCN,SAAS,GAAGA,SAAS,CAACO,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;AAChD,SAAA;QAEAhC,UAAU,CAACiC,IAAI,CAAC;UACdX,QAAQ;UACRL,QAAQ;UACRQ,SAAS;AACTI,UAAAA,YAAAA;AACF,SAAC,CAAC,CAAA;AACJ,OAAA;AACF,KAAC,CACH,CAAC,CAAA;AAED,IAAA,OAAO7B,UAAU,CAAA;AACnB,GAAA;EAEA,MAAMC,OAAO,CAAC,IAAI,CAAC,CAAA;AAEnB,EAAA,OAAOD,UAAU,CAAA;AACnB,CAAA;AAEA,IAAIkC,KAAK,GAAG,KAAK,CAAA;AACjB,IAAIC,WAAW,GAAG,KAAK,CAAA;AAEhB,eAAeC,SAASA,CAACvC,MAAc,EAAE;EAC9CwC,OAAO,CAACC,GAAG,EAAE,CAAA;EAEb,IAAI,CAACJ,KAAK,EAAE;AACVG,IAAAA,OAAO,CAACC,GAAG,CAAC,yBAAyB,CAAC,CAAA;AACtCJ,IAAAA,KAAK,GAAG,IAAI,CAAA;GACb,MAAM,IAAIC,WAAW,EAAE;AACtBA,IAAAA,WAAW,GAAG,KAAK,CAAA;AACrB,GAAC,MAAM;AACLE,IAAAA,OAAO,CAACC,GAAG,CAAC,4BAA4B,CAAC,CAAA;AAC3C,GAAA;AAEA,EAAA,MAAMC,MAAM,GAAG9C,UAAU,GAAG,CAAC,CAAA;AAC7BA,EAAAA,UAAU,GAAG8C,MAAM,CAAA;EAEnB,MAAMC,WAAW,GAAGA,MAAM;IACxB,IAAI/C,UAAU,KAAK8C,MAAM,EAAE;AACzBJ,MAAAA,WAAW,GAAG,IAAI,CAAA;AAClB,MAAA,OAAO,KAAK,CAAA;AACd,KAAA;AAEA,IAAA,OAAO,IAAI,CAAA;GACZ,CAAA;AAED,EAAA,MAAMM,KAAK,GAAGC,IAAI,CAACC,GAAG,EAAE,CAAA;AAExB,EAAA,IAAI3C,UAAU,GAAG,MAAMJ,aAAa,CAACC,MAAM,CAAC,CAAA;AAE5CG,EAAAA,UAAU,GAAG4C,WAAW,CAAC5C,UAAU,EAAE,CAClCW,CAAC,IAAMA,CAAC,CAACc,SAAS,KAAK,GAAG,GAAG,CAAC,CAAC,GAAG,CAAE,EACpCd,CAAC,IAAKA,CAAC,CAACc,SAAS,EAAEG,KAAK,CAAC,GAAG,CAAC,CAACiB,MAAM,EACpClC,CAAC,IAAMA,CAAC,CAACc,SAAS,EAAEM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAE,EAC3CpB,CAAC,IAAKA,CAAC,CAACc,SAAS,CACnB,CAAC,CAACf,MAAM,CAAEC,CAAC,IAAKA,CAAC,CAACc,SAAS,KAAM,CAAG/B,CAAAA,EAAAA,UAAW,EAAC,CAAC,CAAA;EAElD,MAAMoD,SAAsB,GAAG,EAAE,CAAA;;AAEjC;AACA;AACA9C,EAAAA,UAAU,CAAC+C,OAAO,CAAEC,IAAI,IAAK;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACA,MAAMC,WAAW,GAAGC,cAAc,CAAClD,UAAU,EAAEgD,IAAI,CAACvB,SAAS,CAAC,CAAA;AAC9D,IAAA,IAAIwB,WAAW,EAAED,IAAI,CAACG,MAAM,GAAGF,WAAW,CAAA;IAE1CD,IAAI,CAAC5C,IAAI,GAAG4C,IAAI,CAACG,MAAM,GACnBH,IAAI,CAACvB,SAAS,EAAEO,OAAO,CAACgB,IAAI,CAACG,MAAM,CAAC1B,SAAS,EAAG,EAAE,CAAC,IAAI,GAAG,GAC1DuB,IAAI,CAACvB,SAAS,CAAA;IAElB,MAAM2B,WAAW,GAAGC,uBAAY,CAACL,IAAI,CAAC5C,IAAI,IAAI,EAAE,CAAC,CAAA;IAEjD,MAAMwB,KAAK,GAAGwB,WAAW,EAAExB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;IAC3C,IAAIM,KAAK,GAAGN,KAAK,CAAC,CAAC,CAAC,IAAIwB,WAAW,IAAI,EAAE,CAAA;IAEzCJ,IAAI,CAACM,SAAS,GAAGpB,KAAK,CAACtB,UAAU,CAAC,GAAG,CAAC,CAAA;IACtCoC,IAAI,CAACO,WAAW,GAAGrB,KAAK,CAACH,QAAQ,CAAC,GAAG,CAAC,CAAA;IAEtCiB,IAAI,CAACQ,WAAW,GAAGC,iBAAiB,CAACT,IAAI,CAAC5C,IAAI,CAAC,IAAI,EAAE,CAAA;IAErD,IAAI4C,IAAI,CAACG,MAAM,EAAE;MACfH,IAAI,CAACG,MAAM,CAACO,QAAQ,GAAGV,IAAI,CAACG,MAAM,CAACO,QAAQ,IAAI,EAAE,CAAA;MACjDV,IAAI,CAACG,MAAM,CAACO,QAAQ,CAACzB,IAAI,CAACe,IAAI,CAAC,CAAA;AACjC,KAAC,MAAM;AACLF,MAAAA,SAAS,CAACb,IAAI,CAACe,IAAI,CAAC,CAAA;AACtB,KAAA;AACF,GAAC,CAAC,CAAA;AAEF,EAAA,eAAeW,gBAAgBA,CAC7BC,KAAkB,EAClBC,KAAK,GAAG,CAAC,EACQ;IACjB,MAAMH,QAAQ,GAAGE,KAAK,CAAC7C,GAAG,CAAC,MAAOiC,IAAI,IAAK;AACzC,MAAA,MAAMc,SAAS,GAAG,MAAMtD,sBAAE,CAACuD,QAAQ,CAACf,IAAI,CAAC/B,QAAQ,EAAE,OAAO,CAAC,CAAA;;AAE3D;MACA,IAAI+B,IAAI,CAACgB,MAAM,EAAE;AACf,QAAA,OAAA;AACF,OAAA;;AAEA;AACA,MAAA,MAAMC,QAAQ,GAAGH,SAAS,CAAC9B,OAAO,CAChCrC,cAAc,EACb,CAAiBqD,eAAAA,EAAAA,IAAI,CAACvB,SAAU,IACnC,CAAC,CAAA;MAED,IAAIwC,QAAQ,KAAKH,SAAS,EAAE;QAC1B,MAAMtD,sBAAE,CAAC0D,SAAS,CAAClB,IAAI,CAAC/B,QAAQ,EAAEgD,QAAQ,CAAC,CAAA;AAC7C,OAAA;AAEA,MAAA,MAAME,KAAK,GAAI,CAAA,EAAEnB,IAAI,CAACnB,YAAa,CAAM,KAAA,CAAA,CAAA;AAEzC,MAAA,IAAImB,IAAI,CAACU,QAAQ,EAAEb,MAAM,EAAE;AACzB,QAAA,MAAMuB,YAAY,GAAG,MAAMT,gBAAgB,CAACX,IAAI,CAACU,QAAQ,EAAEG,KAAK,GAAG,CAAC,CAAC,CAAA;QACrE,OAAQ,CAAA,EAAEM,KAAM,CAAA,cAAA,EAAgBE,MAAM,CAACR,KAAK,GAAG,CAAC,CAAE,CAAEO,EAAAA,YAAa,CAAG,EAAA,CAAA,CAAA;AACtE,OAAA;AAEA,MAAA,OAAOD,KAAK,CAAA;AACd,KAAC,CAAC,CAAA;AAEF,IAAA,OAAO,CAAC,MAAMtD,OAAO,CAACC,GAAG,CAAC4C,QAAQ,CAAC,EAAEhD,MAAM,CAAC4D,OAAO,CAAC,CAACpD,IAAI,CAAE,GAAE,CAAC,CAAA;AAChE,GAAA;AAEA,EAAA,MAAMqD,uBAAuB,GAAG,MAAMZ,gBAAgB,CAACb,SAAS,CAAC,CAAA;EAEjE,MAAM0B,YAAY,GAAG,CAClB,CAAA,sCAAA,EAAwCC,QAAQ,CAACrE,wBAAI,CAACsE,QAAQ,CAC7DtE,wBAAI,CAACuE,OAAO,CAAC9E,MAAM,CAAC+E,kBAAkB,CAAC,EACvCxE,wBAAI,CAACC,OAAO,CAACR,MAAM,CAACS,eAAe,EAAEZ,UAAU,CAAC,CAAC,CAAE,GAAE,EACvD,GAAGkD,WAAW,CAAC5C,UAAU,EAAE,CACxBW,CAAC,IAAMA,CAAC,CAACc,SAAS,EAAEoD,QAAQ,CAAE,IAAGnF,UAAW,CAAA,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAE,EACxDiB,CAAC,IAAKA,CAAC,CAACc,SAAS,EAAEG,KAAK,CAAC,GAAG,CAAC,CAACiB,MAAM,EACpClC,CAAC,IAAMA,CAAC,CAACc,SAAS,EAAEM,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,CAAE,EAChDpB,CAAC,IAAKA,CAAC,CACT,CAAC,CAACI,GAAG,CAAEiC,IAAI,IAAK;AACf,IAAA,OAAQ,qBAAoBA,IAAI,CAACnB,YAAa,CAAA,gBAAA,EAAkB4C,QAAQ,CAACjD,SAAS,CAChFpB,wBAAI,CAACsE,QAAQ,CACXtE,wBAAI,CAACuE,OAAO,CAAC9E,MAAM,CAAC+E,kBAAkB,CAAC,EACvCxE,wBAAI,CAACC,OAAO,CAACR,MAAM,CAACS,eAAe,EAAE0C,IAAI,CAAC1B,QAAQ,CACpD,CACF,CAAC,CAAE,CAAE,CAAA,CAAA,CAAA;AACP,GAAC,CAAC,CACH,CAACJ,IAAI,CAAC,IAAI,CAAC,CAAA;AAEZ,EAAA,MAAM4D,UAAU,GAAI,CAAA;AACtB;AACA,IAAA,EAAM9E,UAAU,CACTe,GAAG,CAAEgE,SAAS,IAAK;IAClB,OAAQ,CAAA,CAAA,EAAGA,SAAS,CAACtD,SAAU,CAAA;AACvC,8BAAA,EAAgCsD,SAAS,CAAC5B,MAAM,EAAEtB,YAAY,IAAI,MAAO,CAAA;AACzE,SAAU,CAAA,CAAA;AACJ,GAAC,CAAC,CACDX,IAAI,CAAC,IAAI,CAAE,CAAA;AAClB;AACA,CAAE,CAAA,CAAA;AAEA,EAAA,MAAM8D,YAAY,GAAGhF,UAAU,CAC5Be,GAAG,CAAEgE,SAAS,IAAK;AAClB,IAAA,OAAQ,CAAgBA,cAAAA,EAAAA,SAAS,CAAClD,YAAY,IAAI,MAAO,CAAA;AAC/D,QAAU,EAAA,CACAkD,SAAS,CAACzB,SAAS,GACd,QAAOyB,SAAS,CAACvB,WAAY,CAAA,CAAA,CAAE,GAC/B,CAAA,OAAA,EAASuB,SAAS,CAACvB,WAAY,CAAE,CAAA,CAAA,EACrC,CAAwBuB,sBAAAA,EAAAA,SAAS,CAAC5B,MAAM,EAAEtB,YAAY,IAAI,MAC1D,CAAA,KAAA,CAAA;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;KACD,CACEnB,MAAM,CAAC4D,OAAO,CAAC,CACfpD,IAAI,CAAC,GAAG,CAAE,CAAA;AACrB,QAAS,CAAA,CAAA;AACL,GAAC,CAAC,CACDA,IAAI,CAAC,MAAM,CAAC,CAAA;AAEf,EAAA,MAAM+D,WAAW,GAAI,CAAkDV,gDAAAA,EAAAA,uBAAwB,CAAG,EAAA,CAAA,CAAA;EAElG,MAAMW,sBAAsB,GAAG,MAAMC,mBAAQ,CAACC,MAAM,CAClD,CAACZ,YAAY,EAAEM,UAAU,EAAEE,YAAY,EAAEC,WAAW,CAAC,CAAC/D,IAAI,CAAC,MAAM,CAAC,EAClE;AACEmE,IAAAA,IAAI,EAAE,KAAK;AACXC,IAAAA,MAAM,EAAE,YAAA;AACV,GACF,CAAC,CAAA;EAED,MAAMC,gBAAgB,GAAG,MAAM/E,sBAAE,CAC9BuD,QAAQ,CAAC3D,wBAAI,CAACC,OAAO,CAACR,MAAM,CAAC+E,kBAAkB,CAAC,EAAE,OAAO,CAAC,CAC1DY,KAAK,CAAEC,GAAQ,IAAK;AACnB,IAAA,IAAIA,GAAG,CAACC,IAAI,KAAK,QAAQ,EAAE;AACzB,MAAA,OAAOC,SAAS,CAAA;AAClB,KAAA;AACA,IAAA,MAAMF,GAAG,CAAA;AACX,GAAC,CAAC,CAAA;AAEJ,EAAA,IAAI,CAACjD,WAAW,EAAE,EAAE,OAAA;EAEpB,IAAI+C,gBAAgB,KAAKL,sBAAsB,EAAE;AAC/C,IAAA,MAAM1E,sBAAE,CAACoF,SAAS,CAACxF,wBAAI,CAACuE,OAAO,CAACvE,wBAAI,CAACC,OAAO,CAACR,MAAM,CAAC+E,kBAAkB,CAAC,CAAC,CAAC,CAAA;AACzE,IAAA,IAAI,CAACpC,WAAW,EAAE,EAAE,OAAA;AACpB,IAAA,MAAMhC,sBAAE,CAAC0D,SAAS,CAChB9D,wBAAI,CAACC,OAAO,CAACR,MAAM,CAAC+E,kBAAkB,CAAC,EACvCM,sBACF,CAAC,CAAA;AACH,GAAA;AAEA7C,EAAAA,OAAO,CAACC,GAAG,CACR,CAAetC,aAAAA,EAAAA,UAAU,CAAC6C,MAAO,CAAA,WAAA,EAAaH,IAAI,CAACC,GAAG,EAAE,GAAGF,KAAM,IACpE,CAAC,CAAA;AACH,CAAA;AAEA,SAASX,cAAcA,CAACnB,CAAS,EAAU;EACzC,OACE8C,iBAAiB,CAAC9C,CAAC,CAAC,EAChBqB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAClBJ,KAAK,CAAC,OAAO,CAAC,CACfb,GAAG,CAAC,CAACJ,CAAC,EAAEkF,CAAC,KAAMA,CAAC,GAAG,CAAC,GAAGC,UAAU,CAACnF,CAAC,CAAC,GAAGA,CAAE,CAAC,CAC1CO,IAAI,CAAC,EAAE,CAAC,CACRc,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;AAEjD,CAAA;AAEO,SAASR,SAASA,CAACb,CAAS,EAAE;AACnC,EAAA,OAAOA,CAAC,CAACoF,SAAS,CAAC,CAAC,EAAEpF,CAAC,CAACqF,WAAW,CAAC,GAAG,CAAC,CAAC,IAAIrF,CAAC,CAAA;AAChD,CAAA;AAEA,SAAS0D,MAAMA,CAAC1D,CAAS,EAAU;EACjC,OAAOsF,KAAK,CAACC,IAAI,CAAC;AAAErD,IAAAA,MAAM,EAAElC,CAAAA;GAAG,CAAC,CAC7BI,GAAG,CAAC,MAAM,GAAG,CAAC,CACdG,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAA;AAEO,SAAS0B,WAAWA,CACzBuD,GAAQ,EACRC,SAA+B,GAAG,CAAEzF,CAAC,IAAKA,CAAC,CAAC,EACvC;AACL,EAAA,OAAOwF,GAAG,CACPpF,GAAG,CAAC,CAACJ,CAAC,EAAEkF,CAAC,KAAK,CAAClF,CAAC,EAAEkF,CAAC,CAAU,CAAC,CAC9BQ,IAAI,CAAC,CAAC,CAACC,CAAC,EAAEC,EAAE,CAAC,EAAE,CAACC,CAAC,EAAEC,EAAE,CAAC,KAAK;AAC1B,IAAA,KAAK,MAAMC,QAAQ,IAAIN,SAAS,EAAE;AAChC,MAAA,MAAMO,EAAE,GAAGD,QAAQ,CAACJ,CAAC,CAAC,CAAA;AACtB,MAAA,MAAMM,EAAE,GAAGF,QAAQ,CAACF,CAAC,CAAC,CAAA;AAEtB,MAAA,IAAI,OAAOG,EAAE,KAAK,WAAW,EAAE;AAC7B,QAAA,IAAI,OAAOC,EAAE,KAAK,WAAW,EAAE;AAC7B,UAAA,SAAA;AACF,SAAA;AACA,QAAA,OAAO,CAAC,CAAA;AACV,OAAA;MAEA,IAAID,EAAE,KAAKC,EAAE,EAAE;AACb,QAAA,SAAA;AACF,OAAA;AAEA,MAAA,OAAOD,EAAE,GAAGC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;AACzB,KAAA;IAEA,OAAOL,EAAE,GAAGE,EAAE,CAAA;GACf,CAAC,CACD1F,GAAG,CAAC,CAAC,CAACJ,CAAC,CAAC,KAAKA,CAAC,CAAC,CAAA;AACpB,CAAA;AAEA,SAASmF,UAAUA,CAACe,CAAS,EAAE;AAC7B,EAAA,IAAI,OAAOA,CAAC,KAAK,QAAQ,EAAE,OAAO,EAAE,CAAA;AACpC,EAAA,OAAOA,CAAC,CAACC,MAAM,CAAC,CAAC,CAAC,CAACC,WAAW,EAAE,GAAGF,CAAC,CAACG,KAAK,CAAC,CAAC,CAAC,CAAA;AAC/C,CAAA;AAEA,SAASvC,QAAQA,CAACoC,CAAU,EAAE;EAC5B,OAAOnF,gBAAgB,CAACmF,CAAC,EAAE7E,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAA;AACtD,CAAA;AAEA,SAASyB,iBAAiBA,CAACoD,CAAU,EAAE;AACrC,EAAA,OAAOA,CAAC,EAAE7E,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAACA,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;AAC5D,CAAA;AAEA,SAASN,gBAAgBA,CAACmF,CAAU,EAAE;AACpC,EAAA,OAAOA,CAAC,EAAE7E,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAChC,CAAA;AAEA,SAASkB,cAAcA,CAAC+D,MAAmB,EAAEC,YAAgC,EAAoB;AAC/F,EAAA,IAAI,CAACA,YAAY,IAAIA,YAAY,KAAK,GAAG,EAAE;AACzC,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;AACA,EAAA,KAAK,MAAM/C,KAAK,IAAI8C,MAAM,EAAE;AAC1B,IAAA,IAAI9C,KAAK,CAAC1C,SAAS,KAAK,GAAG,EAAE,SAAA;AAC7B,IAAA,IAAIyF,YAAY,CAACtG,UAAU,CAAE,CAAA,EAAEuD,KAAK,CAAC1C,SAAU,CAAE,CAAA,CAAA,CAAC,IAAI0C,KAAK,CAAC1C,SAAS,KAAKyF,YAAY,EAAE;AACtF,MAAA,OAAO/C,KAAK,CAAA;AACd,KAAA;AACF,GAAA;AACA,EAAA,MAAMgD,QAAQ,GAAGD,YAAY,CAACtF,KAAK,CAAC,GAAG,CAAC,CAAA;AACxCuF,EAAAA,QAAQ,CAACC,GAAG,EAAE,CAAC;AACf,EAAA,MAAMnE,WAAW,GAAGkE,QAAQ,CAACjG,IAAI,CAAC,GAAG,CAAC,CAAA;AACtC,EAAA,OAAOgC,cAAc,CAAC+D,MAAM,EAAEhE,WAAW,CAAC,CAAA;AAC5C;;;;;;;;"}
1
+ {"version":3,"file":"generator.js","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\nimport * as prettier from 'prettier'\nimport { Config } from './config'\nimport { cleanPath, trimPathLeft } from '@tanstack/router-core'\n\nlet latestTask = 0\nexport const rootPathId = '__root'\nexport const fileRouteRegex = /new\\s+FileRoute\\(([^)]*)\\)/g\n\nexport type RouteNode = {\n filePath: string\n fullPath: string\n variableName: string\n routePath?: string\n cleanedPath?: string\n path?: string\n isNonPath?: boolean\n isNonLayout?: boolean\n isRoot?: boolean\n children?: RouteNode[]\n parent?: RouteNode\n}\n\nasync function getRouteNodes(config: Config) {\n const { routeFilePrefix, routeFileIgnorePrefix } = config\n\n let routeNodes: RouteNode[] = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fs.readdir(fullDir)\n\n dirList = dirList.filter((d) => {\n if (\n d.startsWith('.') ||\n (routeFileIgnorePrefix && d.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.startsWith(routeFilePrefix)\n }\n\n return true\n })\n\n await Promise.all(\n dirList.map(async (fileName) => {\n const fullPath = path.join(fullDir, fileName)\n const relativePath = path.join(dir, fileName)\n const stat = await fs.stat(fullPath)\n\n if (stat.isDirectory()) {\n await recurse(relativePath)\n } else {\n const filePath = path.join(dir, fileName)\n const filePathNoExt = removeExt(filePath)\n let routePath = replaceBackslash(cleanPath(`/${filePathNoExt.split('.').join('/')}`)) ?? ''\n const variableName = fileToVariable(routePath)\n\n // Remove the index from the route path and\n // if the route path is empty, use `/'\n if (routePath === 'index') {\n routePath = '/'\n } else if (routePath.endsWith('/index')) {\n routePath = routePath.replace(/\\/index$/, '/')\n }\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n return routeNodes\n}\n\nlet first = false\nlet skipMessage = false\n\nexport async function generator(config: Config) {\n console.log()\n\n if (!first) {\n console.log('🔄 Generating routes...')\n first = true\n } else if (skipMessage) {\n skipMessage = false\n } else {\n console.log('♻️ Regenerating routes...')\n }\n\n const taskId = latestTask + 1\n latestTask = taskId\n\n const checkLatest = () => {\n if (latestTask !== taskId) {\n skipMessage = true\n return false\n }\n\n return true\n }\n\n const start = Date.now()\n\n let routeNodes = await getRouteNodes(config)\n\n routeNodes = multiSortBy(routeNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n const routeTree: RouteNode[] = []\n\n // Loop over the flat list of routeNodes and\n // build up a tree based on the routeNodes' routePath\n routeNodes.forEach((node) => {\n // routeNodes.forEach((existingNode) => {\n // if (\n // node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)\n // // node.routePath.length > existingNode.routePath!.length\n // ) {\n // node.parent = existingNode\n // }\n // })\n const parentRoute = hasParentRoute(routeNodes, node.routePath)\n if (parentRoute) node.parent = parentRoute\n\n node.path = node.parent\n ? node.routePath?.replace(node.parent.routePath!, '') || '/'\n : node.routePath\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath?.split('/') ?? []\n let first = split[0] ?? trimmedPath ?? ''\n\n node.isNonPath = first.startsWith('_')\n node.isNonLayout = first.endsWith('_')\n\n node.cleanedPath = removeUnderscores(node.path) ?? ''\n\n if (node.parent) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n } else {\n routeTree.push(node)\n }\n })\n\n async function buildRouteConfig(\n nodes: RouteNode[],\n depth = 1,\n ): Promise<string> {\n const children = nodes.map(async (node) => {\n const routeCode = await fs.readFile(node.fullPath, 'utf-8')\n\n // Ensure the boilerplate for the route exists\n if (node.isRoot) {\n return\n }\n\n // Ensure that new FileRoute(anything?) is replace with FileRoute(${node.routePath})\n // routePath can contain $ characters, which have special meaning when used in replace\n // so we have to escape it by turning all $ into $$. But since we do it through a replace call\n // we have to double escape it into $$$$. For more information, see\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement\n const escapedRoutePath = node.routePath?.replaceAll('$', '$$$$') ?? ''\n const replaced = routeCode.replace(\n fileRouteRegex,\n `new FileRoute('${escapedRoutePath}')`,\n )\n\n if (replaced !== routeCode) {\n await fs.writeFile(node.fullPath, replaced)\n }\n\n const route = `${node.variableName}Route`\n\n if (node.children?.length) {\n const childConfigs = await buildRouteConfig(node.children, depth + 1)\n return `${route}.addChildren([${spaces(depth * 4)}${childConfigs}])`\n }\n\n return route\n })\n\n return (await Promise.all(children)).filter(Boolean).join(`,`)\n }\n\n const routeConfigChildrenText = await buildRouteConfig(routeTree)\n\n const routeImports = [\n `import { route as rootRoute } from './${sanitize(path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, rootPathId)))}'`,\n ...multiSortBy(routeNodes, [\n (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(\"index'\") ? -1 : 1),\n (d) => d,\n ]).map((node) => {\n return `import { route as ${node.variableName}Route } from './${sanitize(removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, node.filePath),\n ),\n ))}'`\n }),\n ].join('\\n')\n\n const routeTypes = `declare module '@tanstack/react-router' {\n interface FileRoutesByPath {\n ${routeNodes\n .map((routeNode) => {\n return `'${routeNode.routePath}': {\n parentRoute: typeof ${routeNode.parent?.variableName ?? 'root'}Route\n }`\n })\n .join('\\n')}\n }\n}`\n\n const routeOptions = routeNodes\n .map((routeNode) => {\n return `Object.assign(${routeNode.variableName ?? 'root'}Route.options, {\n ${[\n routeNode.isNonPath\n ? `id: '${routeNode.cleanedPath}'`\n : `path: '${routeNode.cleanedPath}'`,\n `getParentRoute: () => ${routeNode.parent?.variableName ?? 'root'\n }Route`,\n // `\\n// ${JSON.stringify(\n // {\n // ...routeNode,\n // parent: undefined,\n // children: undefined,\n // fullPath: undefined,\n // variableName: undefined,\n // },\n // null,\n // 2,\n // )\n // .split('\\n')\n // .join('\\n// ')}`,\n ]\n .filter(Boolean)\n .join(',')}\n })`\n })\n .join('\\n\\n')\n\n const routeConfig = `export const routeTree = rootRoute.addChildren([${routeConfigChildrenText}])`\n\n const routeConfigFileContent = await prettier.format(\n [routeImports, routeTypes, routeOptions, routeConfig].join('\\n\\n'),\n {\n semi: false,\n parser: 'typescript',\n },\n )\n\n const routeTreeContent = await fs\n .readFile(path.resolve(config.generatedRouteTree), 'utf-8')\n .catch((err: any) => {\n if (err.code === 'ENOENT') {\n return undefined\n }\n throw err\n })\n\n if (!checkLatest()) return\n\n if (routeTreeContent !== routeConfigFileContent) {\n await fs.ensureDir(path.dirname(path.resolve(config.generatedRouteTree)))\n if (!checkLatest()) return\n await fs.writeFile(\n path.resolve(config.generatedRouteTree),\n routeConfigFileContent,\n )\n }\n\n console.log(\n `🌲 Processed ${routeNodes.length} routes in ${Date.now() - start}ms`,\n )\n}\n\nfunction fileToVariable(d: string): string {\n return (\n removeUnderscores(d)\n ?.replace(/\\$/g, '')\n ?.split(/[/-]/g)\n .map((d, i) => (i > 0 ? capitalize(d) : d))\n .join('')\n .replace(/([^a-zA-Z0-9]|[\\.])/gm, '') ?? ''\n )\n}\n\nexport function removeExt(d: string) {\n return d.substring(0, d.lastIndexOf('.')) || d\n}\n\nfunction spaces(d: number): string {\n return Array.from({ length: d })\n .map(() => ' ')\n .join('')\n}\n\nexport function multiSortBy<T>(\n arr: T[],\n accessors: ((item: T) => any)[] = [(d) => d],\n): T[] {\n return arr\n .map((d, i) => [d, i] as const)\n .sort(([a, ai], [b, bi]) => {\n for (const accessor of accessors) {\n const ao = accessor(a)\n const bo = accessor(b)\n\n if (typeof ao === 'undefined') {\n if (typeof bo === 'undefined') {\n continue\n }\n return 1\n }\n\n if (ao === bo) {\n continue\n }\n\n return ao > bo ? 1 : -1\n }\n\n return ai - bi\n })\n .map(([d]) => d)\n}\n\nfunction capitalize(s: string) {\n if (typeof s !== 'string') return ''\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nfunction sanitize(s?: string) {\n return replaceBackslash(s?.replace(/\\\\index/gi, ''))\n}\n\nfunction removeUnderscores(s?: string) {\n return s?.replace(/(^_|_$)/, '').replace(/(\\/_|_\\/)/, '/');\n}\n\nfunction replaceBackslash(s?: string) {\n return s?.replace(/\\\\/gi, '/')\n}\n\nexport function hasParentRoute(routes: RouteNode[], routeToCheck: string | undefined): RouteNode | null {\n if (!routeToCheck || routeToCheck === \"/\") {\n return null;\n }\n\n const sortedNodes = multiSortBy(routes, [ \n (d) => d.routePath!.length * -1,\n (d) => d.variableName,\n \n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n for (const route of sortedNodes) {\n if (route.routePath === '/') continue;\n\n if (routeToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routeToCheck) {\n return route;\n }\n }\n const segments = routeToCheck.split(\"/\");\n segments.pop(); // Remove the last segment\n const parentRoute = segments.join(\"/\");\n\n return hasParentRoute(routes, parentRoute);\n}\n"],"names":["latestTask","rootPathId","fileRouteRegex","getRouteNodes","config","routeFilePrefix","routeFileIgnorePrefix","routeNodes","recurse","dir","fullDir","path","resolve","routesDirectory","dirList","fs","readdir","filter","d","startsWith","Promise","all","map","fileName","fullPath","join","relativePath","stat","isDirectory","filePath","filePathNoExt","removeExt","routePath","replaceBackslash","cleanPath","split","variableName","fileToVariable","endsWith","replace","push","first","skipMessage","generator","console","log","taskId","checkLatest","start","Date","now","multiSortBy","length","routeTree","forEach","node","parentRoute","hasParentRoute","parent","trimmedPath","trimPathLeft","isNonPath","isNonLayout","cleanedPath","removeUnderscores","children","buildRouteConfig","nodes","depth","routeCode","readFile","isRoot","escapedRoutePath","replaceAll","replaced","writeFile","route","childConfigs","spaces","Boolean","routeConfigChildrenText","routeImports","sanitize","relative","dirname","generatedRouteTree","includes","routeTypes","routeNode","routeOptions","routeConfig","routeConfigFileContent","prettier","format","semi","parser","routeTreeContent","catch","err","code","undefined","ensureDir","i","capitalize","substring","lastIndexOf","Array","from","arr","accessors","sort","a","ai","b","bi","accessor","ao","bo","s","charAt","toUpperCase","slice","routes","routeToCheck","sortedNodes","segments","pop"],"mappings":"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"}
@@ -17,3 +17,4 @@ export type RouteNode = {
17
17
  export declare function generator(config: Config): Promise<void>;
18
18
  export declare function removeExt(d: string): string;
19
19
  export declare function multiSortBy<T>(arr: T[], accessors?: ((item: T) => any)[]): T[];
20
+ export declare function hasParentRoute(routes: RouteNode[], routeToCheck: string | undefined): RouteNode | null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tanstack/router-cli",
3
3
  "author": "Tanner Linsley",
4
- "version": "0.0.1-beta.190",
4
+ "version": "0.0.1-beta.192",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/router",
7
7
  "homepage": "https://tanstack.com/router",
package/src/generator.ts CHANGED
@@ -175,9 +175,14 @@ export async function generator(config: Config) {
175
175
  }
176
176
 
177
177
  // Ensure that new FileRoute(anything?) is replace with FileRoute(${node.routePath})
178
+ // routePath can contain $ characters, which have special meaning when used in replace
179
+ // so we have to escape it by turning all $ into $$. But since we do it through a replace call
180
+ // we have to double escape it into $$$$. For more information, see
181
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement
182
+ const escapedRoutePath = node.routePath?.replaceAll('$', '$$$$') ?? ''
178
183
  const replaced = routeCode.replace(
179
184
  fileRouteRegex,
180
- `new FileRoute('${node.routePath}')`,
185
+ `new FileRoute('${escapedRoutePath}')`,
181
186
  )
182
187
 
183
188
  if (replaced !== routeCode) {
@@ -226,7 +231,7 @@ export async function generator(config: Config) {
226
231
  parentRoute: typeof ${routeNode.parent?.variableName ?? 'root'}Route
227
232
  }`
228
233
  })
229
- .join('\n')}
234
+ .join('\n')}
230
235
  }
231
236
  }`
232
237
 
@@ -362,12 +367,20 @@ function replaceBackslash(s?: string) {
362
367
  return s?.replace(/\\/gi, '/')
363
368
  }
364
369
 
365
- function hasParentRoute(routes: RouteNode[], routeToCheck: string | undefined): RouteNode | null {
370
+ export function hasParentRoute(routes: RouteNode[], routeToCheck: string | undefined): RouteNode | null {
366
371
  if (!routeToCheck || routeToCheck === "/") {
367
372
  return null;
368
373
  }
369
- for (const route of routes) {
374
+
375
+ const sortedNodes = multiSortBy(routes, [
376
+ (d) => d.routePath!.length * -1,
377
+ (d) => d.variableName,
378
+
379
+ ]).filter((d) => d.routePath !== `/${rootPathId}`)
380
+
381
+ for (const route of sortedNodes) {
370
382
  if (route.routePath === '/') continue;
383
+
371
384
  if (routeToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routeToCheck) {
372
385
  return route;
373
386
  }
@@ -375,5 +388,6 @@ function hasParentRoute(routes: RouteNode[], routeToCheck: string | undefined):
375
388
  const segments = routeToCheck.split("/");
376
389
  segments.pop(); // Remove the last segment
377
390
  const parentRoute = segments.join("/");
391
+
378
392
  return hasParentRoute(routes, parentRoute);
379
393
  }