{"version":3,"file":"utils.cjs","names":[],"sources":["../../src/utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/prefer-for-of */\nimport * as fsp from 'node:fs/promises'\nimport path from 'node:path'\nimport * as prettier from 'prettier'\nimport { rootPathId } from './filesystem/physical/rootPathId'\nimport type { Config, TokenMatcher } from './config'\nimport type {\n  ImportDeclaration,\n  RouteNode,\n  RoutePathSegmentMetadata,\n} from './types'\n\n/**\n * Prefix map for O(1) parent route lookups.\n * Maps each route path prefix to the route node that owns that prefix.\n * Enables finding longest matching parent without linear search.\n */\nexport class RoutePrefixMap {\n  private prefixToRoute: Map<string, RouteNode> = new Map()\n\n  constructor(routes: Array<RouteNode>) {\n    for (const route of routes) {\n      if (!route.routePath || route.routePath === `/${rootPathId}`) continue\n\n      // Skip route pieces (lazy, loader, component, etc.) - they are merged with main routes\n      // and should not be valid parent candidates\n      if (\n        route._fsRouteType === 'lazy' ||\n        route._fsRouteType === 'loader' ||\n        route._fsRouteType === 'component' ||\n        route._fsRouteType === 'pendingComponent' ||\n        route._fsRouteType === 'errorComponent' ||\n        route._fsRouteType === 'notFoundComponent'\n      ) {\n        continue\n      }\n\n      // Index by exact path for direct lookups\n      this.prefixToRoute.set(route.routePath, route)\n    }\n  }\n\n  /**\n   * Find the longest matching parent route for a given path.\n   * O(k) where k is the number of path segments, not O(n) routes.\n   */\n  findParent(routePath: string): RouteNode | null {\n    if (!routePath || routePath === '/') return null\n\n    // Walk up the path segments\n    let searchPath = 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 parent = this.prefixToRoute.get(searchPath)\n      if (parent && parent.routePath !== routePath) {\n        return parent\n      }\n    }\n    return null\n  }\n\n  /**\n   * Check if a route exists at the given path.\n   */\n  has(routePath: string): boolean {\n    return this.prefixToRoute.has(routePath)\n  }\n\n  /**\n   * Get a route by exact path.\n   */\n  get(routePath: string): RouteNode | undefined {\n    return this.prefixToRoute.get(routePath)\n  }\n}\n\nexport function multiSortBy<T>(\n  arr: Array<T>,\n  accessors: Array<(item: T) => any> = [(d) => d],\n): Array<T> {\n  const len = arr.length\n  // Pre-compute all accessor values to avoid repeated function calls during sort\n  const indexed: Array<{ item: T; index: number; keys: Array<any> }> =\n    new Array(len)\n  for (let i = 0; i < len; i++) {\n    const item = arr[i]!\n    const keys = new Array(accessors.length)\n    for (let j = 0; j < accessors.length; j++) {\n      keys[j] = accessors[j]!(item)\n    }\n    indexed[i] = { item, index: i, keys }\n  }\n\n  indexed.sort((a, b) => {\n    for (let j = 0; j < accessors.length; j++) {\n      const ao = a.keys[j]\n      const bo = b.keys[j]\n\n      if (typeof ao === 'undefined') {\n        if (typeof bo === 'undefined') {\n          continue\n        }\n        return 1\n      }\n\n      if (ao === bo) {\n        continue\n      }\n\n      return ao > bo ? 1 : -1\n    }\n\n    return a.index - b.index\n  })\n\n  const result: Array<T> = new Array(len)\n  for (let i = 0; i < len; i++) {\n    result[i] = indexed[i]!.item\n  }\n  return result\n}\n\nexport function cleanPath(path: string) {\n  // remove double slashes\n  return path.replace(/\\/{2,}/g, '/')\n}\n\nexport function trimPathLeft(path: string) {\n  return path === '/' ? path : path.replace(/^\\/{1,}/, '')\n}\n\nexport function removeLeadingSlash(path: string): string {\n  return path.replace(/^\\//, '')\n}\n\nexport function removeTrailingSlash(s: string) {\n  return s.replace(/\\/$/, '')\n}\n\nconst BRACKET_CONTENT_RE = /\\[(.*?)\\]/g\nconst SPLIT_REGEX = /(?<!\\[)\\.(?!\\])/g\n\n/**\n * Characters that cannot be escaped in square brackets.\n * These are characters that would cause issues in URLs or file systems.\n */\nconst DISALLOWED_ESCAPE_CHARS = new Set([\n  '/',\n  '\\\\',\n  '?',\n  '#',\n  ':',\n  '*',\n  '<',\n  '>',\n  '|',\n  '!',\n  '$',\n  '%',\n])\n\nexport function determineInitialRoutePath(routePath: string) {\n  const originalRoutePath =\n    cleanPath(\n      `/${(cleanPath(routePath) || '').split(SPLIT_REGEX).join('/')}`,\n    ) || ''\n\n  const parts = routePath.split(SPLIT_REGEX)\n\n  // Escape any characters that in square brackets\n  // we keep the original path untouched\n  const escapedParts = parts.map((part) => {\n    // Check if any disallowed characters are used in brackets\n\n    let match\n    while ((match = BRACKET_CONTENT_RE.exec(part)) !== null) {\n      const character = match[1]\n      if (character === undefined) continue\n      if (DISALLOWED_ESCAPE_CHARS.has(character)) {\n        console.error(\n          `Error: Disallowed character \"${character}\" found in square brackets in route path \"${routePath}\".\\nYou cannot use any of the following characters in square brackets: ${Array.from(\n            DISALLOWED_ESCAPE_CHARS,\n          ).join(', ')}\\nPlease remove and/or replace them.`,\n        )\n        process.exit(1)\n      }\n    }\n\n    // Since this split segment is safe at this point, we can\n    // remove the brackets and replace them with the content inside\n    return part.replace(BRACKET_CONTENT_RE, '$1')\n  })\n\n  // If the syntax for prefix/suffix is different, from the path\n  // matching internals of router-core, we'd perform those changes here\n  // on the `escapedParts` array before it is joined back together in\n  // `final`\n\n  const final = cleanPath(`/${escapedParts.join('/')}`) || ''\n\n  return {\n    routePath: final,\n    originalRoutePath,\n  }\n}\n\n/**\n * Checks if a segment is fully escaped (entirely wrapped in brackets with no nested brackets).\n * E.g., \"[index]\" -> true, \"[_layout]\" -> true, \"foo[.]bar\" -> false, \"index\" -> false\n */\nfunction isFullyEscapedSegment(originalSegment: string): boolean {\n  return (\n    originalSegment.startsWith('[') &&\n    originalSegment.endsWith(']') &&\n    !originalSegment.slice(1, -1).includes('[') &&\n    !originalSegment.slice(1, -1).includes(']')\n  )\n}\n\n/**\n * Checks if the leading underscore in a segment is escaped.\n * Returns true if:\n * - Segment starts with [_] pattern: \"[_]layout\" -> \"_layout\"\n * - Segment is fully escaped and content starts with _: \"[_1nd3x]\" -> \"_1nd3x\"\n */\nexport function hasEscapedLeadingUnderscore(originalSegment: string): boolean {\n  // Pattern: [_]something or [_something]\n  return (\n    originalSegment.startsWith('[_]') ||\n    (originalSegment.startsWith('[_') && isFullyEscapedSegment(originalSegment))\n  )\n}\n\n/**\n * Checks if the trailing underscore in a segment is escaped.\n * Returns true if:\n * - Segment ends with [_] pattern: \"blog[_]\" -> \"blog_\"\n * - Segment is fully escaped and content ends with _: \"[_r0ut3_]\" -> \"_r0ut3_\"\n */\nexport function hasEscapedTrailingUnderscore(originalSegment: string): boolean {\n  // Pattern: something[_] or [something_]\n  return (\n    originalSegment.endsWith('[_]') ||\n    (originalSegment.endsWith('_]') && isFullyEscapedSegment(originalSegment))\n  )\n}\n\nexport function countRoutePathSegments(routePath?: string): number {\n  const path = routePath ?? ''\n  let count = 0\n  let inSegment = false\n\n  for (let i = 0; i < path.length; i++) {\n    if (path[i] === '/') {\n      inSegment = false\n      continue\n    }\n\n    if (!inSegment) {\n      count++\n      inSegment = true\n    }\n  }\n\n  return count\n}\n\nexport function countSlashSeparatedParts(path: string): number {\n  let count = 1\n\n  for (let i = 0; i < path.length; i++) {\n    if (path[i] === '/') count++\n  }\n\n  return count\n}\n\nexport function hasRoutePathSegmentMetadata(\n  metadata: RoutePathSegmentMetadata | undefined,\n): metadata is RoutePathSegmentMetadata {\n  return !!(\n    metadata?.literalLeadingUnderscore || metadata?.literalTrailingUnderscore\n  )\n}\n\nfunction mergeRoutePathSegmentMetadata(\n  current: RoutePathSegmentMetadata | undefined,\n  incoming: RoutePathSegmentMetadata | undefined,\n): RoutePathSegmentMetadata | undefined {\n  const hasCurrent = hasRoutePathSegmentMetadata(current)\n  const hasIncoming = hasRoutePathSegmentMetadata(incoming)\n\n  if (!hasCurrent) return hasIncoming ? incoming : undefined\n  if (!hasIncoming) return current\n\n  return {\n    literalLeadingUnderscore:\n      current.literalLeadingUnderscore || incoming.literalLeadingUnderscore,\n    literalTrailingUnderscore:\n      current.literalTrailingUnderscore || incoming.literalTrailingUnderscore,\n  }\n}\n\nexport function createRoutePathSegmentMetadata(\n  routePath: string = '/',\n  originalPath?: string,\n): Array<RoutePathSegmentMetadata | undefined> | undefined {\n  if (!originalPath) return undefined\n\n  const routeSegments = routePath.split('/')\n  const originalSegments = originalPath.split('/')\n  const metadata = new Array<RoutePathSegmentMetadata | undefined>(\n    routeSegments.length,\n  )\n  let hasMetadata = false\n\n  for (let i = 0; i < routeSegments.length; i++) {\n    const segment = routeSegments[i]!\n    const originalSegment = originalSegments[i] || ''\n    const literalLeadingUnderscore =\n      segment.startsWith('_') && hasEscapedLeadingUnderscore(originalSegment)\n    const literalTrailingUnderscore =\n      segment.endsWith('_') && hasEscapedTrailingUnderscore(originalSegment)\n\n    if (!literalLeadingUnderscore && !literalTrailingUnderscore) continue\n\n    hasMetadata = true\n    metadata[i] = {\n      literalLeadingUnderscore: literalLeadingUnderscore || undefined,\n      literalTrailingUnderscore: literalTrailingUnderscore || undefined,\n    }\n  }\n\n  return hasMetadata ? metadata : undefined\n}\n\nexport function createLiteralRoutePathSegmentMetadata(\n  routePath: string,\n  parent?: RouteNode,\n  literalNewSegments = false,\n): Array<RoutePathSegmentMetadata | undefined> | undefined {\n  const routeSegments = routePath.split('/')\n  const metadata = new Array<RoutePathSegmentMetadata | undefined>(\n    routeSegments.length,\n  )\n  const parentDepth = countRoutePathSegments(parent?.routePath)\n  let hasMetadata = false\n  let depth = 0\n\n  for (let i = 0; i < routeSegments.length; i++) {\n    const segment = routeSegments[i]\n    metadata[i] = parent?._routePathSegmentMetadata?.[i]\n    hasMetadata ||= hasRoutePathSegmentMetadata(metadata[i])\n\n    if (!segment) continue\n\n    if (literalNewSegments && depth >= parentDepth) {\n      const literalLeadingUnderscore = segment.startsWith('_')\n      const literalTrailingUnderscore = segment.endsWith('_')\n\n      if (literalLeadingUnderscore || literalTrailingUnderscore) {\n        metadata[i] = mergeRoutePathSegmentMetadata(metadata[i], {\n          literalLeadingUnderscore: literalLeadingUnderscore || undefined,\n          literalTrailingUnderscore: literalTrailingUnderscore || undefined,\n        })\n        hasMetadata = true\n      }\n    }\n\n    depth++\n  }\n\n  return hasMetadata ? metadata : undefined\n}\n\nexport function joinRoutePathSegmentMetadata(\n  routePath: string,\n  prefixPath: string,\n  prefixMetadata: Array<RoutePathSegmentMetadata | undefined> | undefined,\n  childMetadata: Array<RoutePathSegmentMetadata | undefined> | undefined,\n): Array<RoutePathSegmentMetadata | undefined> | undefined {\n  const metadata = new Array<RoutePathSegmentMetadata | undefined>(\n    countSlashSeparatedParts(routePath),\n  )\n  let hasMetadata = false\n\n  if (prefixMetadata) {\n    for (let i = 0; i < prefixMetadata.length && i < metadata.length; i++) {\n      metadata[i] = prefixMetadata[i]\n      hasMetadata ||= hasRoutePathSegmentMetadata(metadata[i])\n    }\n  }\n\n  const offset = countRoutePathSegments(prefixPath)\n  if (childMetadata) {\n    for (let i = 1; i < childMetadata.length; i++) {\n      const targetIndex = offset + i\n      if (targetIndex >= metadata.length) break\n\n      metadata[targetIndex] = mergeRoutePathSegmentMetadata(\n        metadata[targetIndex],\n        childMetadata[i],\n      )\n      hasMetadata ||= hasRoutePathSegmentMetadata(metadata[targetIndex])\n    }\n  }\n\n  return hasMetadata ? metadata : undefined\n}\n\nconst backslashRegex = /\\\\/g\n\nexport function replaceBackslash(s: string) {\n  return s.replace(backslashRegex, '/')\n}\n\nconst alphanumericRegex = /[a-zA-Z0-9_]/\nconst splatSlashRegex = /\\/\\$\\//g\nconst trailingSplatRegex = /\\$$/g\nconst bracketSplatRegex = /\\$\\{\\$\\}/g\nconst dollarSignRegex = /\\$/g\nconst splitPathRegex = /[/-]/g\nconst leadingDigitRegex = /^(\\d)/g\n\nconst toVariableSafeChar = (char: string): string => {\n  if (alphanumericRegex.test(char)) {\n    return char // Keep alphanumeric characters and underscores as is\n  }\n\n  // Replace special characters with meaningful text equivalents\n  switch (char) {\n    case '.':\n      return 'Dot'\n    case '-':\n      return 'Dash'\n    case '@':\n      return 'At'\n    case '(':\n      return '' // Removed since route groups use parentheses\n    case ')':\n      return '' // Removed since route groups use parentheses\n    case ' ':\n      return '' // Remove spaces\n    default:\n      return `Char${char.charCodeAt(0)}` // For any other characters\n  }\n}\n\nexport function routePathToVariable(routePath: string): string {\n  const cleaned = removeUnderscores(routePath)\n  if (!cleaned) return ''\n\n  const parts = cleaned\n    .replace(splatSlashRegex, '/splat/')\n    .replace(trailingSplatRegex, 'splat')\n    .replace(bracketSplatRegex, 'splat')\n    .replace(dollarSignRegex, '')\n    .split(splitPathRegex)\n\n  let result = ''\n  for (let i = 0; i < parts.length; i++) {\n    const part = parts[i]!\n    const segment = i > 0 ? capitalize(part) : part\n    for (let j = 0; j < segment.length; j++) {\n      result += toVariableSafeChar(segment[j]!)\n    }\n  }\n\n  return result.replace(leadingDigitRegex, 'R$1')\n}\n\nconst underscoreStartEndRegex = /(^_|_$)/gi\nconst underscoreSlashRegex = /(\\/_|_\\/)/gi\n\nexport function removeUnderscores(s?: string) {\n  return s\n    ?.replace(underscoreStartEndRegex, '')\n    .replace(underscoreSlashRegex, '/')\n}\n\nfunction removeUnderscoresFromSegment(\n  segment: string,\n  metadata?: RoutePathSegmentMetadata,\n): string {\n  let result = segment\n\n  if (result.startsWith('_') && !metadata?.literalLeadingUnderscore) {\n    result = result.slice(1)\n  }\n\n  if (result.endsWith('_') && !metadata?.literalTrailingUnderscore) {\n    result = result.slice(0, -1)\n  }\n\n  return result\n}\n\n/**\n * Removes underscores from a path, but preserves underscores that were escaped\n * in the original path (indicated by [_] syntax).\n *\n * @param routePath - The path with brackets removed\n * @param originalPath - The original path that may contain [_] escape sequences\n * @returns The path with non-escaped underscores removed\n */\nexport function removeUnderscoresWithEscape(\n  routePath?: string,\n  originalPath?: string,\n): string {\n  if (!routePath) return ''\n  if (!originalPath) return removeUnderscores(routePath) ?? ''\n\n  const routeSegments = routePath.split('/')\n  const metadata = createRoutePathSegmentMetadata(routePath, originalPath)\n  const newSegments = new Array<string>(routeSegments.length)\n\n  for (let i = 0; i < routeSegments.length; i++) {\n    newSegments[i] = removeUnderscoresFromSegment(\n      routeSegments[i]!,\n      metadata?.[i],\n    )\n  }\n\n  return newSegments.join('/')\n}\n\nexport function removeLayoutSegmentsAndUnderscoresWithEscape(\n  routePath: string = '/',\n  originalPath?: string,\n  routePathSegmentMetadata?: Array<RoutePathSegmentMetadata | undefined>,\n): string {\n  if (!originalPath) {\n    return removeUnderscores(removeLayoutSegments(routePath)) ?? ''\n  }\n\n  const metadata =\n    routePathSegmentMetadata ??\n    createRoutePathSegmentMetadata(routePath, originalPath)\n\n  const routeSegments = routePath.split('/')\n  const originalSegments = originalPath.split('/')\n  const newSegments: Array<string> = []\n\n  for (let i = 0; i < routeSegments.length; i++) {\n    const segment = routeSegments[i]!\n    const originalSegment = originalSegments[i] || ''\n    const segmentMetadata = metadata?.[i]\n\n    if (\n      !segmentMetadata?.literalLeadingUnderscore &&\n      isSegmentPathless(segment, originalSegment)\n    ) {\n      continue\n    }\n\n    newSegments.push(removeUnderscoresFromSegment(segment, segmentMetadata))\n  }\n\n  return newSegments.join('/')\n}\n\n/**\n * Removes layout segments (segments starting with underscore) from a path,\n * but preserves segments where the underscore was escaped.\n *\n * @param routePath - The path with brackets removed\n * @param originalPath - The original path that may contain [_] escape sequences\n * @returns The path with non-escaped layout segments removed\n */\nexport function removeLayoutSegmentsWithEscape(\n  routePath: string = '/',\n  originalPath?: string,\n): string {\n  if (!originalPath) return removeLayoutSegments(routePath)\n\n  const routeSegments = routePath.split('/')\n  const originalSegments = originalPath.split('/')\n\n  // Keep segments that are NOT pathless (i.e., don't start with unescaped underscore)\n  const newSegments = routeSegments.filter((segment, i) => {\n    const originalSegment = originalSegments[i] || ''\n    return !isSegmentPathless(segment, originalSegment)\n  })\n\n  return newSegments.join('/')\n}\n\n/**\n * Checks if a segment should be treated as a pathless/layout segment.\n * A segment is pathless if it starts with underscore and the underscore is not escaped.\n *\n * @param segment - The segment from routePath (brackets removed)\n * @param originalSegment - The segment from originalRoutePath (may contain brackets)\n * @returns true if the segment is pathless (has non-escaped leading underscore)\n */\nexport function isSegmentPathless(\n  segment: string,\n  originalSegment: string,\n): boolean {\n  if (!segment.startsWith('_')) return false\n  return !hasEscapedLeadingUnderscore(originalSegment)\n}\n\nexport function escapeRegExp(s: string): string {\n  return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction sanitizeTokenFlags(flags?: string): string | undefined {\n  if (!flags) return flags\n\n  // Prevent stateful behavior with RegExp.prototype.test/exec\n  // g = global, y = sticky\n  return flags.replace(/[gy]/g, '')\n}\n\nexport function createTokenRegex(\n  token: TokenMatcher,\n  opts: {\n    type: 'segment' | 'filename'\n  },\n): RegExp {\n  // Defensive check: if token is undefined/null, throw a clear error\n  // (runtime safety for config loading edge cases)\n  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n  if (token === undefined || token === null) {\n    throw new Error(\n      `createTokenRegex: token is ${token}. This usually means the config was not properly parsed with defaults.`,\n    )\n  }\n\n  try {\n    if (typeof token === 'string') {\n      return opts.type === 'segment'\n        ? new RegExp(`^${escapeRegExp(token)}$`)\n        : new RegExp(`[./]${escapeRegExp(token)}[.]`)\n    }\n\n    if (token instanceof RegExp) {\n      const flags = sanitizeTokenFlags(token.flags)\n      return opts.type === 'segment'\n        ? new RegExp(`^(?:${token.source})$`, flags)\n        : new RegExp(`[./](?:${token.source})[.]`, flags)\n    }\n\n    // Handle JSON regex object form: { regex: string, flags?: string }\n    if (typeof token === 'object' && 'regex' in token) {\n      const flags = sanitizeTokenFlags(token.flags)\n      return opts.type === 'segment'\n        ? new RegExp(`^(?:${token.regex})$`, flags)\n        : new RegExp(`[./](?:${token.regex})[.]`, flags)\n    }\n\n    throw new Error(\n      `createTokenRegex: invalid token type. Expected string, RegExp, or { regex, flags } object, got: ${typeof token}`,\n    )\n  } catch (e) {\n    if (e instanceof SyntaxError) {\n      const pattern =\n        typeof token === 'string'\n          ? token\n          : token instanceof RegExp\n            ? token.source\n            : token.regex\n      throw new Error(\n        `Invalid regex pattern in token config: \"${pattern}\". ${e.message}`,\n      )\n    }\n    throw e\n  }\n}\n\nfunction isBracketWrappedSegment(segment: string): boolean {\n  return segment.startsWith('[') && segment.endsWith(']')\n}\n\nexport function unwrapBracketWrappedSegment(segment: string): string {\n  return isBracketWrappedSegment(segment) ? segment.slice(1, -1) : segment\n}\n\nexport function removeLeadingUnderscores(s: string, routeToken: string) {\n  if (!s) return s\n\n  const hasLeadingUnderscore = routeToken[0] === '_'\n\n  const routeTokenToExclude = hasLeadingUnderscore\n    ? routeToken.slice(1)\n    : routeToken\n\n  const escapedRouteToken = escapeRegExp(routeTokenToExclude)\n\n  const leadingUnderscoreRegex = hasLeadingUnderscore\n    ? new RegExp(`(?<=^|\\\\/)_(?!${escapedRouteToken})`, 'g')\n    : new RegExp(`(?<=^|\\\\/)_`, 'g')\n\n  return s.replaceAll(leadingUnderscoreRegex, '')\n}\n\nexport function removeTrailingUnderscores(s: string, routeToken: string) {\n  if (!s) return s\n\n  const hasTrailingUnderscore = routeToken.slice(-1) === '_'\n\n  const routeTokenToExclude = hasTrailingUnderscore\n    ? routeToken.slice(0, -1)\n    : routeToken\n\n  const escapedRouteToken = escapeRegExp(routeTokenToExclude)\n\n  const trailingUnderscoreRegex = hasTrailingUnderscore\n    ? new RegExp(`(?<!${escapedRouteToken})_(?=\\\\/|$)`, 'g')\n    : new RegExp(`_(?=\\\\/)|_$`, 'g')\n\n  return s.replaceAll(trailingUnderscoreRegex, '')\n}\n\nexport function capitalize(s: string) {\n  if (typeof s !== 'string') return ''\n  return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nexport function removeExt(d: string, addExtensions: boolean | string = false) {\n  if (typeof addExtensions === 'string') {\n    const dotIndex = d.lastIndexOf('.')\n    if (dotIndex === -1) return d\n    return d.substring(0, dotIndex) + addExtensions\n  }\n  return addExtensions ? d : d.substring(0, d.lastIndexOf('.')) || d\n}\n\n/**\n * This function writes to a file if the content is different.\n *\n * @param filepath The path to the file\n * @param content Original content\n * @param incomingContent New content\n * @param callbacks Callbacks to run before and after writing\n * @returns Whether the file was written\n */\nexport async function writeIfDifferent(\n  filepath: string,\n  content: string,\n  incomingContent: string,\n  callbacks?: { beforeWrite?: () => void; afterWrite?: () => void },\n): Promise<boolean> {\n  if (content !== incomingContent) {\n    callbacks?.beforeWrite?.()\n    await fsp.writeFile(filepath, incomingContent)\n    callbacks?.afterWrite?.()\n    return true\n  }\n  return false\n}\n\n/**\n * This function formats the source code using the default formatter (Prettier).\n *\n * @param source The content to format\n * @param config The configuration object\n * @returns The formatted content\n */\nexport async function format(\n  source: string,\n  config: {\n    quoteStyle: 'single' | 'double'\n    semicolons: boolean\n  },\n): Promise<string> {\n  const prettierOptions: prettier.Config = {\n    semi: config.semicolons,\n    singleQuote: config.quoteStyle === 'single',\n    parser: 'typescript',\n  }\n  return prettier.format(source, prettierOptions)\n}\n\n/**\n * This function resets the regex index to 0 so that it can be reused\n * without having to create a new regex object or worry about the last\n * state when using the global flag.\n *\n * @param regex The regex object to reset\n * @returns\n */\nexport function resetRegex(regex: RegExp) {\n  regex.lastIndex = 0\n  return\n}\n\n/**\n * This function checks if a file exists.\n *\n * @param file The path to the file\n * @returns Whether the file exists\n */\nexport async function checkFileExists(file: string) {\n  try {\n    await fsp.access(file, fsp.constants.F_OK)\n    return true\n  } catch {\n    return false\n  }\n}\n\nconst possiblyNestedRouteGroupPatternRegex = /\\([^/]+\\)\\/?/g\nexport function removeGroups(s: string) {\n  return s.replace(possiblyNestedRouteGroupPatternRegex, '')\n}\n\n/**\n * Removes all segments from a given path that start with an underscore ('_').\n *\n * @param {string} routePath - The path from which to remove segments. Defaults to '/'.\n * @returns {string} The path with all underscore-prefixed segments removed.\n * @example\n * removeLayoutSegments('/workspace/_auth/foo') // '/workspace/foo'\n */\nexport function removeLayoutSegments(routePath: string = '/'): string {\n  const segments = routePath.split('/')\n  const newSegments = segments.filter((segment) => !segment.startsWith('_'))\n  return newSegments.join('/')\n}\n\n/**\n * The `node.path` is used as the `id` in the route definition.\n * This function checks if the given node has a parent and if so, it determines the correct path for the given node.\n * @param node - The node to determine the path for.\n * @returns The correct path for the given node.\n */\nexport function determineNodePath(node: RouteNode) {\n  return (node.path = node.parent\n    ? node.routePath?.replace(node.parent.routePath ?? '', '') || '/'\n    : node.routePath)\n}\n\n/**\n * Removes the last segment from a given path. Segments are considered to be separated by a '/'.\n *\n * @param {string} routePath - The path from which to remove the last segment. Defaults to '/'.\n * @returns {string} The path with the last segment removed.\n * @example\n * removeLastSegmentFromPath('/workspace/_auth/foo') // '/workspace/_auth'\n */\nexport function removeLastSegmentFromPath(routePath: string = '/'): string {\n  const segments = routePath.split('/')\n  segments.pop() // Remove the last segment\n  return segments.join('/')\n}\n\n/**\n * Find parent route using RoutePrefixMap for O(k) lookups instead of O(n).\n */\nexport function hasParentRoute(\n  prefixMap: RoutePrefixMap,\n  node: RouteNode,\n  routePathToCheck: string | undefined,\n): RouteNode | null {\n  if (!routePathToCheck || routePathToCheck === '/') {\n    return null\n  }\n\n  return prefixMap.findParent(routePathToCheck)\n}\n\n/**\n * Gets the final variable name for a route\n */\nexport const getResolvedRouteNodeVariableName = (\n  routeNode: RouteNode,\n): string => {\n  return routeNode.children?.length\n    ? `${routeNode.variableName}RouteWithChildren`\n    : `${routeNode.variableName}Route`\n}\n\n/**\n * Infers the path for use by TS\n */\nconst inferPath = (routeNode: RouteNode): string => {\n  if (routeNode.cleanedPath === '/') {\n    return routeNode.cleanedPath ?? ''\n  }\n  return routeNode.cleanedPath?.replace(/\\/$/, '') ?? ''\n}\n\n/**\n * Infers the full path for use by TS\n */\nexport const inferFullPath = (routeNode: RouteNode): string => {\n  const fullPath = removeGroups(\n    removeLayoutSegmentsAndUnderscoresWithEscape(\n      routeNode.routePath,\n      routeNode.originalRoutePath,\n      routeNode._routePathSegmentMetadata,\n    ),\n  )\n\n  if (fullPath === '') {\n    return '/'\n  }\n\n  // Preserve trailing slash for index routes (routePath ends with '/')\n  // This ensures types match runtime behavior\n  const isIndexRoute = routeNode.routePath?.endsWith('/')\n  if (isIndexRoute) {\n    return fullPath\n  }\n\n  return fullPath.replace(/\\/$/, '')\n}\n\nconst shouldPreferIndexRoute = (\n  current: RouteNode,\n  existing: RouteNode,\n): boolean => {\n  return existing.cleanedPath === '/' && current.cleanedPath !== '/'\n}\n\nconst isIndexRouteNode = (routeNode: RouteNode): boolean => {\n  return routeNode.routePath?.endsWith('/') ?? false\n}\n\nconst isPathlessRouteNode = (routeNode: RouteNode): boolean => {\n  return routeNode._fsRouteType === 'pathless_layout'\n}\n\nconst shouldReplaceRouteNodeForTo = (\n  current: RouteNode,\n  existing: RouteNode,\n): boolean => {\n  const currentIsIndex = isIndexRouteNode(current)\n  const existingIsIndex = isIndexRouteNode(existing)\n  if (currentIsIndex !== existingIsIndex) {\n    return currentIsIndex\n  }\n\n  const currentIsPathless = isPathlessRouteNode(current)\n  const existingIsPathless = isPathlessRouteNode(existing)\n  if (currentIsPathless !== existingIsPathless) {\n    return !currentIsPathless\n  }\n\n  return true\n}\n\nconst shouldReplaceRouteNodeForFullPath = (\n  current: RouteNode,\n  existing: RouteNode,\n): boolean => {\n  const currentIsPathless = isPathlessRouteNode(current)\n  const existingIsPathless = isPathlessRouteNode(existing)\n  if (currentIsPathless !== existingIsPathless) {\n    return !currentIsPathless\n  }\n\n  return true\n}\n\n/**\n * Creates a map from fullPath to routeNode\n */\nexport const createRouteNodesByFullPath = (\n  routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n  const map = new Map<string, RouteNode>()\n\n  for (const routeNode of routeNodes) {\n    const fullPath = inferFullPath(routeNode)\n\n    if (fullPath === '/' && map.has('/')) {\n      const existing = map.get('/')!\n      if (shouldPreferIndexRoute(routeNode, existing)) {\n        continue\n      }\n    }\n\n    const existing = map.get(fullPath)\n    if (existing && !shouldReplaceRouteNodeForFullPath(routeNode, existing)) {\n      continue\n    }\n\n    map.set(fullPath, routeNode)\n  }\n\n  return map\n}\n\n/**\n * Create a map from 'to' to a routeNode\n */\nexport const createRouteNodesByTo = (\n  routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n  const map = new Map<string, RouteNode>()\n\n  for (const routeNode of dedupeBranchesAndIndexRoutes(routeNodes)) {\n    const to = inferTo(routeNode)\n\n    const existing = map.get(to)\n    if (existing && !shouldReplaceRouteNodeForTo(routeNode, existing)) {\n      continue\n    }\n\n    map.set(to, routeNode)\n  }\n\n  return map\n}\n\n/**\n * Create a map from 'id' to a routeNode\n */\nexport const createRouteNodesById = (\n  routeNodes: Array<RouteNode>,\n): Map<string, RouteNode> => {\n  return new Map(\n    routeNodes.map((routeNode) => {\n      const id = routeNode.routePath ?? ''\n      return [id, routeNode]\n    }),\n  )\n}\n\n/**\n * Infers to path\n */\nconst inferTo = (routeNode: RouteNode): string => {\n  const fullPath = inferFullPath(routeNode)\n\n  if (fullPath === '/') return fullPath\n\n  return fullPath.replace(/\\/$/, '')\n}\n\n/**\n * Dedupes branches and index routes\n */\nconst dedupeBranchesAndIndexRoutes = (\n  routes: Array<RouteNode>,\n): Array<RouteNode> => {\n  return routes.filter((route) => {\n    if (route.children?.find((child) => child.cleanedPath === '/')) return false\n    return true\n  })\n}\n\nfunction checkUnique<TElement>(routes: Array<TElement>, key: keyof TElement) {\n  // Check no two routes have the same `key`\n  // if they do, throw an error with the conflicting filePaths\n  const keys = routes.map((d) => d[key])\n  const uniqueKeys = new Set(keys)\n  if (keys.length !== uniqueKeys.size) {\n    const duplicateKeys = keys.filter((d, i) => keys.indexOf(d) !== i)\n    const conflictingFiles = routes.filter((d) =>\n      duplicateKeys.includes(d[key]),\n    )\n    return conflictingFiles\n  }\n  return undefined\n}\n\nexport function checkRouteFullPathUniqueness(\n  _routes: Array<RouteNode>,\n  config: Config,\n) {\n  const emptyPathRoutes = _routes.filter((d) => d.routePath === '')\n  if (emptyPathRoutes.length) {\n    const errorMessage = `Invalid route path \"\" was found. Root routes must be defined via __root.tsx (createRootRoute), not createFileRoute('') or a route file that resolves to an empty path.\nConflicting files: \\n ${emptyPathRoutes\n      .map((d) => path.resolve(config.routesDirectory, d.filePath))\n      .join('\\n ')}\\n`\n    throw new Error(errorMessage)\n  }\n\n  const routes = _routes.map((d) => {\n    const inferredFullPath = inferFullPath(d)\n    return { ...d, inferredFullPath }\n  })\n\n  const conflictingFiles = checkUnique(routes, 'inferredFullPath')\n\n  if (conflictingFiles !== undefined) {\n    const errorMessage = `Conflicting configuration paths were found for the following route${conflictingFiles.length > 1 ? 's' : ''}: ${conflictingFiles\n      .map((p) => `\"${p.inferredFullPath}\"`)\n      .join(', ')}.\nPlease ensure each Route has a unique full path.\nConflicting files: \\n ${conflictingFiles.map((d) => path.resolve(config.routesDirectory, d.filePath)).join('\\n ')}\\n`\n    throw new Error(errorMessage)\n  }\n}\n\nexport function buildRouteTreeConfig(\n  nodes: Array<RouteNode>,\n  disableTypes: boolean,\n  depth = 1,\n): Array<string> {\n  const children = nodes.map((node) => {\n    if (node._fsRouteType === '__root') {\n      return\n    }\n\n    if (node._fsRouteType === 'pathless_layout' && !node.children?.length) {\n      return\n    }\n\n    const route = `${node.variableName}`\n\n    if (node.children?.length) {\n      const childConfigs = buildRouteTreeConfig(\n        node.children,\n        disableTypes,\n        depth + 1,\n      )\n\n      const childrenDeclaration = disableTypes\n        ? ''\n        : `interface ${route}RouteChildren {\n  ${node.children\n    .map(\n      (child) =>\n        `${child.variableName}Route: typeof ${getResolvedRouteNodeVariableName(child)}`,\n    )\n    .join(',')}\n}`\n\n      const children = `const ${route}RouteChildren${disableTypes ? '' : `: ${route}RouteChildren`} = {\n  ${node.children\n    .map(\n      (child) =>\n        `${child.variableName}Route: ${getResolvedRouteNodeVariableName(child)}`,\n    )\n    .join(',')}\n}`\n\n      const routeWithChildren = `const ${route}RouteWithChildren = ${route}Route._addFileChildren(${route}RouteChildren)`\n\n      return [\n        childConfigs.join('\\n'),\n        childrenDeclaration,\n        children,\n        routeWithChildren,\n      ].join('\\n\\n')\n    }\n\n    return undefined\n  })\n\n  return children.filter((x) => x !== undefined)\n}\n\nexport function buildImportString(\n  importDeclaration: ImportDeclaration,\n): string {\n  const { source, specifiers, importKind } = importDeclaration\n  return specifiers.length\n    ? `import ${importKind === 'type' ? 'type ' : ''}{ ${specifiers.map((s) => (s.local ? `${s.imported} as ${s.local}` : s.imported)).join(', ')} } from '${source}'`\n    : ''\n}\n\nexport function mergeImportDeclarations(\n  imports: Array<ImportDeclaration>,\n): Array<ImportDeclaration> {\n  const merged = new Map<string, ImportDeclaration>()\n\n  for (const imp of imports) {\n    const key = `${imp.source}-${imp.importKind ?? ''}`\n    let existing = merged.get(key)\n    if (!existing) {\n      existing = { ...imp, specifiers: [] }\n      merged.set(key, existing)\n    }\n\n    const existingSpecs = existing.specifiers\n    for (const specifier of imp.specifiers) {\n      let found = false\n      for (let i = 0; i < existingSpecs.length; i++) {\n        const e = existingSpecs[i]!\n        if (e.imported === specifier.imported && e.local === specifier.local) {\n          found = true\n          break\n        }\n      }\n      if (!found) {\n        existingSpecs.push(specifier)\n      }\n    }\n  }\n\n  return [...merged.values()]\n}\n\nexport const findParent = (node: RouteNode | undefined): string => {\n  if (!node) {\n    return `rootRouteImport`\n  }\n  if (node.parent) {\n    return `${node.parent.variableName}Route`\n  }\n  return findParent(node.parent)\n}\n\nexport function buildFileRoutesByPathInterface(opts: {\n  routeNodes: Array<RouteNode>\n  module: string\n  interfaceName: string\n  config?: Pick<Config, 'routeToken'>\n}): string {\n  return `declare module '${opts.module}' {\n  interface ${opts.interfaceName} {\n    ${opts.routeNodes\n      .map((routeNode) => {\n        const filePathId = routeNode.routePath\n        const preloaderRoute = `typeof ${routeNode.variableName}RouteImport`\n\n        const parent = findParent(routeNode)\n\n        return `'${filePathId}': {\n          id: '${filePathId}'\n          path: '${inferPath(routeNode)}'\n          fullPath: '${inferFullPath(routeNode)}'\n          preLoaderRoute: ${preloaderRoute}\n          parentRoute: typeof ${parent}\n        }`\n      })\n      .join('\\n')}\n  }\n}`\n}\n\nfunction getImportPath(\n  node: RouteNode,\n  config: Config,\n  generatedRouteTreePath: string,\n): string {\n  return replaceBackslash(\n    removeExt(\n      path.relative(\n        path.dirname(generatedRouteTreePath),\n        path.resolve(config.routesDirectory, node.filePath),\n      ),\n      config.addExtensions,\n    ),\n  )\n}\n\nexport function getImportForRouteNode(\n  node: RouteNode,\n  config: Config,\n  generatedRouteTreePath: string,\n  root: string,\n): ImportDeclaration {\n  let source = ''\n  if (config.importRoutesUsingAbsolutePaths) {\n    source = replaceBackslash(\n      removeExt(\n        path.resolve(root, config.routesDirectory, node.filePath),\n        config.addExtensions,\n      ),\n    )\n  } else {\n    source = `./${getImportPath(node, config, generatedRouteTreePath)}`\n  }\n  return {\n    source,\n    specifiers: [\n      {\n        imported: 'Route',\n        local: `${node.variableName}RouteImport`,\n      },\n    ],\n  } satisfies ImportDeclaration\n}\n"],"mappings":"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"}