{"version":3,"file":"generator.cjs","names":[],"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  RoutePrefixMap,\n  buildFileRoutesByPathInterface,\n  buildImportString,\n  buildRouteTreeConfig,\n  checkFileExists,\n  checkRouteFullPathUniqueness,\n  countRoutePathSegments,\n  countSlashSeparatedParts,\n  createRouteNodesByFullPath,\n  createRouteNodesById,\n  createRouteNodesByTo,\n  createTokenRegex,\n  determineNodePath,\n  findParent,\n  format,\n  getImportForRouteNode,\n  getResolvedRouteNodeVariableName,\n  hasParentRoute,\n  isSegmentPathless,\n  mergeImportDeclarations,\n  multiSortBy,\n  removeExt,\n  removeGroups,\n  removeLastSegmentFromPath,\n  removeLayoutSegmentsAndUnderscoresWithEscape,\n  removeTrailingSlash,\n  replaceBackslash,\n  trimPathLeft,\n} from './utils'\nimport { fillTemplate, getTargetTemplate } from './template'\nimport { transform } from './transform/transform'\nimport { validateRouteParams } from './validate-route-params'\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  RoutePathSegmentMetadata,\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\nfunction getRoutePathSegmentMetadataForPath(\n  node: RouteNode,\n  routePath: string,\n  parentRoutePath?: string,\n): Array<RoutePathSegmentMetadata | undefined> | undefined {\n  if (!node._routePathSegmentMetadata) return undefined\n\n  const segments = routePath.split('/')\n  const result = new Array<RoutePathSegmentMetadata | undefined>(\n    segments.length,\n  )\n  const parentSegmentCount = countRoutePathSegments(parentRoutePath)\n  let hasMetadata = false\n  let segmentCount = 0\n\n  for (let i = 0; i < segments.length; i++) {\n    if (!segments[i]) continue\n    const sourceIndex = parentSegmentCount + segmentCount + 1\n    result[i] = node._routePathSegmentMetadata[sourceIndex]\n    hasMetadata ||= !!result[i]\n    segmentCount++\n  }\n\n  return hasMetadata ? result : undefined\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 = /\\(.+\\)/\n  private physicalDirectories: Array<string> = []\n\n  /**\n   * Token regexes are pre-compiled once here and reused throughout route processing.\n   * We need TWO types of regex for each token because they match against different inputs:\n   *\n   * 1. FILENAME regexes: Match token patterns within full file path strings.\n   *    Example: For file \"routes/dashboard.index.tsx\", we want to detect \".index.\"\n   *    Pattern: `[./](?:token)[.]` - matches token bounded by path separators/dots\n   *    Used in: sorting route nodes by file path\n   *\n   * 2. SEGMENT regexes: Match token against a single logical route segment.\n   *    Example: For segment \"index\" (extracted from path), match the whole segment\n   *    Pattern: `^(?:token)$` - matches entire segment exactly\n   *    Used in: route parsing, determining route types, escape detection\n   *\n   * We cannot reuse one for the other without false positives or missing matches.\n   */\n  private indexTokenFilenameRegex: RegExp\n  private routeTokenFilenameRegex: RegExp\n  private indexTokenSegmentRegex: RegExp\n  private routeTokenSegmentRegex: RegExp\n  private static componentPieceRegex =\n    /[./](component|errorComponent|notFoundComponent|pendingComponent|loader|lazy)[.]/\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    // Create all token regexes once in constructor\n    this.indexTokenFilenameRegex = createTokenRegex(this.config.indexToken, {\n      type: 'filename',\n    })\n    this.routeTokenFilenameRegex = createTokenRegex(this.config.routeToken, {\n      type: 'filename',\n    })\n    this.indexTokenSegmentRegex = createTokenRegex(this.config.indexToken, {\n      type: 'segment',\n    })\n    this.routeTokenSegmentRegex = createTokenRegex(this.config.routeToken, {\n      type: 'segment',\n    })\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        { routeId: 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        indexTokenSegmentRegex: this.indexTokenSegmentRegex,\n        routeTokenSegmentRegex: this.routeTokenSegmentRegex,\n      })\n    } else {\n      getRouteNodesResult = await physicalGetRouteNodes(\n        this.config,\n        this.root,\n        {\n          indexTokenSegmentRegex: this.indexTokenSegmentRegex,\n          routeTokenSegmentRegex: this.routeTokenSegmentRegex,\n        },\n      )\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) =>\n        d.routePath === undefined\n          ? undefined\n          : countSlashSeparatedParts(d.routePath),\n      (d) => (d.filePath.match(this.indexTokenFilenameRegex) ? 1 : -1),\n      (d) => (d.filePath.match(Generator.componentPieceRegex) ? 1 : -1),\n      (d) => (d.filePath.match(this.routeTokenFilenameRegex) ? -1 : 1),\n      (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n      (d) => d.routePath,\n    ]).filter((d) => {\n      // Exclude the root route itself, but keep component/loader pieces for the root\n      if (d.routePath === `/${rootPathId}`) {\n        return [\n          'component',\n          'errorComponent',\n          'notFoundComponent',\n          'pendingComponent',\n          'loader',\n          'lazy',\n        ].includes(d._fsRouteType)\n      }\n      return true\n    })\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      routeNodesByPath: new Map(),\n    }\n\n    const prefixMap = new RoutePrefixMap(routeFileResult)\n\n    for (const node of routeFileResult) {\n      Generator.handleNode(node, acc, prefixMap, 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 (this.routeTreeFileCache.fileContent === routeTreeContent) {\n        // existing route tree file is already up-to-date, don't write it.\n        // When 'force' was set because an external change was detected,\n        // we still re-read and re-check here, but if the generated content\n        // matches we skip the write to avoid triggering another watcher cycle.\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    // Use pre-compiled regex if config hasn't been overridden, otherwise create new one\n    const indexTokenSegmentRegex =\n      config.indexToken === this.config.indexToken\n        ? this.indexTokenSegmentRegex\n        : createTokenRegex(config.indexToken, { type: 'segment' })\n\n    const sortedRouteNodes = multiSortBy(acc.routeNodes, [\n      (d) => (d.routePath?.includes(`/${rootPathId}`) ? -1 : 1),\n      (d) =>\n        d.routePath === undefined\n          ? undefined\n          : countSlashSeparatedParts(d.routePath),\n      (d) => {\n        const segments = d.routePath?.split('/').filter(Boolean) ?? []\n        const last = segments[segments.length - 1] ?? ''\n        return indexTokenSegmentRegex.test(last) ? -1 : 1\n      },\n      (d) => d,\n    ])\n\n    const routeImports: Array<ImportDeclaration> = []\n    const virtualRouteNodes: Array<string> = []\n\n    for (const node of sortedRouteNodes) {\n      if (node.isVirtual) {\n        virtualRouteNodes.push(\n          `const ${node.variableName}RouteImport = createFileRoute('${node.routePath}')()`,\n        )\n      } else {\n        routeImports.push(\n          getImportForRouteNode(\n            node,\n            config,\n            this.generatedRouteTreePath,\n            this.root,\n          ),\n        )\n      }\n    }\n\n    const imports: Array<ImportDeclaration> = []\n    if (virtualRouteNodes.length > 0) {\n      imports.push({\n        specifiers: [{ imported: 'createFileRoute' }],\n        source: this.targetTemplate.fullPkg,\n      })\n    }\n    // Add lazyRouteComponent import if there are component pieces\n    let hasComponentPieces = false\n    let hasLoaderPieces = false\n    for (const node of sortedRouteNodes) {\n      const pieces = acc.routePiecesByPath[node.routePath!]\n      if (pieces) {\n        if (\n          pieces.component ||\n          pieces.errorComponent ||\n          pieces.notFoundComponent ||\n          pieces.pendingComponent\n        ) {\n          hasComponentPieces = true\n        }\n        if (pieces.loader) {\n          hasLoaderPieces = true\n        }\n        if (hasComponentPieces && hasLoaderPieces) break\n      }\n    }\n    if (hasComponentPieces || hasLoaderPieces) {\n      const runtimeImport: ImportDeclaration = {\n        specifiers: [],\n        source: this.targetTemplate.fullPkg,\n      }\n      if (hasComponentPieces) {\n        runtimeImport.specifiers.push({ imported: 'lazyRouteComponent' })\n      }\n      if (hasLoaderPieces) {\n        runtimeImport.specifiers.push({ imported: 'lazyFn' })\n      }\n      imports.push(runtimeImport)\n    }\n    const routeTreeConfig = buildRouteTreeConfig(\n      acc.routeTree,\n      config.disableTypes,\n    )\n\n    const createUpdateRoutes = sortedRouteNodes.map((node) => {\n      const pieces = acc.routePiecesByPath[node.routePath!]\n      const loaderNode = pieces?.loader\n      const componentNode = pieces?.component\n      const errorComponentNode = pieces?.errorComponent\n      const notFoundComponentNode = pieces?.notFoundComponent\n      const pendingComponentNode = pieces?.pendingComponent\n      const lazyComponentNode = pieces?.lazy\n\n      return [\n        [\n          `const ${node.variableName}Route = ${node.variableName}RouteImport.update({\n            ${[\n              `id: '${node.path}'`,\n              !node.isNonPath ||\n              (node._fsRouteType === 'pathless_layout' && node.cleanedPath)\n                ? `path: '${node.cleanedPath}'`\n                : 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 ||\n          errorComponentNode ||\n          notFoundComponentNode ||\n          pendingComponentNode\n            ? `.update({\n                ${(\n                  [\n                    ['component', componentNode],\n                    ['errorComponent', errorComponentNode],\n                    ['notFoundComponent', notFoundComponentNode],\n                    ['pendingComponent', pendingComponentNode],\n                  ] as const\n                )\n                  .filter((d) => d[1])\n                  .map((d) => {\n                    // For .vue files, use 'default' as the export name since Vue SFCs export default\n                    const isVueFile = d[1]!.filePath.endsWith('.vue')\n                    const exportName = isVueFile ? 'default' : d[0]\n                    // Keep .vue extension for Vue files since Vite requires it\n                    const importPath = replaceBackslash(\n                      isVueFile\n                        ? path.relative(\n                            path.dirname(config.generatedRouteTree),\n                            path.resolve(\n                              config.routesDirectory,\n                              d[1]!.filePath,\n                            ),\n                          )\n                        : removeExt(\n                            path.relative(\n                              path.dirname(config.generatedRouteTree),\n                              path.resolve(\n                                config.routesDirectory,\n                                d[1]!.filePath,\n                              ),\n                            ),\n                            config.addExtensions,\n                          ),\n                    )\n                    return `${\n                      d[0]\n                    }: lazyRouteComponent(() => import('./${importPath}'), '${exportName}')`\n                  })\n                  .join('\\n,')}\n              })`\n            : '',\n          lazyComponentNode\n            ? (() => {\n                // For .vue files, use 'default' export since Vue SFCs export default\n                const isVueFile = lazyComponentNode.filePath.endsWith('.vue')\n                const exportAccessor = isVueFile ? 'd.default' : 'd.Route'\n                // Keep .vue extension for Vue files since Vite requires it\n                const importPath = replaceBackslash(\n                  isVueFile\n                    ? path.relative(\n                        path.dirname(config.generatedRouteTree),\n                        path.resolve(\n                          config.routesDirectory,\n                          lazyComponentNode.filePath,\n                        ),\n                      )\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                )\n                return `.lazy(() => import('./${importPath}').then((d) => ${exportAccessor}))`\n              })()\n            : '',\n        ].join(''),\n      ].join('\\n\\n')\n    })\n\n    // Generate update for root route if it has component pieces\n    const rootRoutePath = `/${rootPathId}`\n    const rootPieces = acc.routePiecesByPath[rootRoutePath]\n    const rootComponentNode = rootPieces?.component\n    const rootErrorComponentNode = rootPieces?.errorComponent\n    const rootNotFoundComponentNode = rootPieces?.notFoundComponent\n    const rootPendingComponentNode = rootPieces?.pendingComponent\n\n    let rootRouteUpdate = ''\n    if (\n      rootComponentNode ||\n      rootErrorComponentNode ||\n      rootNotFoundComponentNode ||\n      rootPendingComponentNode\n    ) {\n      rootRouteUpdate = `const rootRouteWithChildren = rootRouteImport${\n        rootComponentNode ||\n        rootErrorComponentNode ||\n        rootNotFoundComponentNode ||\n        rootPendingComponentNode\n          ? `.update({\n              ${(\n                [\n                  ['component', rootComponentNode],\n                  ['errorComponent', rootErrorComponentNode],\n                  ['notFoundComponent', rootNotFoundComponentNode],\n                  ['pendingComponent', rootPendingComponentNode],\n                ] as const\n              )\n                .filter((d) => d[1])\n                .map((d) => {\n                  // For .vue files, use 'default' as the export name since Vue SFCs export default\n                  const isVueFile = d[1]!.filePath.endsWith('.vue')\n                  const exportName = isVueFile ? 'default' : d[0]\n                  // Keep .vue extension for Vue files since Vite requires it\n                  const importPath = replaceBackslash(\n                    isVueFile\n                      ? path.relative(\n                          path.dirname(config.generatedRouteTree),\n                          path.resolve(config.routesDirectory, d[1]!.filePath),\n                        )\n                      : removeExt(\n                          path.relative(\n                            path.dirname(config.generatedRouteTree),\n                            path.resolve(\n                              config.routesDirectory,\n                              d[1]!.filePath,\n                            ),\n                          ),\n                          config.addExtensions,\n                        ),\n                  )\n                  return `${d[0]}: lazyRouteComponent(() => import('./${importPath}'), '${exportName}')`\n                })\n                .join('\\n,')}\n            })`\n          : ''\n      }._addFileChildren(rootRouteChildren)${config.disableTypes ? '' : `._addFileTypes<FileRouteTypes>()`}`\n    }\n\n    let fileRoutesByPathInterface = ''\n    let fileRoutesByFullPath = ''\n\n    if (!config.disableTypes) {\n      const routeNodesByFullPath = createRouteNodesByFullPath(acc.routeNodes)\n      const routeNodesByTo = createRouteNodesByTo(acc.routeNodes)\n      const routeNodesById = createRouteNodesById(acc.routeNodes)\n\n      fileRoutesByFullPath = [\n        `export interface FileRoutesByFullPath {\n${[...routeNodesByFullPath.entries()]\n  .filter(([fullPath]) => fullPath)\n  .map(([fullPath, routeNode]) => {\n    return `'${fullPath}': typeof ${getResolvedRouteNodeVariableName(routeNode)}`\n  })}\n}`,\n        `export interface FileRoutesByTo {\n${[...routeNodesByTo.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${[...routeNodesById.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            ? [...routeNodesByFullPath.keys()]\n                .filter((fullPath) => fullPath)\n                .map((fullPath) => `'${fullPath}'`)\n                .join('|')\n            : 'never'\n        }\nfileRoutesByTo: FileRoutesByTo\nto: ${\n          acc.routeNodes.length > 0\n            ? [...routeNodesByTo.keys()]\n                .filter((to) => to)\n                .map((to) => `'${to}'`)\n                .join('|')\n            : 'never'\n        }\nid: ${[`'${rootRouteId}'`, ...[...routeNodesById.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      rootRouteUpdate\n        ? rootRouteUpdate.replace(\n            'const rootRouteWithChildren = ',\n            'export const routeTree = ',\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    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      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    if (node.routePath) {\n      validateRouteParams(node.routePath, node.filePath, this.logger)\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            'notFoundComponent',\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\n    // Check if this is a Vue component file\n    // Vue SFC files (.vue) don't need transformation as they can't have a Route export\n    const isVueFile = node.filePath.endsWith('.vue')\n\n    if (!isVueFile) {\n      // transform the file\n      const transformResult = await transform({\n        source: updatedCacheEntry.fileContent,\n        filename: node.fullPath,\n        ctx: {\n          target: this.config.target,\n          routeId: escapedRoutePath,\n          lazy: node._fsRouteType === 'lazy',\n        },\n        node,\n      })\n\n      if (transformResult.result === 'no-route-export') {\n        const fileName = path.basename(node.fullPath)\n        const dirName = path.dirname(node.fullPath)\n        const ignorePrefix = this.config.routeFileIgnorePrefix\n        const ignorePattern = this.config.routeFileIgnorePattern\n        const suggestedFileName = `${ignorePrefix}${fileName}`\n        const suggestedFullPath = path.join(dirName, suggestedFileName)\n\n        let message = `Warning: Route file \"${node.fullPath}\" does not export a Route. This file will not be included in the route tree.`\n        message += `\\n\\nIf this file is not intended to be a route, you can exclude it using one of these options:`\n        message += `\\n  1. Rename the file to \"${suggestedFullPath}\" (prefix with \"${ignorePrefix}\")`\n        message += `\\n  2. Use 'routeFileIgnorePattern' in your config to match this file`\n        message += `\\n\\nCurrent configuration:`\n        message += `\\n  routeFileIgnorePrefix: \"${ignorePrefix}\"`\n        message += `\\n  routeFileIgnorePattern: ${ignorePattern ? `\"${ignorePattern}\"` : 'undefined'}`\n\n        this.logger.warn(message)\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\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    await this.fs.rename(tmpPath, opts.filePath)\n\n    // stat the target file AFTER rename so the cached mtime matches\n    // what the filesystem reports for the actual file path.\n    // Previously we stat'd the temp file before rename, but rename()\n    // can assign a different mtime to the target on some filesystems,\n    // causing the cache to be permanently stale.\n    const stat = await this.fs.stat(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    prefixMap: RoutePrefixMap,\n    config?: Config,\n  ) {\n    let parentRoute = hasParentRoute(prefixMap, node, node.routePath)\n\n    // Check routeNodesByPath for a closer parent that may not be in prefixMap.\n    //\n    // Why: The prefixMap excludes lazy routes by design. When lazy-only routes are\n    // nested inside a pathless layout, the virtual route created from the lazy file\n    // won't be in the prefixMap, but it will be in routeNodesByPath.\n    //\n    // Example: Given files _layout/path.lazy.tsx and _layout/path.index.lazy.tsx:\n    //   - prefixMap contains: /_layout (from route.tsx)\n    //   - routeNodesByPath contains: /_layout AND /_layout/path (virtual from lazy)\n    //   - For /_layout/path/, hasParentRoute returns /_layout (wrong)\n    //   - But the correct parent is /_layout/path (the virtual route from path.lazy.tsx)\n    //\n    // We walk up the path segments to find the closest registered parent. This handles\n    // cases where multiple path segments (e.g., $a/$b) don't have intermediate routes.\n    if (node.routePath) {\n      let searchPath = node.routePath\n      while (searchPath.length > 0) {\n        const lastSlash = searchPath.lastIndexOf('/')\n        if (lastSlash <= 0) break\n\n        searchPath = searchPath.substring(0, lastSlash)\n        const candidate = acc.routeNodesByPath.get(searchPath)\n        if (candidate && candidate.routePath !== node.routePath) {\n          // Found a parent in routeNodesByPath\n          // If it's different from what prefixMap found AND is a closer match, use it\n          if (candidate !== parentRoute) {\n            // Check if this candidate is a closer parent than what prefixMap found\n            // (longer path prefix means closer parent)\n            if (\n              !parentRoute ||\n              (candidate.routePath?.length ?? 0) >\n                (parentRoute.routePath?.length ?? 0)\n            ) {\n              parentRoute = candidate\n            }\n          }\n          break\n        }\n      }\n    }\n\n    // Virtual routes may have an explicit parent from virtual config.\n    // If we can find that exact parent, use it to prevent auto-nesting siblings\n    // based on path prefix matching (#5822, #5431).\n    if (node._virtualParentRoutePath !== undefined) {\n      const explicitParent = acc.routeNodesByPath.get(\n        node._virtualParentRoutePath,\n      )\n      if (explicitParent) {\n        parentRoute = explicitParent\n      } else if (node._virtualParentRoutePath === `/${rootPathId}`) {\n        // The explicit parent is the root route (handled separately).\n        // Override path-based inference so this node stays at root level.\n        parentRoute = null\n      }\n      // Otherwise the explicit parent was a virtual file-less route that got\n      // filtered out. Fall back to the path-based parentRoute already computed.\n    }\n\n    if (parentRoute) node.parent = parentRoute\n\n    node.path = determineNodePath(node)\n\n    const trimmedPath = trimPathLeft(node.path ?? '')\n    const originalPath =\n      node.originalRoutePath && node.parent?.originalRoutePath\n        ? node.originalRoutePath.replace(node.parent.originalRoutePath, '') ||\n          '/'\n        : node.originalRoutePath\n    const routePathSegmentMetadata = getRoutePathSegmentMetadataForPath(\n      node,\n      node.path ?? '/',\n      node.parent?.routePath,\n    )\n    const trimmedOriginalPath = trimPathLeft(originalPath ?? '')\n\n    const split = trimmedPath.split('/')\n    const pathSplit = (node.path ?? '').split('/')\n    const originalSplit = trimmedOriginalPath.split('/')\n    const lastRouteSegment = split[split.length - 1] ?? trimmedPath\n    const lastOriginalSegment =\n      originalSplit[originalSplit.length - 1] ?? trimmedOriginalPath\n    const lastRouteSegmentMetadata =\n      routePathSegmentMetadata?.[pathSplit.length - 1]\n\n    // A segment is non-path if it starts with underscore AND the underscore is not escaped\n    node.isNonPath =\n      (!lastRouteSegmentMetadata?.literalLeadingUnderscore &&\n        isSegmentPathless(lastRouteSegment, lastOriginalSegment)) ||\n      split.every((part) => this.routeGroupPatternRegex.test(part))\n\n    // Use a single pass so layout removal does not desync escaped underscore checks.\n    node.cleanedPath = removeGroups(\n      removeLayoutSegmentsAndUnderscoresWithEscape(\n        node.path,\n        originalPath,\n        routePathSegmentMetadata,\n      ),\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          'notFoundComponent',\n        ] satisfies Array<FsRouteType>\n      ).some((d) => d === node._fsRouteType)\n    ) {\n      acc.routePiecesByPath[node.routePath!] =\n        acc.routePiecesByPath[node.routePath!] || {}\n\n      const pieceKey =\n        node._fsRouteType === 'lazy'\n          ? 'lazy'\n          : (node._fsRouteType as keyof (typeof acc.routePiecesByPath)[string])\n      acc.routePiecesByPath[node.routePath!]![pieceKey] = node\n\n      const anchorRoute = acc.routeNodesByPath.get(node.routePath!)\n\n      // Don't create virtual routes for root route component pieces - the root route is handled separately\n      if (!anchorRoute && node.routePath !== `/${rootPathId}`) {\n        this.handleNode(\n          {\n            ...node,\n            isVirtual: true,\n            _fsRouteType: 'static',\n          },\n          acc,\n          prefixMap,\n          config,\n        )\n      }\n      return\n    }\n\n    const isPathlessLayoutWithPath =\n      node._fsRouteType === 'pathless_layout' &&\n      node.cleanedPath &&\n      node.cleanedPath.length > 0\n\n    // Special handling: pathless layouts with path need to find real ancestor\n    if (!node.isVirtual && isPathlessLayoutWithPath) {\n      const immediateParentPath =\n        removeLastSegmentFromPath(node.routePath) || '/'\n      const immediateParentOriginalPath =\n        removeLastSegmentFromPath(node.originalRoutePath) || '/'\n      let searchPath = immediateParentPath\n\n      // Find nearest real (non-virtual, non-index) parent\n      while (searchPath) {\n        const candidate = acc.routeNodesByPath.get(searchPath)\n        if (candidate && !candidate.isVirtual && candidate.path !== '/') {\n          node.parent = candidate\n          node.path =\n            node.routePath?.replace(candidate.routePath ?? '', '') || '/'\n          const pathRelativeToParent =\n            immediateParentPath.replace(candidate.routePath ?? '', '') || '/'\n          const originalPathRelativeToParent =\n            immediateParentOriginalPath.replace(\n              candidate.originalRoutePath ?? '',\n              '',\n            ) || '/'\n          const routePathSegmentMetadataRelativeToParent =\n            getRoutePathSegmentMetadataForPath(\n              node,\n              pathRelativeToParent,\n              candidate.routePath,\n            )\n          node.cleanedPath = removeGroups(\n            removeLayoutSegmentsAndUnderscoresWithEscape(\n              pathRelativeToParent,\n              originalPathRelativeToParent,\n              routePathSegmentMetadataRelativeToParent,\n            ),\n          )\n          break\n        }\n        if (searchPath === '/') break\n        searchPath = removeLastSegmentFromPath(searchPath) || '/'\n      }\n    }\n\n    // Add to parent's children or to root\n    if (node.parent) {\n      node.parent.children = node.parent.children ?? []\n      node.parent.children.push(node)\n    } else {\n      acc.routeTree.push(node)\n    }\n\n    acc.routeNodes.push(node)\n    if (node.routePath) {\n      // Always register routes by path so child routes can find parents.\n      // Virtual routes (created from lazy-only files) also need to be registered\n      // so that index routes like path.index.lazy.tsx can find their parent path.lazy.tsx.\n      // If a non-virtual route is later processed for the same path, it will overwrite.\n      acc.routeNodesByPath.set(node.routePath, node)\n    }\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"],"mappings":"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"}