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

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.
@@ -71,15 +71,15 @@ async function getRouteNodes(config) {
71
71
  } else {
72
72
  const filePath = path__default["default"].join(dir, fileName);
73
73
  const filePathNoExt = removeExt(filePath);
74
- let routePath = routerCore.cleanPath(`/${filePathNoExt.split('.').join('/')}`);
74
+ let routePath = replaceBackslash(routerCore.cleanPath(`/${filePathNoExt.split('.').join('/')}`)) ?? '';
75
75
  const variableName = fileToVariable(routePath);
76
76
 
77
77
  // Remove the index from the route path and
78
78
  // if the route path is empty, use `/'
79
- if (routePath.endsWith('/index')) {
80
- routePath = routePath.replace(/\/index$/, '/');
81
- } else if (routePath === 'index') {
79
+ if (routePath === 'index') {
82
80
  routePath = '/';
81
+ } else if (routePath.endsWith('/index')) {
82
+ routePath = routePath.replace(/\/index$/, '/');
83
83
  }
84
84
  routeNodes.push({
85
85
  filePath,
@@ -123,13 +123,16 @@ async function generator(config) {
123
123
  // Loop over the flat list of routeNodes and
124
124
  // build up a tree based on the routeNodes' routePath
125
125
  routeNodes.forEach(node => {
126
- routeNodes.forEach(existingNode => {
127
- if (node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)
128
- // node.routePath.length > existingNode.routePath!.length
129
- ) {
130
- node.parent = existingNode;
131
- }
132
- });
126
+ // routeNodes.forEach((existingNode) => {
127
+ // if (
128
+ // node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)
129
+ // // node.routePath.length > existingNode.routePath!.length
130
+ // ) {
131
+ // node.parent = existingNode
132
+ // }
133
+ // })
134
+ const parentRoute = hasParentRoute(routeNodes, node.routePath);
135
+ if (parentRoute) node.parent = parentRoute;
133
136
  node.path = node.parent ? node.routePath?.replace(node.parent.routePath, '') || '/' : node.routePath;
134
137
  const trimmedPath = routerCore.trimPathLeft(node.path ?? '');
135
138
  const split = trimmedPath?.split('/') ?? [];
@@ -168,8 +171,8 @@ async function generator(config) {
168
171
  return (await Promise.all(children)).filter(Boolean).join(`,`);
169
172
  }
170
173
  const routeConfigChildrenText = await buildRouteConfig(routeTree);
171
- const routeImports = [`import { route as rootRoute } from './${path__default["default"].relative(path__default["default"].dirname(config.generatedRouteTree), path__default["default"].resolve(config.routesDirectory, rootPathId))}'`, ...multiSortBy(routeNodes, [d => d.routePath?.includes(`/${rootPathId}`) ? -1 : 1, d => d.routePath?.split('/').length, d => d.routePath?.endsWith("index'") ? -1 : 1, d => d]).map(node => {
172
- return `import { route as ${node.variableName}Route } from './${removeExt(path__default["default"].relative(path__default["default"].dirname(config.generatedRouteTree), path__default["default"].resolve(config.routesDirectory, node.filePath)))}'`;
174
+ const routeImports = [`import { route as rootRoute } from './${sanitize(path__default["default"].relative(path__default["default"].dirname(config.generatedRouteTree), path__default["default"].resolve(config.routesDirectory, rootPathId)))}'`, ...multiSortBy(routeNodes, [d => d.routePath?.includes(`/${rootPathId}`) ? -1 : 1, d => d.routePath?.split('/').length, d => d.routePath?.endsWith("index'") ? -1 : 1, d => d]).map(node => {
175
+ return `import { route as ${node.variableName}Route } from './${sanitize(removeExt(path__default["default"].relative(path__default["default"].dirname(config.generatedRouteTree), path__default["default"].resolve(config.routesDirectory, node.filePath))))}'`;
173
176
  })].join('\n');
174
177
  const routeTypes = `declare module '@tanstack/react-router' {
175
178
  interface FileRoutesByPath {
@@ -252,9 +255,30 @@ function capitalize(s) {
252
255
  if (typeof s !== 'string') return '';
253
256
  return s.charAt(0).toUpperCase() + s.slice(1);
254
257
  }
258
+ function sanitize(s) {
259
+ return replaceBackslash(s?.replace(/\\index/gi, ''));
260
+ }
255
261
  function removeUnderscores(s) {
256
262
  return s?.replace(/(^_|_$)/, '').replace(/(\/_|_\/)/, '/');
257
263
  }
264
+ function replaceBackslash(s) {
265
+ return s?.replace(/\\/gi, '/');
266
+ }
267
+ function hasParentRoute(routes, routeToCheck) {
268
+ if (!routeToCheck || routeToCheck === "/") {
269
+ return null;
270
+ }
271
+ for (const route of routes) {
272
+ if (route.routePath === '/') continue;
273
+ if (routeToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routeToCheck) {
274
+ return route;
275
+ }
276
+ }
277
+ const segments = routeToCheck.split("/");
278
+ segments.pop(); // Remove the last segment
279
+ const parentRoute = segments.join("/");
280
+ return hasParentRoute(routes, parentRoute);
281
+ }
258
282
 
259
283
  exports.fileRouteRegex = fileRouteRegex;
260
284
  exports.generator = generator;
@@ -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 = 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.endsWith('/index')) {\n routePath = routePath.replace(/\\/index$/, '/')\n } else if (routePath === 'index') {\n routePath = '/'\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\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 './${path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, rootPathId),\n )}'`,\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 './${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: () => ${\n 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 removeUnderscores(s?: string) {\n return s?.replace(/(^_|_$)/, '').replace(/(\\/_|_\\/)/, '/')\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","cleanPath","split","variableName","fileToVariable","endsWith","replace","push","first","skipMessage","generator","console","log","taskId","checkLatest","start","Date","now","multiSortBy","length","routeTree","forEach","node","existingNode","parent","trimmedPath","trimPathLeft","isNonPath","isNonLayout","cleanedPath","removeUnderscores","children","buildRouteConfig","nodes","depth","routeCode","readFile","isRoot","replaced","writeFile","route","childConfigs","spaces","Boolean","routeConfigChildrenText","routeImports","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"],"mappings":"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"}
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":"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"}
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.189",
4
+ "version": "0.0.1-beta.190",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/router",
7
7
  "homepage": "https://tanstack.com/router",
package/src/generator.ts CHANGED
@@ -57,15 +57,15 @@ async function getRouteNodes(config: Config) {
57
57
  } else {
58
58
  const filePath = path.join(dir, fileName)
59
59
  const filePathNoExt = removeExt(filePath)
60
- let routePath = cleanPath(`/${filePathNoExt.split('.').join('/')}`)
60
+ let routePath = replaceBackslash(cleanPath(`/${filePathNoExt.split('.').join('/')}`)) ?? ''
61
61
  const variableName = fileToVariable(routePath)
62
62
 
63
63
  // Remove the index from the route path and
64
64
  // if the route path is empty, use `/'
65
- if (routePath.endsWith('/index')) {
66
- routePath = routePath.replace(/\/index$/, '/')
67
- } else if (routePath === 'index') {
65
+ if (routePath === 'index') {
68
66
  routePath = '/'
67
+ } else if (routePath.endsWith('/index')) {
68
+ routePath = routePath.replace(/\/index$/, '/')
69
69
  }
70
70
 
71
71
  routeNodes.push({
@@ -129,14 +129,16 @@ export async function generator(config: Config) {
129
129
  // Loop over the flat list of routeNodes and
130
130
  // build up a tree based on the routeNodes' routePath
131
131
  routeNodes.forEach((node) => {
132
- routeNodes.forEach((existingNode) => {
133
- if (
134
- node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)
135
- // node.routePath.length > existingNode.routePath!.length
136
- ) {
137
- node.parent = existingNode
138
- }
139
- })
132
+ // routeNodes.forEach((existingNode) => {
133
+ // if (
134
+ // node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)
135
+ // // node.routePath.length > existingNode.routePath!.length
136
+ // ) {
137
+ // node.parent = existingNode
138
+ // }
139
+ // })
140
+ const parentRoute = hasParentRoute(routeNodes, node.routePath)
141
+ if (parentRoute) node.parent = parentRoute
140
142
 
141
143
  node.path = node.parent
142
144
  ? node.routePath?.replace(node.parent.routePath!, '') || '/'
@@ -198,22 +200,21 @@ export async function generator(config: Config) {
198
200
  const routeConfigChildrenText = await buildRouteConfig(routeTree)
199
201
 
200
202
  const routeImports = [
201
- `import { route as rootRoute } from './${path.relative(
203
+ `import { route as rootRoute } from './${sanitize(path.relative(
202
204
  path.dirname(config.generatedRouteTree),
203
- path.resolve(config.routesDirectory, rootPathId),
204
- )}'`,
205
+ path.resolve(config.routesDirectory, rootPathId)))}'`,
205
206
  ...multiSortBy(routeNodes, [
206
207
  (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),
207
208
  (d) => d.routePath?.split('/').length,
208
209
  (d) => (d.routePath?.endsWith("index'") ? -1 : 1),
209
210
  (d) => d,
210
211
  ]).map((node) => {
211
- return `import { route as ${node.variableName}Route } from './${removeExt(
212
+ return `import { route as ${node.variableName}Route } from './${sanitize(removeExt(
212
213
  path.relative(
213
214
  path.dirname(config.generatedRouteTree),
214
215
  path.resolve(config.routesDirectory, node.filePath),
215
216
  ),
216
- )}'`
217
+ ))}'`
217
218
  }),
218
219
  ].join('\n')
219
220
 
@@ -236,8 +237,7 @@ export async function generator(config: Config) {
236
237
  routeNode.isNonPath
237
238
  ? `id: '${routeNode.cleanedPath}'`
238
239
  : `path: '${routeNode.cleanedPath}'`,
239
- `getParentRoute: () => ${
240
- routeNode.parent?.variableName ?? 'root'
240
+ `getParentRoute: () => ${routeNode.parent?.variableName ?? 'root'
241
241
  }Route`,
242
242
  // `\n// ${JSON.stringify(
243
243
  // {
@@ -350,6 +350,30 @@ function capitalize(s: string) {
350
350
  return s.charAt(0).toUpperCase() + s.slice(1)
351
351
  }
352
352
 
353
+ function sanitize(s?: string) {
354
+ return replaceBackslash(s?.replace(/\\index/gi, ''))
355
+ }
356
+
353
357
  function removeUnderscores(s?: string) {
354
- return s?.replace(/(^_|_$)/, '').replace(/(\/_|_\/)/, '/')
358
+ return s?.replace(/(^_|_$)/, '').replace(/(\/_|_\/)/, '/');
359
+ }
360
+
361
+ function replaceBackslash(s?: string) {
362
+ return s?.replace(/\\/gi, '/')
363
+ }
364
+
365
+ function hasParentRoute(routes: RouteNode[], routeToCheck: string | undefined): RouteNode | null {
366
+ if (!routeToCheck || routeToCheck === "/") {
367
+ return null;
368
+ }
369
+ for (const route of routes) {
370
+ if (route.routePath === '/') continue;
371
+ if (routeToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routeToCheck) {
372
+ return route;
373
+ }
374
+ }
375
+ const segments = routeToCheck.split("/");
376
+ segments.pop(); // Remove the last segment
377
+ const parentRoute = segments.join("/");
378
+ return hasParentRoute(routes, parentRoute);
355
379
  }