@tanstack/router-generator 1.133.20 → 1.133.27
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.
- package/dist/cjs/config.cjs +3 -1
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/config.d.cts +11 -6
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs +9 -2
- package/dist/cjs/filesystem/physical/getRouteNodes.cjs.map +1 -1
- package/dist/cjs/filesystem/physical/getRouteNodes.d.cts +1 -1
- package/dist/cjs/generator.cjs +24 -12
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/types.d.cts +2 -0
- package/dist/cjs/utils.cjs +112 -16
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +20 -6
- package/dist/esm/config.d.ts +11 -6
- package/dist/esm/config.js +3 -1
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/filesystem/physical/getRouteNodes.d.ts +1 -1
- package/dist/esm/filesystem/physical/getRouteNodes.js +9 -2
- package/dist/esm/filesystem/physical/getRouteNodes.js.map +1 -1
- package/dist/esm/generator.js +25 -13
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/types.d.ts +2 -0
- package/dist/esm/utils.d.ts +20 -6
- package/dist/esm/utils.js +112 -16
- package/dist/esm/utils.js.map +1 -1
- package/package.json +4 -4
- package/src/config.ts +2 -0
- package/src/filesystem/physical/getRouteNodes.ts +10 -1
- package/src/generator.ts +32 -9
- package/src/types.ts +2 -0
- package/src/utils.ts +205 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.cjs","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport { existsSync, mkdirSync } from 'node:fs'\nimport crypto from 'node:crypto'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { logging } from './logger'\nimport {\n isVirtualConfigFile,\n getRouteNodes as physicalGetRouteNodes,\n} from './filesystem/physical/getRouteNodes'\nimport { getRouteNodes as virtualGetRouteNodes } from './filesystem/virtual/getRouteNodes'\nimport { rootPathId } from './filesystem/physical/rootPathId'\nimport {\n buildFileRoutesByPathInterface,\n buildImportString,\n buildRouteTreeConfig,\n checkFileExists,\n checkRouteFullPathUniqueness,\n createRouteNodesByFullPath,\n createRouteNodesById,\n createRouteNodesByTo,\n determineNodePath,\n findParent,\n format,\n getImportForRouteNode,\n getImportPath,\n getResolvedRouteNodeVariableName,\n hasParentRoute,\n isRouteNodeValidForAugmentation,\n mergeImportDeclarations,\n multiSortBy,\n removeExt,\n removeGroups,\n removeLastSegmentFromPath,\n removeLayoutSegments,\n removeTrailingSlash,\n removeUnderscores,\n replaceBackslash,\n resetRegex,\n routePathToVariable,\n trimPathLeft,\n} from './utils'\nimport { fillTemplate, getTargetTemplate } from './template'\nimport { transform } from './transform/transform'\nimport type { GeneratorPlugin } from './plugin/types'\nimport type { TargetTemplate } from './template'\nimport type {\n FsRouteType,\n GetRouteNodesResult,\n GetRoutesByFileMapResult,\n HandleNodeAccumulator,\n ImportDeclaration,\n RouteNode,\n} from './types'\nimport type { Config } from './config'\nimport type { Logger } from './logger'\n\ninterface fs {\n stat: (\n filePath: string,\n ) => Promise<{ mtimeMs: bigint; mode: number; uid: number; gid: number }>\n rename: (oldPath: string, newPath: string) => Promise<void>\n writeFile: (filePath: string, content: string) => Promise<void>\n readFile: (\n filePath: string,\n ) => Promise<\n { stat: { mtimeMs: bigint }; fileContent: string } | 'file-not-existing'\n >\n chmod: (filePath: string, mode: number) => Promise<void>\n chown: (filePath: string, uid: number, gid: number) => Promise<void>\n}\n\nconst DefaultFileSystem: fs = {\n stat: async (filePath) => {\n const res = await fsp.stat(filePath, { bigint: true })\n return {\n mtimeMs: res.mtimeMs,\n mode: Number(res.mode),\n uid: Number(res.uid),\n gid: Number(res.gid),\n }\n },\n rename: (oldPath, newPath) => fsp.rename(oldPath, newPath),\n writeFile: (filePath, content) => fsp.writeFile(filePath, content),\n readFile: async (filePath: string) => {\n try {\n const fileHandle = await fsp.open(filePath, 'r')\n const stat = await fileHandle.stat({ bigint: true })\n const fileContent = (await fileHandle.readFile()).toString()\n await fileHandle.close()\n return { stat, fileContent }\n } catch (e: any) {\n if ('code' in e) {\n if (e.code === 'ENOENT') {\n return 'file-not-existing'\n }\n }\n throw e\n }\n },\n chmod: (filePath, mode) => fsp.chmod(filePath, mode),\n chown: (filePath, uid, gid) => fsp.chown(filePath, uid, gid),\n}\n\ninterface Rerun {\n rerun: true\n msg?: string\n event: GeneratorEvent\n}\nfunction rerun(opts: { msg?: string; event?: GeneratorEvent }): Rerun {\n const { event, ...rest } = opts\n return { rerun: true, event: event ?? { type: 'rerun' }, ...rest }\n}\n\nfunction isRerun(result: unknown): result is Rerun {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'rerun' in result &&\n result.rerun === true\n )\n}\n\nexport type FileEventType = 'create' | 'update' | 'delete'\nexport type FileEvent = {\n type: FileEventType\n path: string\n}\nexport type GeneratorEvent = FileEvent | { type: 'rerun' }\n\ntype FileCacheChange<TCacheEntry extends GeneratorCacheEntry> =\n | {\n result: false\n cacheEntry: TCacheEntry\n }\n | { result: true; mtimeMs: bigint; cacheEntry: TCacheEntry }\n | {\n result: 'file-not-in-cache'\n }\n | {\n result: 'cannot-stat-file'\n }\n\ninterface GeneratorCacheEntry {\n mtimeMs: bigint\n fileContent: string\n}\n\ninterface RouteNodeCacheEntry extends GeneratorCacheEntry {\n routeId: string\n node: RouteNode\n}\n\ntype GeneratorRouteNodeCache = Map</** filePath **/ string, RouteNodeCacheEntry>\n\ninterface CrawlingResult {\n rootRouteNode: RouteNode\n routeFileResult: Array<RouteNode>\n acc: HandleNodeAccumulator\n}\n\nexport class Generator {\n /**\n * why do we have two caches for the route files?\n * During processing, we READ from the cache and WRITE to the shadow cache.\n *\n * After a route file is processed, we write to the shadow cache.\n * If during processing we bail out and re-run, we don't lose this modification\n * but still can track whether the file contributed changes and thus the route tree file needs to be regenerated.\n * After all files are processed, we swap the shadow cache with the main cache and initialize a new shadow cache.\n * That way we also ensure deleted/renamed files don't stay in the cache forever.\n */\n private routeNodeCache: GeneratorRouteNodeCache = new Map()\n private routeNodeShadowCache: GeneratorRouteNodeCache = new Map()\n\n private routeTreeFileCache: GeneratorCacheEntry | undefined\n\n private crawlingResult: CrawlingResult | undefined\n public config: Config\n public targetTemplate: TargetTemplate\n\n private root: string\n private routesDirectoryPath: string\n private sessionId?: string\n private fs: fs\n private logger: Logger\n private generatedRouteTreePath: string\n private runPromise: Promise<void> | undefined\n private fileEventQueue: Array<GeneratorEvent> = []\n private plugins: Array<GeneratorPlugin> = []\n private static routeGroupPatternRegex = /\\(.+\\)/g\n private physicalDirectories: Array<string> = []\n\n constructor(opts: { config: Config; root: string; fs?: fs }) {\n this.config = opts.config\n this.logger = logging({ disabled: this.config.disableLogging })\n this.root = opts.root\n this.fs = opts.fs || DefaultFileSystem\n this.generatedRouteTreePath = this.getGeneratedRouteTreePath()\n this.targetTemplate = getTargetTemplate(this.config)\n\n this.routesDirectoryPath = this.getRoutesDirectoryPath()\n this.plugins.push(...(opts.config.plugins || []))\n\n for (const plugin of this.plugins) {\n plugin.init?.({ generator: this })\n }\n }\n\n private getGeneratedRouteTreePath() {\n const generatedRouteTreePath = path.isAbsolute(\n this.config.generatedRouteTree,\n )\n ? this.config.generatedRouteTree\n : path.resolve(this.root, this.config.generatedRouteTree)\n\n const generatedRouteTreeDir = path.dirname(generatedRouteTreePath)\n\n if (!existsSync(generatedRouteTreeDir)) {\n mkdirSync(generatedRouteTreeDir, { recursive: true })\n }\n\n return generatedRouteTreePath\n }\n\n private getRoutesDirectoryPath() {\n return path.isAbsolute(this.config.routesDirectory)\n ? this.config.routesDirectory\n : path.resolve(this.root, this.config.routesDirectory)\n }\n\n public getRoutesByFileMap(): GetRoutesByFileMapResult {\n return new Map(\n [...this.routeNodeCache.entries()].map(([filePath, cacheEntry]) => [\n filePath,\n { routePath: cacheEntry.routeId },\n ]),\n )\n }\n\n public async run(event?: GeneratorEvent): Promise<void> {\n if (\n event &&\n event.type !== 'rerun' &&\n !this.isFileRelevantForRouteTreeGeneration(event.path)\n ) {\n return\n }\n this.fileEventQueue.push(event ?? { type: 'rerun' })\n // only allow a single run at a time\n if (this.runPromise) {\n return this.runPromise\n }\n\n this.runPromise = (async () => {\n do {\n // synchronously copy and clear the queue since we are going to iterate asynchronously over it\n // and while we do so, a new event could be put into the queue\n const tempQueue = this.fileEventQueue\n this.fileEventQueue = []\n // if we only have 'update' events in the queue\n // and we already have the affected files' latest state in our cache, we can exit early\n const remainingEvents = (\n await Promise.all(\n tempQueue.map(async (e) => {\n if (e.type === 'update') {\n let cacheEntry: GeneratorCacheEntry | undefined\n if (e.path === this.generatedRouteTreePath) {\n cacheEntry = this.routeTreeFileCache\n } else {\n // we only check the routeNodeCache here\n // if the file's state is only up-to-date in the shadow cache we need to re-run\n cacheEntry = this.routeNodeCache.get(e.path)\n }\n const change = await this.didFileChangeComparedToCache(\n { path: e.path },\n cacheEntry,\n )\n if (change.result === false) {\n return null\n }\n }\n return e\n }),\n )\n ).filter((e) => e !== null)\n\n if (remainingEvents.length === 0) {\n break\n }\n\n try {\n await this.generatorInternal()\n } catch (err) {\n const errArray = !Array.isArray(err) ? [err] : err\n\n const recoverableErrors = errArray.filter((e) => isRerun(e))\n if (recoverableErrors.length === errArray.length) {\n this.fileEventQueue.push(...recoverableErrors.map((e) => e.event))\n recoverableErrors.forEach((e) => {\n if (e.msg) {\n this.logger.info(e.msg)\n }\n })\n } else {\n const unrecoverableErrors = errArray.filter((e) => !isRerun(e))\n this.runPromise = undefined\n throw new Error(\n unrecoverableErrors.map((e) => (e as Error).message).join(),\n )\n }\n }\n } while (this.fileEventQueue.length)\n this.runPromise = undefined\n })()\n return this.runPromise\n }\n\n private async generatorInternal() {\n let writeRouteTreeFile: boolean | 'force' = false\n\n let getRouteNodesResult: GetRouteNodesResult\n\n if (this.config.virtualRouteConfig) {\n getRouteNodesResult = await virtualGetRouteNodes(this.config, this.root)\n } else {\n getRouteNodesResult = await physicalGetRouteNodes(this.config, this.root)\n }\n\n const {\n rootRouteNode,\n routeNodes: beforeRouteNodes,\n physicalDirectories,\n } = getRouteNodesResult\n if (rootRouteNode === undefined) {\n let errorMessage = `rootRouteNode must not be undefined. Make sure you've added your root route into the route-tree.`\n if (!this.config.virtualRouteConfig) {\n errorMessage += `\\nMake sure that you add a \"${rootPathId}.${this.config.disableTypes ? 'js' : 'tsx'}\" file to your routes directory.\\nAdd the file in: \"${this.config.routesDirectory}/${rootPathId}.${this.config.disableTypes ? 'js' : 'tsx'}\"`\n }\n throw new Error(errorMessage)\n }\n this.physicalDirectories = physicalDirectories\n\n await this.handleRootNode(rootRouteNode)\n\n const preRouteNodes = multiSortBy(beforeRouteNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) =>\n d.filePath.match(new RegExp(`[./]${this.config.indexToken}[.]`))\n ? 1\n : -1,\n (d) =>\n d.filePath.match(\n /[./](component|errorComponent|pendingComponent|loader|lazy)[.]/,\n )\n ? 1\n : -1,\n (d) =>\n d.filePath.match(new RegExp(`[./]${this.config.routeToken}[.]`))\n ? -1\n : 1,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => ![`/${rootPathId}`].includes(d.routePath || ''))\n\n const routeFileAllResult = await Promise.allSettled(\n preRouteNodes\n // only process routes that are backed by an actual file\n .filter((n) => !n.isVirtualParentRoute && !n.isVirtual)\n .map((n) => this.processRouteNodeFile(n)),\n )\n\n const rejections = routeFileAllResult.filter(\n (result) => result.status === 'rejected',\n )\n if (rejections.length > 0) {\n throw rejections.map((e) => e.reason)\n }\n\n const routeFileResult = routeFileAllResult.flatMap((result) => {\n if (result.status === 'fulfilled' && result.value !== null) {\n if (result.value.shouldWriteTree) {\n writeRouteTreeFile = true\n }\n return result.value.node\n }\n return []\n })\n\n // reset children in case we re-use a node from the cache\n routeFileResult.forEach((r) => (r.children = undefined))\n\n const acc: HandleNodeAccumulator = {\n routeTree: [],\n routeNodes: [],\n routePiecesByPath: {},\n }\n\n for (const node of routeFileResult) {\n Generator.handleNode(node, acc)\n }\n\n this.crawlingResult = { rootRouteNode, routeFileResult, acc }\n\n // this is the first time the generator runs, so read in the route tree file if it exists yet\n if (!this.routeTreeFileCache) {\n const routeTreeFile = await this.fs.readFile(this.generatedRouteTreePath)\n if (routeTreeFile !== 'file-not-existing') {\n this.routeTreeFileCache = {\n fileContent: routeTreeFile.fileContent,\n mtimeMs: routeTreeFile.stat.mtimeMs,\n }\n }\n writeRouteTreeFile = true\n } else {\n const routeTreeFileChange = await this.didFileChangeComparedToCache(\n { path: this.generatedRouteTreePath },\n this.routeTreeFileCache,\n )\n if (routeTreeFileChange.result !== false) {\n writeRouteTreeFile = 'force'\n if (routeTreeFileChange.result === true) {\n const routeTreeFile = await this.fs.readFile(\n this.generatedRouteTreePath,\n )\n if (routeTreeFile !== 'file-not-existing') {\n this.routeTreeFileCache = {\n fileContent: routeTreeFile.fileContent,\n mtimeMs: routeTreeFile.stat.mtimeMs,\n }\n }\n }\n }\n }\n\n if (!writeRouteTreeFile) {\n // only needs to be done if no other changes have been detected yet\n // compare shadowCache and cache to identify deleted routes\n if (this.routeNodeCache.size !== this.routeNodeShadowCache.size) {\n writeRouteTreeFile = true\n } else {\n for (const fullPath of this.routeNodeCache.keys()) {\n if (!this.routeNodeShadowCache.has(fullPath)) {\n writeRouteTreeFile = true\n break\n }\n }\n }\n }\n\n if (!writeRouteTreeFile) {\n this.swapCaches()\n return\n }\n\n const buildResult = this.buildRouteTree({\n rootRouteNode,\n acc,\n routeFileResult,\n })\n let routeTreeContent = buildResult.routeTreeContent\n\n routeTreeContent = this.config.enableRouteTreeFormatting\n ? await format(routeTreeContent, this.config)\n : routeTreeContent\n\n let newMtimeMs: bigint | undefined\n if (this.routeTreeFileCache) {\n if (\n writeRouteTreeFile !== 'force' &&\n this.routeTreeFileCache.fileContent === routeTreeContent\n ) {\n // existing route tree file is already up-to-date, don't write it\n // we should only get here in the initial run when the route cache is not filled yet\n } else {\n const newRouteTreeFileStat = await this.safeFileWrite({\n filePath: this.generatedRouteTreePath,\n newContent: routeTreeContent,\n strategy: {\n type: 'mtime',\n expectedMtimeMs: this.routeTreeFileCache.mtimeMs,\n },\n })\n newMtimeMs = newRouteTreeFileStat.mtimeMs\n }\n } else {\n const newRouteTreeFileStat = await this.safeFileWrite({\n filePath: this.generatedRouteTreePath,\n newContent: routeTreeContent,\n strategy: {\n type: 'new-file',\n },\n })\n newMtimeMs = newRouteTreeFileStat.mtimeMs\n }\n\n if (newMtimeMs !== undefined) {\n this.routeTreeFileCache = {\n fileContent: routeTreeContent,\n mtimeMs: newMtimeMs,\n }\n }\n\n this.plugins.map((plugin) => {\n return plugin.onRouteTreeChanged?.({\n routeTree: buildResult.routeTree,\n routeNodes: buildResult.routeNodes,\n acc,\n rootRouteNode,\n })\n })\n this.swapCaches()\n }\n\n private swapCaches() {\n this.routeNodeCache = this.routeNodeShadowCache\n this.routeNodeShadowCache = new Map()\n }\n\n public buildRouteTree(opts: {\n rootRouteNode: RouteNode\n acc: HandleNodeAccumulator\n routeFileResult: Array<RouteNode>\n config?: Partial<Config>\n }) {\n const config = { ...this.config, ...(opts.config || {}) }\n\n const { rootRouteNode, acc } = opts\n\n const sortedRouteNodes = multiSortBy(acc.routeNodes, [\n (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(config.indexToken) ? -1 : 1),\n (d) => d,\n ])\n\n const routeImports = sortedRouteNodes\n .filter((d) => !d.isVirtual)\n .flatMap((node) =>\n getImportForRouteNode(\n node,\n config,\n this.generatedRouteTreePath,\n this.root,\n ),\n )\n\n const virtualRouteNodes = sortedRouteNodes\n .filter((d) => d.isVirtual)\n .map((node) => {\n return `const ${\n node.variableName\n }RouteImport = createFileRoute('${node.routePath}')()`\n })\n\n const imports: Array<ImportDeclaration> = []\n if (acc.routeNodes.some((n) => n.isVirtual)) {\n imports.push({\n specifiers: [{ imported: 'createFileRoute' }],\n source: this.targetTemplate.fullPkg,\n })\n }\n if (config.verboseFileRoutes === false) {\n const typeImport: ImportDeclaration = {\n specifiers: [],\n source: this.targetTemplate.fullPkg,\n importKind: 'type',\n }\n if (\n sortedRouteNodes.some(\n (d) =>\n isRouteNodeValidForAugmentation(d) && d._fsRouteType !== 'lazy',\n )\n ) {\n typeImport.specifiers.push({ imported: 'CreateFileRoute' })\n }\n if (\n sortedRouteNodes.some(\n (node) =>\n acc.routePiecesByPath[node.routePath!]?.lazy &&\n isRouteNodeValidForAugmentation(node),\n )\n ) {\n typeImport.specifiers.push({ imported: 'CreateLazyFileRoute' })\n }\n\n if (typeImport.specifiers.length > 0) {\n typeImport.specifiers.push({ imported: 'FileRoutesByPath' })\n imports.push(typeImport)\n }\n }\n\n const routeTreeConfig = buildRouteTreeConfig(\n acc.routeTree,\n config.disableTypes,\n )\n\n const createUpdateRoutes = sortedRouteNodes.map((node) => {\n const loaderNode = acc.routePiecesByPath[node.routePath!]?.loader\n const componentNode = acc.routePiecesByPath[node.routePath!]?.component\n const errorComponentNode =\n acc.routePiecesByPath[node.routePath!]?.errorComponent\n const pendingComponentNode =\n acc.routePiecesByPath[node.routePath!]?.pendingComponent\n const lazyComponentNode = acc.routePiecesByPath[node.routePath!]?.lazy\n\n return [\n [\n `const ${node.variableName}Route = ${node.variableName}RouteImport.update({\n ${[\n `id: '${node.path}'`,\n !node.isNonPath ? `path: '${node.cleanedPath}'` : undefined,\n `getParentRoute: () => ${findParent(node)}`,\n ]\n .filter(Boolean)\n .join(',')}\n }${config.disableTypes ? '' : 'as any'})`,\n loaderNode\n ? `.updateLoader({ loader: lazyFn(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, loaderNode.filePath),\n ),\n config.addExtensions,\n ),\n )}'), 'loader') })`\n : '',\n componentNode || errorComponentNode || pendingComponentNode\n ? `.update({\n ${(\n [\n ['component', componentNode],\n ['errorComponent', errorComponentNode],\n ['pendingComponent', pendingComponentNode],\n ] as const\n )\n .filter((d) => d[1])\n .map((d) => {\n return `${\n d[0]\n }: lazyRouteComponent(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, d[1]!.filePath),\n ),\n config.addExtensions,\n ),\n )}'), '${d[0]}')`\n })\n .join('\\n,')}\n })`\n : '',\n lazyComponentNode\n ? `.lazy(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(\n config.routesDirectory,\n lazyComponentNode.filePath,\n ),\n ),\n config.addExtensions,\n ),\n )}').then((d) => d.Route))`\n : '',\n ].join(''),\n ].join('\\n\\n')\n })\n\n let fileRoutesByPathInterface = ''\n let fileRoutesByFullPath = ''\n\n if (!config.disableTypes) {\n fileRoutesByFullPath = [\n `export interface FileRoutesByFullPath {\n${[...createRouteNodesByFullPath(acc.routeNodes).entries()]\n .filter(([fullPath]) => fullPath)\n .map(([fullPath, routeNode]) => {\n return `'${fullPath}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRoutesByTo {\n${[...createRouteNodesByTo(acc.routeNodes).entries()]\n .filter(([to]) => to)\n .map(([to, routeNode]) => {\n return `'${to}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRoutesById {\n'${rootRouteId}': typeof rootRouteImport,\n${[...createRouteNodesById(acc.routeNodes).entries()].map(([id, routeNode]) => {\n return `'${id}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n})}\n}`,\n `export interface FileRouteTypes {\nfileRoutesByFullPath: FileRoutesByFullPath\nfullPaths: ${\n acc.routeNodes.length > 0\n ? [...createRouteNodesByFullPath(acc.routeNodes).keys()]\n .filter((fullPath) => fullPath)\n .map((fullPath) => `'${fullPath}'`)\n .join('|')\n : 'never'\n }\nfileRoutesByTo: FileRoutesByTo\nto: ${\n acc.routeNodes.length > 0\n ? [...createRouteNodesByTo(acc.routeNodes).keys()]\n .filter((to) => to)\n .map((to) => `'${to}'`)\n .join('|')\n : 'never'\n }\nid: ${[`'${rootRouteId}'`, ...[...createRouteNodesById(acc.routeNodes).keys()].map((id) => `'${id}'`)].join('|')}\nfileRoutesById: FileRoutesById\n}`,\n `export interface RootRouteChildren {\n${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n ].join('\\n')\n\n fileRoutesByPathInterface = buildFileRoutesByPathInterface({\n module: this.targetTemplate.fullPkg,\n interfaceName: 'FileRoutesByPath',\n routeNodes: sortedRouteNodes,\n })\n }\n\n const routeTree = [\n `const rootRouteChildren${config.disableTypes ? '' : `: RootRouteChildren`} = {\n ${acc.routeTree\n .map(\n (child) =>\n `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`,\n )\n .join(',')}\n}`,\n `export const routeTree = rootRouteImport._addFileChildren(rootRouteChildren)${config.disableTypes ? '' : `._addFileTypes<FileRouteTypes>()`}`,\n ].join('\\n')\n\n checkRouteFullPathUniqueness(\n sortedRouteNodes.filter(\n (d) => d.children === undefined && 'lazy' !== d._fsRouteType,\n ),\n config,\n )\n\n let mergedImports = mergeImportDeclarations(imports)\n if (config.disableTypes) {\n mergedImports = mergedImports.filter((d) => d.importKind !== 'type')\n }\n\n const importStatements = mergedImports.map(buildImportString)\n\n let moduleAugmentation = ''\n if (config.verboseFileRoutes === false && !config.disableTypes) {\n moduleAugmentation = opts.routeFileResult\n .map((node) => {\n const getModuleDeclaration = (routeNode?: RouteNode) => {\n if (!isRouteNodeValidForAugmentation(routeNode)) {\n return ''\n }\n let moduleAugmentation = ''\n if (routeNode._fsRouteType === 'lazy') {\n moduleAugmentation = `const createLazyFileRoute: CreateLazyFileRoute<FileRoutesByPath['${routeNode.routePath}']['preLoaderRoute']>`\n } else {\n moduleAugmentation = `const createFileRoute: CreateFileRoute<'${routeNode.routePath}',\n FileRoutesByPath['${routeNode.routePath}']['parentRoute'],\n FileRoutesByPath['${routeNode.routePath}']['id'],\n FileRoutesByPath['${routeNode.routePath}']['path'],\n FileRoutesByPath['${routeNode.routePath}']['fullPath']\n >\n `\n }\n\n return `declare module './${getImportPath(routeNode, config, this.generatedRouteTreePath)}' {\n ${moduleAugmentation}\n }`\n }\n return getModuleDeclaration(node)\n })\n .join('\\n')\n }\n\n const rootRouteImport = getImportForRouteNode(\n rootRouteNode,\n config,\n this.generatedRouteTreePath,\n this.root,\n )\n routeImports.unshift(rootRouteImport)\n\n let footer: Array<string> = []\n if (config.routeTreeFileFooter) {\n if (Array.isArray(config.routeTreeFileFooter)) {\n footer = config.routeTreeFileFooter\n } else {\n footer = config.routeTreeFileFooter()\n }\n }\n const routeTreeContent = [\n ...config.routeTreeFileHeader,\n `// This file was automatically generated by TanStack Router.\n// You should NOT make any changes in this file as it will be overwritten.\n// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.`,\n [...importStatements].join('\\n'),\n mergeImportDeclarations(routeImports).map(buildImportString).join('\\n'),\n virtualRouteNodes.join('\\n'),\n createUpdateRoutes.join('\\n'),\n fileRoutesByFullPath,\n fileRoutesByPathInterface,\n moduleAugmentation,\n routeTreeConfig.join('\\n'),\n routeTree,\n ...footer,\n ]\n .filter(Boolean)\n .join('\\n\\n')\n return {\n routeTreeContent,\n routeTree: acc.routeTree,\n routeNodes: acc.routeNodes,\n }\n }\n\n private async processRouteNodeFile(node: RouteNode): Promise<{\n shouldWriteTree: boolean\n cacheEntry: RouteNodeCacheEntry\n node: RouteNode\n } | null> {\n const result = await this.isRouteFileCacheFresh(node)\n\n if (result.status === 'fresh') {\n return {\n node: result.cacheEntry.node,\n shouldWriteTree: false,\n cacheEntry: result.cacheEntry,\n }\n }\n\n const previousCacheEntry = result.cacheEntry\n\n const existingRouteFile = await this.fs.readFile(node.fullPath)\n if (existingRouteFile === 'file-not-existing') {\n throw new Error(`⚠️ File ${node.fullPath} does not exist`)\n }\n\n const updatedCacheEntry: RouteNodeCacheEntry = {\n fileContent: existingRouteFile.fileContent,\n mtimeMs: existingRouteFile.stat.mtimeMs,\n routeId: node.routePath ?? '$$TSR_NO_ROUTE_PATH_ASSIGNED$$',\n node,\n }\n\n const escapedRoutePath = node.routePath?.replaceAll('$', '$$') ?? ''\n\n let shouldWriteRouteFile = false\n let shouldWriteTree = false\n // now we need to either scaffold the file or transform it\n if (!existingRouteFile.fileContent) {\n shouldWriteRouteFile = true\n shouldWriteTree = true\n // Creating a new lazy route file\n if (node._fsRouteType === 'lazy') {\n const tLazyRouteTemplate = this.targetTemplate.lazyRoute\n // Check by default check if the user has a specific lazy route template\n // If not, check if the user has a route template and use that instead\n updatedCacheEntry.fileContent = await fillTemplate(\n this.config,\n (this.config.customScaffolding?.lazyRouteTemplate ||\n this.config.customScaffolding?.routeTemplate) ??\n tLazyRouteTemplate.template(),\n {\n tsrImports: tLazyRouteTemplate.imports.tsrImports(),\n tsrPath: escapedRoutePath.replaceAll(/\\{(.+?)\\}/gm, '$1'),\n tsrExportStart:\n tLazyRouteTemplate.imports.tsrExportStart(escapedRoutePath),\n tsrExportEnd: tLazyRouteTemplate.imports.tsrExportEnd(),\n },\n )\n } else if (\n // Creating a new normal route file\n (['layout', 'static'] satisfies Array<FsRouteType>).some(\n (d) => d === node._fsRouteType,\n ) ||\n (\n [\n 'component',\n 'pendingComponent',\n 'errorComponent',\n 'loader',\n ] satisfies Array<FsRouteType>\n ).every((d) => d !== node._fsRouteType)\n ) {\n const tRouteTemplate = this.targetTemplate.route\n updatedCacheEntry.fileContent = await fillTemplate(\n this.config,\n this.config.customScaffolding?.routeTemplate ??\n tRouteTemplate.template(),\n {\n tsrImports: tRouteTemplate.imports.tsrImports(),\n tsrPath: escapedRoutePath.replaceAll(/\\{(.+?)\\}/gm, '$1'),\n tsrExportStart:\n tRouteTemplate.imports.tsrExportStart(escapedRoutePath),\n tsrExportEnd: tRouteTemplate.imports.tsrExportEnd(),\n },\n )\n } else {\n return null\n }\n }\n // transform the file\n const transformResult = await transform({\n source: updatedCacheEntry.fileContent,\n ctx: {\n target: this.config.target,\n routeId: escapedRoutePath,\n lazy: node._fsRouteType === 'lazy',\n verboseFileRoutes: !(this.config.verboseFileRoutes === false),\n },\n node,\n })\n\n if (transformResult.result === 'no-route-export') {\n this.logger.warn(\n `Route file \"${node.fullPath}\" does not contain any route piece. This is likely a mistake.`,\n )\n return null\n }\n if (transformResult.result === 'error') {\n throw new Error(\n `Error transforming route file ${node.fullPath}: ${transformResult.error}`,\n )\n }\n if (transformResult.result === 'modified') {\n updatedCacheEntry.fileContent = transformResult.output\n shouldWriteRouteFile = true\n }\n\n for (const plugin of this.plugins) {\n plugin.afterTransform?.({ node, prevNode: previousCacheEntry?.node })\n }\n\n // file was changed\n if (shouldWriteRouteFile) {\n const stats = await this.safeFileWrite({\n filePath: node.fullPath,\n newContent: updatedCacheEntry.fileContent,\n strategy: {\n type: 'mtime',\n expectedMtimeMs: updatedCacheEntry.mtimeMs,\n },\n })\n updatedCacheEntry.mtimeMs = stats.mtimeMs\n }\n\n this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry)\n return {\n node,\n shouldWriteTree,\n cacheEntry: updatedCacheEntry,\n }\n }\n\n private async didRouteFileChangeComparedToCache(\n file: {\n path: string\n mtimeMs?: bigint\n },\n cache: 'routeNodeCache' | 'routeNodeShadowCache',\n ): Promise<FileCacheChange<RouteNodeCacheEntry>> {\n const cacheEntry = this[cache].get(file.path)\n return this.didFileChangeComparedToCache(file, cacheEntry)\n }\n\n private async didFileChangeComparedToCache<\n TCacheEntry extends GeneratorCacheEntry,\n >(\n file: {\n path: string\n mtimeMs?: bigint\n },\n cacheEntry: TCacheEntry | undefined,\n ): Promise<FileCacheChange<TCacheEntry>> {\n // for now we rely on the modification time of the file\n // to determine if the file has changed\n // we could also compare the file content but this would be slower as we would have to read the file\n\n if (!cacheEntry) {\n return { result: 'file-not-in-cache' }\n }\n let mtimeMs = file.mtimeMs\n\n if (mtimeMs === undefined) {\n try {\n const currentStat = await this.fs.stat(file.path)\n mtimeMs = currentStat.mtimeMs\n } catch {\n return { result: 'cannot-stat-file' }\n }\n }\n return { result: mtimeMs !== cacheEntry.mtimeMs, mtimeMs, cacheEntry }\n }\n\n private async safeFileWrite(opts: {\n filePath: string\n newContent: string\n strategy:\n | {\n type: 'mtime'\n expectedMtimeMs: bigint\n }\n | {\n type: 'new-file'\n }\n }) {\n const tmpPath = this.getTempFileName(opts.filePath)\n await this.fs.writeFile(tmpPath, opts.newContent)\n\n if (opts.strategy.type === 'mtime') {\n const beforeStat = await this.fs.stat(opts.filePath)\n if (beforeStat.mtimeMs !== opts.strategy.expectedMtimeMs) {\n throw rerun({\n msg: `File ${opts.filePath} was modified by another process during processing.`,\n event: { type: 'update', path: opts.filePath },\n })\n }\n const newFileState = await this.fs.stat(tmpPath)\n if (newFileState.mode !== beforeStat.mode) {\n await this.fs.chmod(tmpPath, beforeStat.mode)\n }\n if (\n newFileState.uid !== beforeStat.uid ||\n newFileState.gid !== beforeStat.gid\n ) {\n try {\n await this.fs.chown(tmpPath, beforeStat.uid, beforeStat.gid)\n } catch (err) {\n if (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n (err as any).code === 'EPERM'\n ) {\n console.warn(\n `[safeFileWrite] chown failed: ${(err as any).message}`,\n )\n } else {\n throw err\n }\n }\n }\n } else {\n if (await checkFileExists(opts.filePath)) {\n throw rerun({\n msg: `File ${opts.filePath} already exists. Cannot overwrite.`,\n event: { type: 'update', path: opts.filePath },\n })\n }\n }\n\n const stat = await this.fs.stat(tmpPath)\n\n await this.fs.rename(tmpPath, opts.filePath)\n\n return stat\n }\n\n private getTempFileName(filePath: string) {\n const absPath = path.resolve(filePath)\n const hash = crypto.createHash('md5').update(absPath).digest('hex')\n // lazy initialize sessionId to only create tmpDir when it is first needed\n if (!this.sessionId) {\n // ensure the directory exists\n mkdirSync(this.config.tmpDir, { recursive: true })\n this.sessionId = crypto.randomBytes(4).toString('hex')\n }\n return path.join(this.config.tmpDir, `${this.sessionId}-${hash}`)\n }\n\n private async isRouteFileCacheFresh(node: RouteNode): Promise<\n | {\n status: 'fresh'\n cacheEntry: RouteNodeCacheEntry\n }\n | { status: 'stale'; cacheEntry?: RouteNodeCacheEntry }\n > {\n const fileChangedCache = await this.didRouteFileChangeComparedToCache(\n { path: node.fullPath },\n 'routeNodeCache',\n )\n if (fileChangedCache.result === false) {\n this.routeNodeShadowCache.set(node.fullPath, fileChangedCache.cacheEntry)\n return {\n status: 'fresh',\n cacheEntry: fileChangedCache.cacheEntry,\n }\n }\n if (fileChangedCache.result === 'cannot-stat-file') {\n throw new Error(`⚠️ expected route file to exist at ${node.fullPath}`)\n }\n const mtimeMs =\n fileChangedCache.result === true ? fileChangedCache.mtimeMs : undefined\n\n const shadowCacheFileChange = await this.didRouteFileChangeComparedToCache(\n { path: node.fullPath, mtimeMs },\n 'routeNodeShadowCache',\n )\n\n if (shadowCacheFileChange.result === 'cannot-stat-file') {\n throw new Error(`⚠️ expected route file to exist at ${node.fullPath}`)\n }\n\n if (shadowCacheFileChange.result === false) {\n // shadow cache has latest file state already\n if (fileChangedCache.result === true) {\n return {\n status: 'fresh',\n cacheEntry: shadowCacheFileChange.cacheEntry,\n }\n }\n }\n\n if (fileChangedCache.result === 'file-not-in-cache') {\n return {\n status: 'stale',\n }\n }\n return { status: 'stale', cacheEntry: fileChangedCache.cacheEntry }\n }\n\n private async handleRootNode(node: RouteNode) {\n const result = await this.isRouteFileCacheFresh(node)\n\n if (result.status === 'fresh') {\n this.routeNodeShadowCache.set(node.fullPath, result.cacheEntry)\n }\n const rootNodeFile = await this.fs.readFile(node.fullPath)\n if (rootNodeFile === 'file-not-existing') {\n throw new Error(`⚠️ expected root route to exist at ${node.fullPath}`)\n }\n\n const updatedCacheEntry: RouteNodeCacheEntry = {\n fileContent: rootNodeFile.fileContent,\n mtimeMs: rootNodeFile.stat.mtimeMs,\n routeId: node.routePath ?? '$$TSR_NO_ROOT_ROUTE_PATH_ASSIGNED$$',\n node,\n }\n\n // scaffold the root route\n if (!rootNodeFile.fileContent) {\n const rootTemplate = this.targetTemplate.rootRoute\n const rootRouteContent = await fillTemplate(\n this.config,\n rootTemplate.template(),\n {\n tsrImports: rootTemplate.imports.tsrImports(),\n tsrPath: rootPathId,\n tsrExportStart: rootTemplate.imports.tsrExportStart(),\n tsrExportEnd: rootTemplate.imports.tsrExportEnd(),\n },\n )\n\n this.logger.log(`🟡 Creating ${node.fullPath}`)\n const stats = await this.safeFileWrite({\n filePath: node.fullPath,\n newContent: rootRouteContent,\n strategy: {\n type: 'mtime',\n expectedMtimeMs: rootNodeFile.stat.mtimeMs,\n },\n })\n updatedCacheEntry.fileContent = rootRouteContent\n updatedCacheEntry.mtimeMs = stats.mtimeMs\n }\n\n this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry)\n }\n\n public async getCrawlingResult(): Promise<CrawlingResult | undefined> {\n await this.runPromise\n return this.crawlingResult\n }\n\n private static handleNode(node: RouteNode, acc: HandleNodeAccumulator) {\n // Do not remove this as we need to set the lastIndex to 0 as it\n // is necessary to reset the regex's index when using the global flag\n // otherwise it might not match the next time it's used\n resetRegex(this.routeGroupPatternRegex)\n\n let parentRoute = hasParentRoute(acc.routeNodes, node, node.routePath)\n\n // if the parent route is a virtual parent route, we need to find the real parent route\n if (parentRoute?.isVirtualParentRoute && parentRoute.children?.length) {\n // only if this sub-parent route returns a valid parent route, we use it, if not leave it as it\n const possibleParentRoute = hasParentRoute(\n parentRoute.children,\n node,\n node.routePath,\n )\n if (possibleParentRoute) {\n parentRoute = possibleParentRoute\n }\n }\n\n if (parentRoute) node.parent = parentRoute\n\n node.path = determineNodePath(node)\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath.split('/')\n const lastRouteSegment = split[split.length - 1] ?? trimmedPath\n\n node.isNonPath =\n lastRouteSegment.startsWith('_') ||\n split.every((part) => this.routeGroupPatternRegex.test(part))\n\n node.cleanedPath = removeGroups(\n removeUnderscores(removeLayoutSegments(node.path)) ?? '',\n )\n\n if (\n node._fsRouteType === 'layout' ||\n node._fsRouteType === 'pathless_layout'\n ) {\n node.cleanedPath = removeTrailingSlash(node.cleanedPath)\n }\n\n if (\n !node.isVirtual &&\n (\n [\n 'lazy',\n 'loader',\n 'component',\n 'pendingComponent',\n 'errorComponent',\n ] satisfies Array<FsRouteType>\n ).some((d) => d === node._fsRouteType)\n ) {\n acc.routePiecesByPath[node.routePath!] =\n acc.routePiecesByPath[node.routePath!] || {}\n\n acc.routePiecesByPath[node.routePath!]![\n node._fsRouteType === 'lazy'\n ? 'lazy'\n : node._fsRouteType === 'loader'\n ? 'loader'\n : node._fsRouteType === 'errorComponent'\n ? 'errorComponent'\n : node._fsRouteType === 'pendingComponent'\n ? 'pendingComponent'\n : 'component'\n ] = node\n\n const anchorRoute = acc.routeNodes.find(\n (d) => d.routePath === node.routePath,\n )\n\n if (!anchorRoute) {\n this.handleNode(\n {\n ...node,\n isVirtual: true,\n _fsRouteType: 'static',\n },\n acc,\n )\n }\n return\n }\n\n const cleanedPathIsEmpty = (node.cleanedPath || '').length === 0\n const nonPathRoute =\n node._fsRouteType === 'pathless_layout' && node.isNonPath\n\n node.isVirtualParentRequired =\n node._fsRouteType === 'pathless_layout' || nonPathRoute\n ? !cleanedPathIsEmpty\n : false\n\n if (!node.isVirtual && node.isVirtualParentRequired) {\n const parentRoutePath = removeLastSegmentFromPath(node.routePath) || '/'\n const parentVariableName = routePathToVariable(parentRoutePath)\n\n const anchorRoute = acc.routeNodes.find(\n (d) => d.routePath === parentRoutePath,\n )\n\n if (!anchorRoute) {\n const parentNode: RouteNode = {\n ...node,\n path: removeLastSegmentFromPath(node.path) || '/',\n filePath: removeLastSegmentFromPath(node.filePath) || '/',\n fullPath: removeLastSegmentFromPath(node.fullPath) || '/',\n routePath: parentRoutePath,\n variableName: parentVariableName,\n isVirtual: true,\n _fsRouteType: 'layout', // layout since this route will wrap other routes\n isVirtualParentRoute: true,\n isVirtualParentRequired: false,\n }\n\n parentNode.children = parentNode.children ?? []\n parentNode.children.push(node)\n\n node.parent = parentNode\n\n if (node._fsRouteType === 'pathless_layout') {\n // since `node.path` is used as the `id` on the route definition, we need to update it\n node.path = determineNodePath(node)\n }\n\n this.handleNode(parentNode, acc)\n } else {\n anchorRoute.children = anchorRoute.children ?? []\n anchorRoute.children.push(node)\n\n node.parent = anchorRoute\n }\n }\n\n if (node.parent) {\n if (!node.isVirtualParentRequired) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n }\n } else {\n acc.routeTree.push(node)\n }\n\n acc.routeNodes.push(node)\n }\n\n // only process files that are relevant for the route tree generation\n private isFileRelevantForRouteTreeGeneration(filePath: string): boolean {\n // the generated route tree file\n if (filePath === this.generatedRouteTreePath) {\n return true\n }\n\n // files inside the routes folder\n if (filePath.startsWith(this.routesDirectoryPath)) {\n return true\n }\n\n // the virtual route config file passed into `virtualRouteConfig`\n if (\n typeof this.config.virtualRouteConfig === 'string' &&\n filePath === this.config.virtualRouteConfig\n ) {\n return true\n }\n\n // this covers all files that are mounted via `virtualRouteConfig` or any `__virtual.ts` files\n if (this.routeNodeCache.has(filePath)) {\n return true\n }\n\n // virtual config files such as`__virtual.ts`\n if (isVirtualConfigFile(path.basename(filePath))) {\n return true\n }\n\n // route files inside directories mounted via `physical()` inside a virtual route config\n if (this.physicalDirectories.some((dir) => filePath.startsWith(dir))) {\n return true\n }\n\n return false\n }\n}\n"],"names":["fsp","logging","getTargetTemplate","existsSync","mkdirSync","virtualGetRouteNodes","physicalGetRouteNodes","rootPathId","multiSortBy","format","getImportForRouteNode","isRouteNodeValidForAugmentation","buildRouteTreeConfig","findParent","replaceBackslash","removeExt","createRouteNodesByFullPath","getResolvedRouteNodeVariableName","createRouteNodesByTo","rootRouteId","createRouteNodesById","buildFileRoutesByPathInterface","checkRouteFullPathUniqueness","mergeImportDeclarations","buildImportString","moduleAugmentation","getImportPath","fillTemplate","transform","checkFileExists","resetRegex","hasParentRoute","determineNodePath","trimPathLeft","removeGroups","removeUnderscores","removeLayoutSegments","removeTrailingSlash","removeLastSegmentFromPath","routePathToVariable","isVirtualConfigFile"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"generator.cjs","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport { existsSync, mkdirSync } from 'node:fs'\nimport crypto from 'node:crypto'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { logging } from './logger'\nimport {\n isVirtualConfigFile,\n getRouteNodes as physicalGetRouteNodes,\n} from './filesystem/physical/getRouteNodes'\nimport { getRouteNodes as virtualGetRouteNodes } from './filesystem/virtual/getRouteNodes'\nimport { rootPathId } from './filesystem/physical/rootPathId'\nimport {\n buildFileRoutesByPathInterface,\n buildImportString,\n buildRouteTreeConfig,\n checkFileExists,\n checkRouteFullPathUniqueness,\n createRouteNodesByFullPath,\n createRouteNodesById,\n createRouteNodesByTo,\n determineNodePath,\n findParent,\n format,\n getImportForRouteNode,\n getImportPath,\n getResolvedRouteNodeVariableName,\n hasParentRoute,\n isRouteNodeValidForAugmentation,\n mergeImportDeclarations,\n multiSortBy,\n removeExt,\n removeGroups,\n removeLastSegmentFromPath,\n removeLayoutSegments,\n removeLeadingUnderscores,\n removeTrailingSlash,\n removeUnderscores,\n replaceBackslash,\n resetRegex,\n routePathToVariable,\n trimPathLeft,\n} from './utils'\nimport { fillTemplate, getTargetTemplate } from './template'\nimport { transform } from './transform/transform'\nimport type { GeneratorPlugin } from './plugin/types'\nimport type { TargetTemplate } from './template'\nimport type {\n FsRouteType,\n GetRouteNodesResult,\n GetRoutesByFileMapResult,\n HandleNodeAccumulator,\n ImportDeclaration,\n RouteNode,\n} from './types'\nimport type { Config } from './config'\nimport type { Logger } from './logger'\n\ninterface fs {\n stat: (\n filePath: string,\n ) => Promise<{ mtimeMs: bigint; mode: number; uid: number; gid: number }>\n rename: (oldPath: string, newPath: string) => Promise<void>\n writeFile: (filePath: string, content: string) => Promise<void>\n readFile: (\n filePath: string,\n ) => Promise<\n { stat: { mtimeMs: bigint }; fileContent: string } | 'file-not-existing'\n >\n chmod: (filePath: string, mode: number) => Promise<void>\n chown: (filePath: string, uid: number, gid: number) => Promise<void>\n}\n\nconst DefaultFileSystem: fs = {\n stat: async (filePath) => {\n const res = await fsp.stat(filePath, { bigint: true })\n return {\n mtimeMs: res.mtimeMs,\n mode: Number(res.mode),\n uid: Number(res.uid),\n gid: Number(res.gid),\n }\n },\n rename: (oldPath, newPath) => fsp.rename(oldPath, newPath),\n writeFile: (filePath, content) => fsp.writeFile(filePath, content),\n readFile: async (filePath: string) => {\n try {\n const fileHandle = await fsp.open(filePath, 'r')\n const stat = await fileHandle.stat({ bigint: true })\n const fileContent = (await fileHandle.readFile()).toString()\n await fileHandle.close()\n return { stat, fileContent }\n } catch (e: any) {\n if ('code' in e) {\n if (e.code === 'ENOENT') {\n return 'file-not-existing'\n }\n }\n throw e\n }\n },\n chmod: (filePath, mode) => fsp.chmod(filePath, mode),\n chown: (filePath, uid, gid) => fsp.chown(filePath, uid, gid),\n}\n\ninterface Rerun {\n rerun: true\n msg?: string\n event: GeneratorEvent\n}\nfunction rerun(opts: { msg?: string; event?: GeneratorEvent }): Rerun {\n const { event, ...rest } = opts\n return { rerun: true, event: event ?? { type: 'rerun' }, ...rest }\n}\n\nfunction isRerun(result: unknown): result is Rerun {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'rerun' in result &&\n result.rerun === true\n )\n}\n\nexport type FileEventType = 'create' | 'update' | 'delete'\nexport type FileEvent = {\n type: FileEventType\n path: string\n}\nexport type GeneratorEvent = FileEvent | { type: 'rerun' }\n\ntype FileCacheChange<TCacheEntry extends GeneratorCacheEntry> =\n | {\n result: false\n cacheEntry: TCacheEntry\n }\n | { result: true; mtimeMs: bigint; cacheEntry: TCacheEntry }\n | {\n result: 'file-not-in-cache'\n }\n | {\n result: 'cannot-stat-file'\n }\n\ninterface GeneratorCacheEntry {\n mtimeMs: bigint\n fileContent: string\n}\n\ninterface RouteNodeCacheEntry extends GeneratorCacheEntry {\n routeId: string\n node: RouteNode\n}\n\ntype GeneratorRouteNodeCache = Map</** filePath **/ string, RouteNodeCacheEntry>\n\ninterface CrawlingResult {\n rootRouteNode: RouteNode\n routeFileResult: Array<RouteNode>\n acc: HandleNodeAccumulator\n}\n\nexport class Generator {\n /**\n * why do we have two caches for the route files?\n * During processing, we READ from the cache and WRITE to the shadow cache.\n *\n * After a route file is processed, we write to the shadow cache.\n * If during processing we bail out and re-run, we don't lose this modification\n * but still can track whether the file contributed changes and thus the route tree file needs to be regenerated.\n * After all files are processed, we swap the shadow cache with the main cache and initialize a new shadow cache.\n * That way we also ensure deleted/renamed files don't stay in the cache forever.\n */\n private routeNodeCache: GeneratorRouteNodeCache = new Map()\n private routeNodeShadowCache: GeneratorRouteNodeCache = new Map()\n\n private routeTreeFileCache: GeneratorCacheEntry | undefined\n\n private crawlingResult: CrawlingResult | undefined\n public config: Config\n public targetTemplate: TargetTemplate\n\n private root: string\n private routesDirectoryPath: string\n private sessionId?: string\n private fs: fs\n private logger: Logger\n private generatedRouteTreePath: string\n private runPromise: Promise<void> | undefined\n private fileEventQueue: Array<GeneratorEvent> = []\n private plugins: Array<GeneratorPlugin> = []\n private static routeGroupPatternRegex = /\\(.+\\)/g\n private physicalDirectories: Array<string> = []\n\n constructor(opts: { config: Config; root: string; fs?: fs }) {\n this.config = opts.config\n this.logger = logging({ disabled: this.config.disableLogging })\n this.root = opts.root\n this.fs = opts.fs || DefaultFileSystem\n this.generatedRouteTreePath = this.getGeneratedRouteTreePath()\n this.targetTemplate = getTargetTemplate(this.config)\n\n this.routesDirectoryPath = this.getRoutesDirectoryPath()\n this.plugins.push(...(opts.config.plugins || []))\n\n for (const plugin of this.plugins) {\n plugin.init?.({ generator: this })\n }\n }\n\n private getGeneratedRouteTreePath() {\n const generatedRouteTreePath = path.isAbsolute(\n this.config.generatedRouteTree,\n )\n ? this.config.generatedRouteTree\n : path.resolve(this.root, this.config.generatedRouteTree)\n\n const generatedRouteTreeDir = path.dirname(generatedRouteTreePath)\n\n if (!existsSync(generatedRouteTreeDir)) {\n mkdirSync(generatedRouteTreeDir, { recursive: true })\n }\n\n return generatedRouteTreePath\n }\n\n private getRoutesDirectoryPath() {\n return path.isAbsolute(this.config.routesDirectory)\n ? this.config.routesDirectory\n : path.resolve(this.root, this.config.routesDirectory)\n }\n\n public getRoutesByFileMap(): GetRoutesByFileMapResult {\n return new Map(\n [...this.routeNodeCache.entries()].map(([filePath, cacheEntry]) => [\n filePath,\n { routePath: cacheEntry.routeId },\n ]),\n )\n }\n\n public async run(event?: GeneratorEvent): Promise<void> {\n if (\n event &&\n event.type !== 'rerun' &&\n !this.isFileRelevantForRouteTreeGeneration(event.path)\n ) {\n return\n }\n this.fileEventQueue.push(event ?? { type: 'rerun' })\n // only allow a single run at a time\n if (this.runPromise) {\n return this.runPromise\n }\n\n this.runPromise = (async () => {\n do {\n // synchronously copy and clear the queue since we are going to iterate asynchronously over it\n // and while we do so, a new event could be put into the queue\n const tempQueue = this.fileEventQueue\n this.fileEventQueue = []\n // if we only have 'update' events in the queue\n // and we already have the affected files' latest state in our cache, we can exit early\n const remainingEvents = (\n await Promise.all(\n tempQueue.map(async (e) => {\n if (e.type === 'update') {\n let cacheEntry: GeneratorCacheEntry | undefined\n if (e.path === this.generatedRouteTreePath) {\n cacheEntry = this.routeTreeFileCache\n } else {\n // we only check the routeNodeCache here\n // if the file's state is only up-to-date in the shadow cache we need to re-run\n cacheEntry = this.routeNodeCache.get(e.path)\n }\n const change = await this.didFileChangeComparedToCache(\n { path: e.path },\n cacheEntry,\n )\n if (change.result === false) {\n return null\n }\n }\n return e\n }),\n )\n ).filter((e) => e !== null)\n\n if (remainingEvents.length === 0) {\n break\n }\n\n try {\n await this.generatorInternal()\n } catch (err) {\n const errArray = !Array.isArray(err) ? [err] : err\n\n const recoverableErrors = errArray.filter((e) => isRerun(e))\n if (recoverableErrors.length === errArray.length) {\n this.fileEventQueue.push(...recoverableErrors.map((e) => e.event))\n recoverableErrors.forEach((e) => {\n if (e.msg) {\n this.logger.info(e.msg)\n }\n })\n } else {\n const unrecoverableErrors = errArray.filter((e) => !isRerun(e))\n this.runPromise = undefined\n throw new Error(\n unrecoverableErrors.map((e) => (e as Error).message).join(),\n )\n }\n }\n } while (this.fileEventQueue.length)\n this.runPromise = undefined\n })()\n return this.runPromise\n }\n\n private async generatorInternal() {\n let writeRouteTreeFile: boolean | 'force' = false\n\n let getRouteNodesResult: GetRouteNodesResult\n\n if (this.config.virtualRouteConfig) {\n getRouteNodesResult = await virtualGetRouteNodes(this.config, this.root)\n } else {\n getRouteNodesResult = await physicalGetRouteNodes(this.config, this.root)\n }\n\n const {\n rootRouteNode,\n routeNodes: beforeRouteNodes,\n physicalDirectories,\n } = getRouteNodesResult\n if (rootRouteNode === undefined) {\n let errorMessage = `rootRouteNode must not be undefined. Make sure you've added your root route into the route-tree.`\n if (!this.config.virtualRouteConfig) {\n errorMessage += `\\nMake sure that you add a \"${rootPathId}.${this.config.disableTypes ? 'js' : 'tsx'}\" file to your routes directory.\\nAdd the file in: \"${this.config.routesDirectory}/${rootPathId}.${this.config.disableTypes ? 'js' : 'tsx'}\"`\n }\n throw new Error(errorMessage)\n }\n this.physicalDirectories = physicalDirectories\n\n await this.handleRootNode(rootRouteNode)\n\n const preRouteNodes = multiSortBy(beforeRouteNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) =>\n d.filePath.match(new RegExp(`[./]${this.config.indexToken}[.]`))\n ? 1\n : -1,\n (d) =>\n d.filePath.match(\n /[./](component|errorComponent|pendingComponent|loader|lazy)[.]/,\n )\n ? 1\n : -1,\n (d) =>\n d.filePath.match(new RegExp(`[./]${this.config.routeToken}[.]`))\n ? -1\n : 1,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => ![`/${rootPathId}`].includes(d.routePath || ''))\n\n const routeFileAllResult = await Promise.allSettled(\n preRouteNodes\n // only process routes that are backed by an actual file\n .filter((n) => !n.isVirtualParentRoute && !n.isVirtual)\n .map((n) => this.processRouteNodeFile(n)),\n )\n\n const rejections = routeFileAllResult.filter(\n (result) => result.status === 'rejected',\n )\n if (rejections.length > 0) {\n throw rejections.map((e) => e.reason)\n }\n\n const routeFileResult = routeFileAllResult.flatMap((result) => {\n if (result.status === 'fulfilled' && result.value !== null) {\n if (result.value.shouldWriteTree) {\n writeRouteTreeFile = true\n }\n return result.value.node\n }\n return []\n })\n\n // reset children in case we re-use a node from the cache\n routeFileResult.forEach((r) => (r.children = undefined))\n\n const acc: HandleNodeAccumulator = {\n routeTree: [],\n routeNodes: [],\n routePiecesByPath: {},\n }\n\n for (const node of routeFileResult) {\n Generator.handleNode(node, acc, this.config)\n }\n\n this.crawlingResult = { rootRouteNode, routeFileResult, acc }\n\n // this is the first time the generator runs, so read in the route tree file if it exists yet\n if (!this.routeTreeFileCache) {\n const routeTreeFile = await this.fs.readFile(this.generatedRouteTreePath)\n if (routeTreeFile !== 'file-not-existing') {\n this.routeTreeFileCache = {\n fileContent: routeTreeFile.fileContent,\n mtimeMs: routeTreeFile.stat.mtimeMs,\n }\n }\n writeRouteTreeFile = true\n } else {\n const routeTreeFileChange = await this.didFileChangeComparedToCache(\n { path: this.generatedRouteTreePath },\n this.routeTreeFileCache,\n )\n if (routeTreeFileChange.result !== false) {\n writeRouteTreeFile = 'force'\n if (routeTreeFileChange.result === true) {\n const routeTreeFile = await this.fs.readFile(\n this.generatedRouteTreePath,\n )\n if (routeTreeFile !== 'file-not-existing') {\n this.routeTreeFileCache = {\n fileContent: routeTreeFile.fileContent,\n mtimeMs: routeTreeFile.stat.mtimeMs,\n }\n }\n }\n }\n }\n\n if (!writeRouteTreeFile) {\n // only needs to be done if no other changes have been detected yet\n // compare shadowCache and cache to identify deleted routes\n if (this.routeNodeCache.size !== this.routeNodeShadowCache.size) {\n writeRouteTreeFile = true\n } else {\n for (const fullPath of this.routeNodeCache.keys()) {\n if (!this.routeNodeShadowCache.has(fullPath)) {\n writeRouteTreeFile = true\n break\n }\n }\n }\n }\n\n if (!writeRouteTreeFile) {\n this.swapCaches()\n return\n }\n\n const buildResult = this.buildRouteTree({\n rootRouteNode,\n acc,\n routeFileResult,\n })\n let routeTreeContent = buildResult.routeTreeContent\n\n routeTreeContent = this.config.enableRouteTreeFormatting\n ? await format(routeTreeContent, this.config)\n : routeTreeContent\n\n let newMtimeMs: bigint | undefined\n if (this.routeTreeFileCache) {\n if (\n writeRouteTreeFile !== 'force' &&\n this.routeTreeFileCache.fileContent === routeTreeContent\n ) {\n // existing route tree file is already up-to-date, don't write it\n // we should only get here in the initial run when the route cache is not filled yet\n } else {\n const newRouteTreeFileStat = await this.safeFileWrite({\n filePath: this.generatedRouteTreePath,\n newContent: routeTreeContent,\n strategy: {\n type: 'mtime',\n expectedMtimeMs: this.routeTreeFileCache.mtimeMs,\n },\n })\n newMtimeMs = newRouteTreeFileStat.mtimeMs\n }\n } else {\n const newRouteTreeFileStat = await this.safeFileWrite({\n filePath: this.generatedRouteTreePath,\n newContent: routeTreeContent,\n strategy: {\n type: 'new-file',\n },\n })\n newMtimeMs = newRouteTreeFileStat.mtimeMs\n }\n\n if (newMtimeMs !== undefined) {\n this.routeTreeFileCache = {\n fileContent: routeTreeContent,\n mtimeMs: newMtimeMs,\n }\n }\n\n this.plugins.map((plugin) => {\n return plugin.onRouteTreeChanged?.({\n routeTree: buildResult.routeTree,\n routeNodes: buildResult.routeNodes,\n acc,\n rootRouteNode,\n })\n })\n this.swapCaches()\n }\n\n private swapCaches() {\n this.routeNodeCache = this.routeNodeShadowCache\n this.routeNodeShadowCache = new Map()\n }\n\n public buildRouteTree(opts: {\n rootRouteNode: RouteNode\n acc: HandleNodeAccumulator\n routeFileResult: Array<RouteNode>\n config?: Partial<Config>\n }) {\n const config = { ...this.config, ...(opts.config || {}) }\n\n const { rootRouteNode, acc } = opts\n\n const sortedRouteNodes = multiSortBy(acc.routeNodes, [\n (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(config.indexToken) ? -1 : 1),\n (d) => d,\n ])\n\n const routeImports = sortedRouteNodes\n .filter((d) => !d.isVirtual)\n .flatMap((node) =>\n getImportForRouteNode(\n node,\n config,\n this.generatedRouteTreePath,\n this.root,\n ),\n )\n\n const virtualRouteNodes = sortedRouteNodes\n .filter((d) => d.isVirtual)\n .map((node) => {\n return `const ${\n node.variableName\n }RouteImport = createFileRoute('${node.routePath}')()`\n })\n\n const imports: Array<ImportDeclaration> = []\n if (acc.routeNodes.some((n) => n.isVirtual)) {\n imports.push({\n specifiers: [{ imported: 'createFileRoute' }],\n source: this.targetTemplate.fullPkg,\n })\n }\n if (config.verboseFileRoutes === false) {\n const typeImport: ImportDeclaration = {\n specifiers: [],\n source: this.targetTemplate.fullPkg,\n importKind: 'type',\n }\n if (\n sortedRouteNodes.some(\n (d) =>\n isRouteNodeValidForAugmentation(d) && d._fsRouteType !== 'lazy',\n )\n ) {\n typeImport.specifiers.push({ imported: 'CreateFileRoute' })\n }\n if (\n sortedRouteNodes.some(\n (node) =>\n acc.routePiecesByPath[node.routePath!]?.lazy &&\n isRouteNodeValidForAugmentation(node),\n )\n ) {\n typeImport.specifiers.push({ imported: 'CreateLazyFileRoute' })\n }\n\n if (typeImport.specifiers.length > 0) {\n typeImport.specifiers.push({ imported: 'FileRoutesByPath' })\n imports.push(typeImport)\n }\n }\n\n const routeTreeConfig = buildRouteTreeConfig(\n acc.routeTree,\n config.disableTypes,\n )\n\n const createUpdateRoutes = sortedRouteNodes.map((node) => {\n const loaderNode = acc.routePiecesByPath[node.routePath!]?.loader\n const componentNode = acc.routePiecesByPath[node.routePath!]?.component\n const errorComponentNode =\n acc.routePiecesByPath[node.routePath!]?.errorComponent\n const pendingComponentNode =\n acc.routePiecesByPath[node.routePath!]?.pendingComponent\n const lazyComponentNode = acc.routePiecesByPath[node.routePath!]?.lazy\n\n return [\n [\n `const ${node.variableName}Route = ${node.variableName}RouteImport.update({\n ${[\n `id: '${node.path}'`,\n !node.isNonPath ? `path: '${node.cleanedPath}'` : undefined,\n `getParentRoute: () => ${findParent(node)}`,\n ]\n .filter(Boolean)\n .join(',')}\n }${config.disableTypes ? '' : 'as any'})`,\n loaderNode\n ? `.updateLoader({ loader: lazyFn(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, loaderNode.filePath),\n ),\n config.addExtensions,\n ),\n )}'), 'loader') })`\n : '',\n componentNode || errorComponentNode || pendingComponentNode\n ? `.update({\n ${(\n [\n ['component', componentNode],\n ['errorComponent', errorComponentNode],\n ['pendingComponent', pendingComponentNode],\n ] as const\n )\n .filter((d) => d[1])\n .map((d) => {\n return `${\n d[0]\n }: lazyRouteComponent(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, d[1]!.filePath),\n ),\n config.addExtensions,\n ),\n )}'), '${d[0]}')`\n })\n .join('\\n,')}\n })`\n : '',\n lazyComponentNode\n ? `.lazy(() => import('./${replaceBackslash(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(\n config.routesDirectory,\n lazyComponentNode.filePath,\n ),\n ),\n config.addExtensions,\n ),\n )}').then((d) => d.Route))`\n : '',\n ].join(''),\n ].join('\\n\\n')\n })\n\n let fileRoutesByPathInterface = ''\n let fileRoutesByFullPath = ''\n\n if (!config.disableTypes) {\n fileRoutesByFullPath = [\n `export interface FileRoutesByFullPath {\n${[...createRouteNodesByFullPath(acc.routeNodes, config).entries()]\n .filter(([fullPath]) => fullPath)\n .map(([fullPath, routeNode]) => {\n return `'${fullPath}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRoutesByTo {\n${[...createRouteNodesByTo(acc.routeNodes, config).entries()]\n .filter(([to]) => to)\n .map(([to, routeNode]) => {\n return `'${to}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n })}\n}`,\n `export interface FileRoutesById {\n'${rootRouteId}': typeof rootRouteImport,\n${[...createRouteNodesById(acc.routeNodes).entries()].map(([id, routeNode]) => {\n return `'${id}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n})}\n}`,\n `export interface FileRouteTypes {\nfileRoutesByFullPath: FileRoutesByFullPath\nfullPaths: ${\n acc.routeNodes.length > 0\n ? [...createRouteNodesByFullPath(acc.routeNodes, config).keys()]\n .filter((fullPath) => fullPath)\n .map((fullPath) => `'${fullPath}'`)\n .join('|')\n : 'never'\n }\nfileRoutesByTo: FileRoutesByTo\nto: ${\n acc.routeNodes.length > 0\n ? [...createRouteNodesByTo(acc.routeNodes, config).keys()]\n .filter((to) => to)\n .map((to) => `'${to}'`)\n .join('|')\n : 'never'\n }\nid: ${[`'${rootRouteId}'`, ...[...createRouteNodesById(acc.routeNodes).keys()].map((id) => `'${id}'`)].join('|')}\nfileRoutesById: FileRoutesById\n}`,\n `export interface RootRouteChildren {\n${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`).join(',')}\n}`,\n ].join('\\n')\n\n fileRoutesByPathInterface = buildFileRoutesByPathInterface({\n module: this.targetTemplate.fullPkg,\n interfaceName: 'FileRoutesByPath',\n routeNodes: sortedRouteNodes,\n config,\n })\n }\n\n const routeTree = [\n `const rootRouteChildren${config.disableTypes ? '' : `: RootRouteChildren`} = {\n ${acc.routeTree\n .map(\n (child) =>\n `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`,\n )\n .join(',')}\n}`,\n `export const routeTree = rootRouteImport._addFileChildren(rootRouteChildren)${config.disableTypes ? '' : `._addFileTypes<FileRouteTypes>()`}`,\n ].join('\\n')\n\n checkRouteFullPathUniqueness(\n sortedRouteNodes.filter(\n (d) => d.children === undefined && 'lazy' !== d._fsRouteType,\n ),\n config,\n )\n\n let mergedImports = mergeImportDeclarations(imports)\n if (config.disableTypes) {\n mergedImports = mergedImports.filter((d) => d.importKind !== 'type')\n }\n\n const importStatements = mergedImports.map(buildImportString)\n\n let moduleAugmentation = ''\n if (config.verboseFileRoutes === false && !config.disableTypes) {\n moduleAugmentation = opts.routeFileResult\n .map((node) => {\n const getModuleDeclaration = (routeNode?: RouteNode) => {\n if (!isRouteNodeValidForAugmentation(routeNode)) {\n return ''\n }\n let moduleAugmentation = ''\n if (routeNode._fsRouteType === 'lazy') {\n moduleAugmentation = `const createLazyFileRoute: CreateLazyFileRoute<FileRoutesByPath['${routeNode.routePath}']['preLoaderRoute']>`\n } else {\n moduleAugmentation = `const createFileRoute: CreateFileRoute<'${routeNode.routePath}',\n FileRoutesByPath['${routeNode.routePath}']['parentRoute'],\n FileRoutesByPath['${routeNode.routePath}']['id'],\n FileRoutesByPath['${routeNode.routePath}']['path'],\n FileRoutesByPath['${routeNode.routePath}']['fullPath']\n >\n `\n }\n\n return `declare module './${getImportPath(routeNode, config, this.generatedRouteTreePath)}' {\n ${moduleAugmentation}\n }`\n }\n return getModuleDeclaration(node)\n })\n .join('\\n')\n }\n\n const rootRouteImport = getImportForRouteNode(\n rootRouteNode,\n config,\n this.generatedRouteTreePath,\n this.root,\n )\n routeImports.unshift(rootRouteImport)\n\n let footer: Array<string> = []\n if (config.routeTreeFileFooter) {\n if (Array.isArray(config.routeTreeFileFooter)) {\n footer = config.routeTreeFileFooter\n } else {\n footer = config.routeTreeFileFooter()\n }\n }\n const routeTreeContent = [\n ...config.routeTreeFileHeader,\n `// This file was automatically generated by TanStack Router.\n// You should NOT make any changes in this file as it will be overwritten.\n// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.`,\n [...importStatements].join('\\n'),\n mergeImportDeclarations(routeImports).map(buildImportString).join('\\n'),\n virtualRouteNodes.join('\\n'),\n createUpdateRoutes.join('\\n'),\n fileRoutesByFullPath,\n fileRoutesByPathInterface,\n moduleAugmentation,\n routeTreeConfig.join('\\n'),\n routeTree,\n ...footer,\n ]\n .filter(Boolean)\n .join('\\n\\n')\n return {\n routeTreeContent,\n routeTree: acc.routeTree,\n routeNodes: acc.routeNodes,\n }\n }\n\n private async processRouteNodeFile(node: RouteNode): Promise<{\n shouldWriteTree: boolean\n cacheEntry: RouteNodeCacheEntry\n node: RouteNode\n } | null> {\n const result = await this.isRouteFileCacheFresh(node)\n\n if (result.status === 'fresh') {\n return {\n node: result.cacheEntry.node,\n shouldWriteTree: false,\n cacheEntry: result.cacheEntry,\n }\n }\n\n const previousCacheEntry = result.cacheEntry\n\n const existingRouteFile = await this.fs.readFile(node.fullPath)\n if (existingRouteFile === 'file-not-existing') {\n throw new Error(`⚠️ File ${node.fullPath} does not exist`)\n }\n\n const updatedCacheEntry: RouteNodeCacheEntry = {\n fileContent: existingRouteFile.fileContent,\n mtimeMs: existingRouteFile.stat.mtimeMs,\n routeId: node.routePath ?? '$$TSR_NO_ROUTE_PATH_ASSIGNED$$',\n node,\n }\n\n const escapedRoutePath = node.routePath?.replaceAll('$', '$$') ?? ''\n\n let shouldWriteRouteFile = false\n let shouldWriteTree = false\n // now we need to either scaffold the file or transform it\n if (!existingRouteFile.fileContent) {\n shouldWriteRouteFile = true\n shouldWriteTree = true\n // Creating a new lazy route file\n if (node._fsRouteType === 'lazy') {\n const tLazyRouteTemplate = this.targetTemplate.lazyRoute\n // Check by default check if the user has a specific lazy route template\n // If not, check if the user has a route template and use that instead\n updatedCacheEntry.fileContent = await fillTemplate(\n this.config,\n (this.config.customScaffolding?.lazyRouteTemplate ||\n this.config.customScaffolding?.routeTemplate) ??\n tLazyRouteTemplate.template(),\n {\n tsrImports: tLazyRouteTemplate.imports.tsrImports(),\n tsrPath: escapedRoutePath.replaceAll(/\\{(.+?)\\}/gm, '$1'),\n tsrExportStart:\n tLazyRouteTemplate.imports.tsrExportStart(escapedRoutePath),\n tsrExportEnd: tLazyRouteTemplate.imports.tsrExportEnd(),\n },\n )\n } else if (\n // Creating a new normal route file\n (['layout', 'static'] satisfies Array<FsRouteType>).some(\n (d) => d === node._fsRouteType,\n ) ||\n (\n [\n 'component',\n 'pendingComponent',\n 'errorComponent',\n 'loader',\n ] satisfies Array<FsRouteType>\n ).every((d) => d !== node._fsRouteType)\n ) {\n const tRouteTemplate = this.targetTemplate.route\n updatedCacheEntry.fileContent = await fillTemplate(\n this.config,\n this.config.customScaffolding?.routeTemplate ??\n tRouteTemplate.template(),\n {\n tsrImports: tRouteTemplate.imports.tsrImports(),\n tsrPath: escapedRoutePath.replaceAll(/\\{(.+?)\\}/gm, '$1'),\n tsrExportStart:\n tRouteTemplate.imports.tsrExportStart(escapedRoutePath),\n tsrExportEnd: tRouteTemplate.imports.tsrExportEnd(),\n },\n )\n } else {\n return null\n }\n }\n // transform the file\n const transformResult = await transform({\n source: updatedCacheEntry.fileContent,\n ctx: {\n target: this.config.target,\n routeId: escapedRoutePath,\n lazy: node._fsRouteType === 'lazy',\n verboseFileRoutes: !(this.config.verboseFileRoutes === false),\n },\n node,\n })\n\n if (transformResult.result === 'no-route-export') {\n this.logger.warn(\n `Route file \"${node.fullPath}\" does not contain any route piece. This is likely a mistake.`,\n )\n return null\n }\n if (transformResult.result === 'error') {\n throw new Error(\n `Error transforming route file ${node.fullPath}: ${transformResult.error}`,\n )\n }\n if (transformResult.result === 'modified') {\n updatedCacheEntry.fileContent = transformResult.output\n shouldWriteRouteFile = true\n }\n\n for (const plugin of this.plugins) {\n plugin.afterTransform?.({ node, prevNode: previousCacheEntry?.node })\n }\n\n // file was changed\n if (shouldWriteRouteFile) {\n const stats = await this.safeFileWrite({\n filePath: node.fullPath,\n newContent: updatedCacheEntry.fileContent,\n strategy: {\n type: 'mtime',\n expectedMtimeMs: updatedCacheEntry.mtimeMs,\n },\n })\n updatedCacheEntry.mtimeMs = stats.mtimeMs\n }\n\n this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry)\n return {\n node,\n shouldWriteTree,\n cacheEntry: updatedCacheEntry,\n }\n }\n\n private async didRouteFileChangeComparedToCache(\n file: {\n path: string\n mtimeMs?: bigint\n },\n cache: 'routeNodeCache' | 'routeNodeShadowCache',\n ): Promise<FileCacheChange<RouteNodeCacheEntry>> {\n const cacheEntry = this[cache].get(file.path)\n return this.didFileChangeComparedToCache(file, cacheEntry)\n }\n\n private async didFileChangeComparedToCache<\n TCacheEntry extends GeneratorCacheEntry,\n >(\n file: {\n path: string\n mtimeMs?: bigint\n },\n cacheEntry: TCacheEntry | undefined,\n ): Promise<FileCacheChange<TCacheEntry>> {\n // for now we rely on the modification time of the file\n // to determine if the file has changed\n // we could also compare the file content but this would be slower as we would have to read the file\n\n if (!cacheEntry) {\n return { result: 'file-not-in-cache' }\n }\n let mtimeMs = file.mtimeMs\n\n if (mtimeMs === undefined) {\n try {\n const currentStat = await this.fs.stat(file.path)\n mtimeMs = currentStat.mtimeMs\n } catch {\n return { result: 'cannot-stat-file' }\n }\n }\n return { result: mtimeMs !== cacheEntry.mtimeMs, mtimeMs, cacheEntry }\n }\n\n private async safeFileWrite(opts: {\n filePath: string\n newContent: string\n strategy:\n | {\n type: 'mtime'\n expectedMtimeMs: bigint\n }\n | {\n type: 'new-file'\n }\n }) {\n const tmpPath = this.getTempFileName(opts.filePath)\n await this.fs.writeFile(tmpPath, opts.newContent)\n\n if (opts.strategy.type === 'mtime') {\n const beforeStat = await this.fs.stat(opts.filePath)\n if (beforeStat.mtimeMs !== opts.strategy.expectedMtimeMs) {\n throw rerun({\n msg: `File ${opts.filePath} was modified by another process during processing.`,\n event: { type: 'update', path: opts.filePath },\n })\n }\n const newFileState = await this.fs.stat(tmpPath)\n if (newFileState.mode !== beforeStat.mode) {\n await this.fs.chmod(tmpPath, beforeStat.mode)\n }\n if (\n newFileState.uid !== beforeStat.uid ||\n newFileState.gid !== beforeStat.gid\n ) {\n try {\n await this.fs.chown(tmpPath, beforeStat.uid, beforeStat.gid)\n } catch (err) {\n if (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n (err as any).code === 'EPERM'\n ) {\n console.warn(\n `[safeFileWrite] chown failed: ${(err as any).message}`,\n )\n } else {\n throw err\n }\n }\n }\n } else {\n if (await checkFileExists(opts.filePath)) {\n throw rerun({\n msg: `File ${opts.filePath} already exists. Cannot overwrite.`,\n event: { type: 'update', path: opts.filePath },\n })\n }\n }\n\n const stat = await this.fs.stat(tmpPath)\n\n await this.fs.rename(tmpPath, opts.filePath)\n\n return stat\n }\n\n private getTempFileName(filePath: string) {\n const absPath = path.resolve(filePath)\n const hash = crypto.createHash('md5').update(absPath).digest('hex')\n // lazy initialize sessionId to only create tmpDir when it is first needed\n if (!this.sessionId) {\n // ensure the directory exists\n mkdirSync(this.config.tmpDir, { recursive: true })\n this.sessionId = crypto.randomBytes(4).toString('hex')\n }\n return path.join(this.config.tmpDir, `${this.sessionId}-${hash}`)\n }\n\n private async isRouteFileCacheFresh(node: RouteNode): Promise<\n | {\n status: 'fresh'\n cacheEntry: RouteNodeCacheEntry\n }\n | { status: 'stale'; cacheEntry?: RouteNodeCacheEntry }\n > {\n const fileChangedCache = await this.didRouteFileChangeComparedToCache(\n { path: node.fullPath },\n 'routeNodeCache',\n )\n if (fileChangedCache.result === false) {\n this.routeNodeShadowCache.set(node.fullPath, fileChangedCache.cacheEntry)\n return {\n status: 'fresh',\n cacheEntry: fileChangedCache.cacheEntry,\n }\n }\n if (fileChangedCache.result === 'cannot-stat-file') {\n throw new Error(`⚠️ expected route file to exist at ${node.fullPath}`)\n }\n const mtimeMs =\n fileChangedCache.result === true ? fileChangedCache.mtimeMs : undefined\n\n const shadowCacheFileChange = await this.didRouteFileChangeComparedToCache(\n { path: node.fullPath, mtimeMs },\n 'routeNodeShadowCache',\n )\n\n if (shadowCacheFileChange.result === 'cannot-stat-file') {\n throw new Error(`⚠️ expected route file to exist at ${node.fullPath}`)\n }\n\n if (shadowCacheFileChange.result === false) {\n // shadow cache has latest file state already\n if (fileChangedCache.result === true) {\n return {\n status: 'fresh',\n cacheEntry: shadowCacheFileChange.cacheEntry,\n }\n }\n }\n\n if (fileChangedCache.result === 'file-not-in-cache') {\n return {\n status: 'stale',\n }\n }\n return { status: 'stale', cacheEntry: fileChangedCache.cacheEntry }\n }\n\n private async handleRootNode(node: RouteNode) {\n const result = await this.isRouteFileCacheFresh(node)\n\n if (result.status === 'fresh') {\n this.routeNodeShadowCache.set(node.fullPath, result.cacheEntry)\n }\n const rootNodeFile = await this.fs.readFile(node.fullPath)\n if (rootNodeFile === 'file-not-existing') {\n throw new Error(`⚠️ expected root route to exist at ${node.fullPath}`)\n }\n\n const updatedCacheEntry: RouteNodeCacheEntry = {\n fileContent: rootNodeFile.fileContent,\n mtimeMs: rootNodeFile.stat.mtimeMs,\n routeId: node.routePath ?? '$$TSR_NO_ROOT_ROUTE_PATH_ASSIGNED$$',\n node,\n }\n\n // scaffold the root route\n if (!rootNodeFile.fileContent) {\n const rootTemplate = this.targetTemplate.rootRoute\n const rootRouteContent = await fillTemplate(\n this.config,\n rootTemplate.template(),\n {\n tsrImports: rootTemplate.imports.tsrImports(),\n tsrPath: rootPathId,\n tsrExportStart: rootTemplate.imports.tsrExportStart(),\n tsrExportEnd: rootTemplate.imports.tsrExportEnd(),\n },\n )\n\n this.logger.log(`🟡 Creating ${node.fullPath}`)\n const stats = await this.safeFileWrite({\n filePath: node.fullPath,\n newContent: rootRouteContent,\n strategy: {\n type: 'mtime',\n expectedMtimeMs: rootNodeFile.stat.mtimeMs,\n },\n })\n updatedCacheEntry.fileContent = rootRouteContent\n updatedCacheEntry.mtimeMs = stats.mtimeMs\n }\n\n this.routeNodeShadowCache.set(node.fullPath, updatedCacheEntry)\n }\n\n public async getCrawlingResult(): Promise<CrawlingResult | undefined> {\n await this.runPromise\n return this.crawlingResult\n }\n\n private static handleNode(\n node: RouteNode,\n acc: HandleNodeAccumulator,\n config?: Config,\n ) {\n // Do not remove this as we need to set the lastIndex to 0 as it\n // is necessary to reset the regex's index when using the global flag\n // otherwise it might not match the next time it's used\n const useExperimentalNonNestedRoutes =\n config?.experimental?.nonNestedRoutes ?? false\n\n resetRegex(this.routeGroupPatternRegex)\n\n let parentRoute = hasParentRoute(\n acc.routeNodes,\n node,\n node.routePath,\n node.originalRoutePath,\n )\n\n // if the parent route is a virtual parent route, we need to find the real parent route\n if (parentRoute?.isVirtualParentRoute && parentRoute.children?.length) {\n // only if this sub-parent route returns a valid parent route, we use it, if not leave it as it\n const possibleParentRoute = hasParentRoute(\n parentRoute.children,\n node,\n node.routePath,\n node.originalRoutePath,\n )\n if (possibleParentRoute) {\n parentRoute = possibleParentRoute\n }\n }\n\n if (parentRoute) node.parent = parentRoute\n\n node.path = determineNodePath(node)\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath.split('/')\n const lastRouteSegment = split[split.length - 1] ?? trimmedPath\n\n node.isNonPath =\n lastRouteSegment.startsWith('_') ||\n split.every((part) => this.routeGroupPatternRegex.test(part))\n\n // with new nonNestedPaths feature we can be sure any remaining trailing underscores are escaped and should remain\n // TODO with new major we can remove check and only remove leading underscores\n node.cleanedPath = removeGroups(\n (useExperimentalNonNestedRoutes\n ? removeLeadingUnderscores(\n removeLayoutSegments(node.path ?? ''),\n config?.routeToken ?? '',\n )\n : removeUnderscores(removeLayoutSegments(node.path))) ?? '',\n )\n\n if (\n node._fsRouteType === 'layout' ||\n node._fsRouteType === 'pathless_layout'\n ) {\n node.cleanedPath = removeTrailingSlash(node.cleanedPath)\n }\n\n if (\n !node.isVirtual &&\n (\n [\n 'lazy',\n 'loader',\n 'component',\n 'pendingComponent',\n 'errorComponent',\n ] satisfies Array<FsRouteType>\n ).some((d) => d === node._fsRouteType)\n ) {\n acc.routePiecesByPath[node.routePath!] =\n acc.routePiecesByPath[node.routePath!] || {}\n\n acc.routePiecesByPath[node.routePath!]![\n node._fsRouteType === 'lazy'\n ? 'lazy'\n : node._fsRouteType === 'loader'\n ? 'loader'\n : node._fsRouteType === 'errorComponent'\n ? 'errorComponent'\n : node._fsRouteType === 'pendingComponent'\n ? 'pendingComponent'\n : 'component'\n ] = node\n\n const anchorRoute = acc.routeNodes.find(\n (d) => d.routePath === node.routePath,\n )\n\n if (!anchorRoute) {\n this.handleNode(\n {\n ...node,\n isVirtual: true,\n _fsRouteType: 'static',\n },\n acc,\n config,\n )\n }\n return\n }\n\n const cleanedPathIsEmpty = (node.cleanedPath || '').length === 0\n const nonPathRoute =\n node._fsRouteType === 'pathless_layout' && node.isNonPath\n\n node.isVirtualParentRequired =\n node._fsRouteType === 'pathless_layout' || nonPathRoute\n ? !cleanedPathIsEmpty\n : false\n\n if (!node.isVirtual && node.isVirtualParentRequired) {\n const parentRoutePath = removeLastSegmentFromPath(node.routePath) || '/'\n const parentVariableName = routePathToVariable(parentRoutePath)\n\n const anchorRoute = acc.routeNodes.find(\n (d) => d.routePath === parentRoutePath,\n )\n\n if (!anchorRoute) {\n const parentNode: RouteNode = {\n ...node,\n path: removeLastSegmentFromPath(node.path) || '/',\n filePath: removeLastSegmentFromPath(node.filePath) || '/',\n fullPath: removeLastSegmentFromPath(node.fullPath) || '/',\n routePath: parentRoutePath,\n variableName: parentVariableName,\n isVirtual: true,\n _fsRouteType: 'layout', // layout since this route will wrap other routes\n isVirtualParentRoute: true,\n isVirtualParentRequired: false,\n }\n\n parentNode.children = parentNode.children ?? []\n parentNode.children.push(node)\n\n node.parent = parentNode\n\n if (node._fsRouteType === 'pathless_layout') {\n // since `node.path` is used as the `id` on the route definition, we need to update it\n node.path = determineNodePath(node)\n }\n\n this.handleNode(parentNode, acc, config)\n } else {\n anchorRoute.children = anchorRoute.children ?? []\n anchorRoute.children.push(node)\n\n node.parent = anchorRoute\n }\n }\n\n if (node.parent) {\n if (!node.isVirtualParentRequired) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n }\n } else {\n acc.routeTree.push(node)\n }\n\n acc.routeNodes.push(node)\n }\n\n // only process files that are relevant for the route tree generation\n private isFileRelevantForRouteTreeGeneration(filePath: string): boolean {\n // the generated route tree file\n if (filePath === this.generatedRouteTreePath) {\n return true\n }\n\n // files inside the routes folder\n if (filePath.startsWith(this.routesDirectoryPath)) {\n return true\n }\n\n // the virtual route config file passed into `virtualRouteConfig`\n if (\n typeof this.config.virtualRouteConfig === 'string' &&\n filePath === this.config.virtualRouteConfig\n ) {\n return true\n }\n\n // this covers all files that are mounted via `virtualRouteConfig` or any `__virtual.ts` files\n if (this.routeNodeCache.has(filePath)) {\n return true\n }\n\n // virtual config files such as`__virtual.ts`\n if (isVirtualConfigFile(path.basename(filePath))) {\n return true\n }\n\n // route files inside directories mounted via `physical()` inside a virtual route config\n if (this.physicalDirectories.some((dir) => filePath.startsWith(dir))) {\n return true\n }\n\n return false\n }\n}\n"],"names":["fsp","logging","getTargetTemplate","existsSync","mkdirSync","virtualGetRouteNodes","physicalGetRouteNodes","rootPathId","multiSortBy","format","getImportForRouteNode","isRouteNodeValidForAugmentation","buildRouteTreeConfig","findParent","replaceBackslash","removeExt","createRouteNodesByFullPath","getResolvedRouteNodeVariableName","createRouteNodesByTo","rootRouteId","createRouteNodesById","buildFileRoutesByPathInterface","checkRouteFullPathUniqueness","mergeImportDeclarations","buildImportString","moduleAugmentation","getImportPath","fillTemplate","transform","checkFileExists","resetRegex","hasParentRoute","determineNodePath","trimPathLeft","removeGroups","removeLeadingUnderscores","removeLayoutSegments","removeUnderscores","removeTrailingSlash","removeLastSegmentFromPath","routePathToVariable","isVirtualConfigFile"],"mappings":"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"}
|
package/dist/cjs/types.d.cts
CHANGED
|
@@ -4,6 +4,7 @@ export type RouteNode = {
|
|
|
4
4
|
variableName: string;
|
|
5
5
|
_fsRouteType: FsRouteType;
|
|
6
6
|
routePath?: string;
|
|
7
|
+
originalRoutePath?: string;
|
|
7
8
|
cleanedPath?: string;
|
|
8
9
|
path?: string;
|
|
9
10
|
isNonPath?: boolean;
|
|
@@ -13,6 +14,7 @@ export type RouteNode = {
|
|
|
13
14
|
children?: Array<RouteNode>;
|
|
14
15
|
parent?: RouteNode;
|
|
15
16
|
createFileRouteProps?: Set<string>;
|
|
17
|
+
_isExperimentalNonNestedRoute?: boolean;
|
|
16
18
|
};
|
|
17
19
|
export interface GetRouteNodesResult {
|
|
18
20
|
rootRouteNode?: RouteNode;
|
package/dist/cjs/utils.cjs
CHANGED
|
@@ -54,7 +54,8 @@ function removeTrailingSlash(s) {
|
|
|
54
54
|
return s.replace(/\/$/, "");
|
|
55
55
|
}
|
|
56
56
|
const BRACKET_CONTENT_RE = /\[(.*?)\]/g;
|
|
57
|
-
|
|
57
|
+
const SPLIT_REGEX = new RegExp("(?<!\\[)\\.(?!\\])", "g");
|
|
58
|
+
function determineInitialRoutePath(routePath, config) {
|
|
58
59
|
const DISALLOWED_ESCAPE_CHARS = /* @__PURE__ */ new Set([
|
|
59
60
|
"/",
|
|
60
61
|
"\\",
|
|
@@ -69,7 +70,23 @@ function determineInitialRoutePath(routePath) {
|
|
|
69
70
|
"$",
|
|
70
71
|
"%"
|
|
71
72
|
]);
|
|
72
|
-
const
|
|
73
|
+
const originalRoutePath = cleanPath(
|
|
74
|
+
`/${(cleanPath(routePath) || "").split(SPLIT_REGEX).join("/")}`
|
|
75
|
+
) || "";
|
|
76
|
+
const isExperimentalNonNestedRoute = isValidNonNestedRoute(
|
|
77
|
+
originalRoutePath,
|
|
78
|
+
config
|
|
79
|
+
);
|
|
80
|
+
let cleanedRoutePath = routePath;
|
|
81
|
+
if (config?.experimental?.nonNestedRoutes) {
|
|
82
|
+
if (originalRoutePath !== `/${rootPathId.rootPathId}`) {
|
|
83
|
+
cleanedRoutePath = removeTrailingUnderscores(
|
|
84
|
+
originalRoutePath,
|
|
85
|
+
config.routeToken
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const parts = cleanedRoutePath.split(SPLIT_REGEX);
|
|
73
90
|
const escapedParts = parts.map((part) => {
|
|
74
91
|
let match;
|
|
75
92
|
while ((match = BRACKET_CONTENT_RE.exec(part)) !== null) {
|
|
@@ -89,7 +106,11 @@ Please remove and/or replace them.`
|
|
|
89
106
|
return part.replace(BRACKET_CONTENT_RE, "$1");
|
|
90
107
|
});
|
|
91
108
|
const final = cleanPath(`/${escapedParts.join("/")}`) || "";
|
|
92
|
-
return
|
|
109
|
+
return {
|
|
110
|
+
routePath: final,
|
|
111
|
+
isExperimentalNonNestedRoute,
|
|
112
|
+
originalRoutePath
|
|
113
|
+
};
|
|
93
114
|
}
|
|
94
115
|
function replaceBackslash(s) {
|
|
95
116
|
return s.replaceAll(/\\/gi, "/");
|
|
@@ -124,6 +145,25 @@ function routePathToVariable(routePath) {
|
|
|
124
145
|
function removeUnderscores(s) {
|
|
125
146
|
return s?.replaceAll(/(^_|_$)/gi, "").replaceAll(/(\/_|_\/)/gi, "/");
|
|
126
147
|
}
|
|
148
|
+
function escapeRegExp(s) {
|
|
149
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
150
|
+
}
|
|
151
|
+
function removeLeadingUnderscores(s, routeToken) {
|
|
152
|
+
if (!s) return s;
|
|
153
|
+
const hasLeadingUnderscore = routeToken[0] === "_";
|
|
154
|
+
const routeTokenToExclude = hasLeadingUnderscore ? routeToken.slice(1) : routeToken;
|
|
155
|
+
const escapedRouteToken = escapeRegExp(routeTokenToExclude);
|
|
156
|
+
const leadingUnderscoreRegex = hasLeadingUnderscore ? new RegExp(`(?<=^|\\/)_(?!${escapedRouteToken})`, "g") : new RegExp(`(?<=^|\\/)_`, "g");
|
|
157
|
+
return s.replaceAll(leadingUnderscoreRegex, "");
|
|
158
|
+
}
|
|
159
|
+
function removeTrailingUnderscores(s, routeToken) {
|
|
160
|
+
if (!s) return s;
|
|
161
|
+
const hasTrailingUnderscore = routeToken.slice(-1) === "_";
|
|
162
|
+
const routeTokenToExclude = hasTrailingUnderscore ? routeToken.slice(0, -1) : routeToken;
|
|
163
|
+
const escapedRouteToken = escapeRegExp(routeTokenToExclude);
|
|
164
|
+
const trailingUnderscoreRegex = hasTrailingUnderscore ? new RegExp(`(?<!${escapedRouteToken})_(?=\\/|$)`, "g") : new RegExp(`_(?=\\/)|_$`, "g");
|
|
165
|
+
return s.replaceAll(trailingUnderscoreRegex, "");
|
|
166
|
+
}
|
|
127
167
|
function capitalize(s) {
|
|
128
168
|
if (typeof s !== "string") return "";
|
|
129
169
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
@@ -177,7 +217,16 @@ function removeLastSegmentFromPath(routePath = "/") {
|
|
|
177
217
|
segments.pop();
|
|
178
218
|
return segments.join("/");
|
|
179
219
|
}
|
|
180
|
-
function hasParentRoute(routes, node, routePathToCheck) {
|
|
220
|
+
function hasParentRoute(routes, node, routePathToCheck, originalRoutePathToCheck) {
|
|
221
|
+
const getNonNestedSegments = (routePath) => {
|
|
222
|
+
const regex = /_(?=\/|$)/g;
|
|
223
|
+
return [...routePath.matchAll(regex)].filter((match) => {
|
|
224
|
+
const beforeStr = routePath.substring(0, match.index);
|
|
225
|
+
const openBrackets = (beforeStr.match(/\[/g) || []).length;
|
|
226
|
+
const closeBrackets = (beforeStr.match(/\]/g) || []).length;
|
|
227
|
+
return openBrackets === closeBrackets;
|
|
228
|
+
}).map((match) => routePath.substring(0, match.index + 1)).reverse();
|
|
229
|
+
};
|
|
181
230
|
if (!routePathToCheck || routePathToCheck === "/") {
|
|
182
231
|
return null;
|
|
183
232
|
}
|
|
@@ -185,7 +234,23 @@ function hasParentRoute(routes, node, routePathToCheck) {
|
|
|
185
234
|
(d) => d.routePath.length * -1,
|
|
186
235
|
(d) => d.variableName
|
|
187
236
|
]).filter((d) => d.routePath !== `/${rootPathId.rootPathId}`);
|
|
188
|
-
|
|
237
|
+
const filteredNodes = node._isExperimentalNonNestedRoute ? [] : [...sortedNodes];
|
|
238
|
+
if (node._isExperimentalNonNestedRoute) {
|
|
239
|
+
const nonNestedSegments = getNonNestedSegments(
|
|
240
|
+
originalRoutePathToCheck ?? ""
|
|
241
|
+
);
|
|
242
|
+
for (const route of sortedNodes) {
|
|
243
|
+
if (route.routePath === "/") continue;
|
|
244
|
+
if (routePathToCheck.startsWith(`${route.routePath}/`) && route._isExperimentalNonNestedRoute && route.routePath !== routePathToCheck) {
|
|
245
|
+
return route;
|
|
246
|
+
}
|
|
247
|
+
if (nonNestedSegments.find((seg) => seg === `${route.routePath}_`) || !(route._fsRouteType === "pathless_layout" || route._fsRouteType === "layout" || route._fsRouteType === "__root")) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
filteredNodes.push(route);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
for (const route of filteredNodes) {
|
|
189
254
|
if (route.routePath === "/") continue;
|
|
190
255
|
if (routePathToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routePathToCheck) {
|
|
191
256
|
return route;
|
|
@@ -194,7 +259,7 @@ function hasParentRoute(routes, node, routePathToCheck) {
|
|
|
194
259
|
const segments = routePathToCheck.split("/");
|
|
195
260
|
segments.pop();
|
|
196
261
|
const parentRoutePath = segments.join("/");
|
|
197
|
-
return hasParentRoute(routes, node, parentRoutePath);
|
|
262
|
+
return hasParentRoute(routes, node, parentRoutePath, originalRoutePathToCheck);
|
|
198
263
|
}
|
|
199
264
|
const getResolvedRouteNodeVariableName = (routeNode) => {
|
|
200
265
|
return routeNode.children?.length ? `${routeNode.variableName}RouteWithChildren` : `${routeNode.variableName}Route`;
|
|
@@ -208,21 +273,24 @@ function isRouteNodeValidForAugmentation(routeNode) {
|
|
|
208
273
|
const inferPath = (routeNode) => {
|
|
209
274
|
return routeNode.cleanedPath === "/" ? routeNode.cleanedPath : routeNode.cleanedPath?.replace(/\/$/, "") ?? "";
|
|
210
275
|
};
|
|
211
|
-
const inferFullPath = (routeNode) => {
|
|
276
|
+
const inferFullPath = (routeNode, config) => {
|
|
212
277
|
const fullPath = removeGroups(
|
|
213
|
-
removeUnderscores(removeLayoutSegments(routeNode.routePath)) ?? ""
|
|
278
|
+
(config?.experimental?.nonNestedRoutes ? removeLayoutSegments(routeNode.routePath) : removeUnderscores(removeLayoutSegments(routeNode.routePath))) ?? ""
|
|
214
279
|
);
|
|
215
280
|
return routeNode.cleanedPath === "/" ? fullPath : fullPath.replace(/\/$/, "");
|
|
216
281
|
};
|
|
217
|
-
const createRouteNodesByFullPath = (routeNodes) => {
|
|
282
|
+
const createRouteNodesByFullPath = (routeNodes, config) => {
|
|
218
283
|
return new Map(
|
|
219
|
-
routeNodes.map((routeNode) => [
|
|
284
|
+
routeNodes.map((routeNode) => [
|
|
285
|
+
inferFullPath(routeNode, config),
|
|
286
|
+
routeNode
|
|
287
|
+
])
|
|
220
288
|
);
|
|
221
289
|
};
|
|
222
|
-
const createRouteNodesByTo = (routeNodes) => {
|
|
290
|
+
const createRouteNodesByTo = (routeNodes, config) => {
|
|
223
291
|
return new Map(
|
|
224
292
|
dedupeBranchesAndIndexRoutes(routeNodes).map((routeNode) => [
|
|
225
|
-
inferTo(routeNode),
|
|
293
|
+
inferTo(routeNode, config),
|
|
226
294
|
routeNode
|
|
227
295
|
])
|
|
228
296
|
);
|
|
@@ -235,8 +303,8 @@ const createRouteNodesById = (routeNodes) => {
|
|
|
235
303
|
})
|
|
236
304
|
);
|
|
237
305
|
};
|
|
238
|
-
const inferTo = (routeNode) => {
|
|
239
|
-
const fullPath = inferFullPath(routeNode);
|
|
306
|
+
const inferTo = (routeNode, config) => {
|
|
307
|
+
const fullPath = inferFullPath(routeNode, config);
|
|
240
308
|
if (fullPath === "/") return fullPath;
|
|
241
309
|
return fullPath.replace(/\/$/, "");
|
|
242
310
|
};
|
|
@@ -260,7 +328,7 @@ function checkUnique(routes, key) {
|
|
|
260
328
|
}
|
|
261
329
|
function checkRouteFullPathUniqueness(_routes, config) {
|
|
262
330
|
const routes = _routes.map((d) => {
|
|
263
|
-
const inferredFullPath = inferFullPath(d);
|
|
331
|
+
const inferredFullPath = inferFullPath(d, config);
|
|
264
332
|
return { ...d, inferredFullPath };
|
|
265
333
|
});
|
|
266
334
|
const conflictingFiles = checkUnique(routes, "inferredFullPath");
|
|
@@ -354,7 +422,7 @@ function buildFileRoutesByPathInterface(opts) {
|
|
|
354
422
|
return `'${filePathId}': {
|
|
355
423
|
id: '${filePathId}'
|
|
356
424
|
path: '${inferPath(routeNode)}'
|
|
357
|
-
fullPath: '${inferFullPath(routeNode)}'
|
|
425
|
+
fullPath: '${inferFullPath(routeNode, opts.config)}'
|
|
358
426
|
preLoaderRoute: ${preloaderRoute}
|
|
359
427
|
parentRoute: typeof ${parent}
|
|
360
428
|
}`;
|
|
@@ -395,6 +463,31 @@ function getImportForRouteNode(node, config, generatedRouteTreePath, root) {
|
|
|
395
463
|
]
|
|
396
464
|
};
|
|
397
465
|
}
|
|
466
|
+
function isValidNonNestedRoute(normalizedRoutePath, config) {
|
|
467
|
+
if (!config?.experimental?.nonNestedRoutes) {
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
const segments = normalizedRoutePath.split("/").filter(Boolean);
|
|
471
|
+
if (segments.length === 0) {
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
const lastRouteSegment = segments[segments.length - 1];
|
|
475
|
+
if (lastRouteSegment === rootPathId.rootPathId) {
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
if (lastRouteSegment !== config.indexToken && lastRouteSegment !== config.routeToken && lastRouteSegment.endsWith("_")) {
|
|
479
|
+
return true;
|
|
480
|
+
}
|
|
481
|
+
for (const segment of segments.slice(0, -1).reverse()) {
|
|
482
|
+
if (segment === config.routeToken) {
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
if (segment.endsWith("_")) {
|
|
486
|
+
return true;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
398
491
|
exports.buildFileRoutesByPathInterface = buildFileRoutesByPathInterface;
|
|
399
492
|
exports.buildImportString = buildImportString;
|
|
400
493
|
exports.buildRouteTreeConfig = buildRouteTreeConfig;
|
|
@@ -418,6 +511,7 @@ exports.inferFullPath = inferFullPath;
|
|
|
418
511
|
exports.inferPath = inferPath;
|
|
419
512
|
exports.inferTo = inferTo;
|
|
420
513
|
exports.isRouteNodeValidForAugmentation = isRouteNodeValidForAugmentation;
|
|
514
|
+
exports.isValidNonNestedRoute = isValidNonNestedRoute;
|
|
421
515
|
exports.mergeImportDeclarations = mergeImportDeclarations;
|
|
422
516
|
exports.multiSortBy = multiSortBy;
|
|
423
517
|
exports.removeExt = removeExt;
|
|
@@ -425,7 +519,9 @@ exports.removeGroups = removeGroups;
|
|
|
425
519
|
exports.removeLastSegmentFromPath = removeLastSegmentFromPath;
|
|
426
520
|
exports.removeLayoutSegments = removeLayoutSegments;
|
|
427
521
|
exports.removeLeadingSlash = removeLeadingSlash;
|
|
522
|
+
exports.removeLeadingUnderscores = removeLeadingUnderscores;
|
|
428
523
|
exports.removeTrailingSlash = removeTrailingSlash;
|
|
524
|
+
exports.removeTrailingUnderscores = removeTrailingUnderscores;
|
|
429
525
|
exports.removeUnderscores = removeUnderscores;
|
|
430
526
|
exports.replaceBackslash = replaceBackslash;
|
|
431
527
|
exports.resetRegex = resetRegex;
|