{"version":3,"file":"utils.js","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 { ImportDeclaration, RouteNode } 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  private layoutRoutes: Array<RouteNode> = []\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      if (\n        route._fsRouteType === 'pathless_layout' ||\n        route._fsRouteType === 'layout' ||\n        route._fsRouteType === '__root'\n      ) {\n        this.layoutRoutes.push(route)\n      }\n    }\n\n    // Sort by path length descending for longest-match-first\n    this.layoutRoutes.sort(\n      (a, b) => (b.routePath?.length ?? 0) - (a.routePath?.length ?? 0),\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\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\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 originalSegments = originalPath.split('/')\n\n  const newSegments = routeSegments.map((segment, i) => {\n    const originalSegment = originalSegments[i] || ''\n\n    // Check if leading underscore is escaped\n    const leadingEscaped = hasEscapedLeadingUnderscore(originalSegment)\n    // Check if trailing underscore is escaped\n    const trailingEscaped = hasEscapedTrailingUnderscore(originalSegment)\n\n    let result = segment\n\n    // Remove leading underscore only if not escaped\n    if (result.startsWith('_') && !leadingEscaped) {\n      result = result.slice(1)\n    }\n\n    // Remove trailing underscore only if not escaped\n    if (result.endsWith('_') && !trailingEscaped) {\n      result = result.slice(0, -1)\n    }\n\n    return result\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\nfunction 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\nexport function 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 * Checks if a given RouteNode is valid for augmenting it with typing based on conditions.\n * Also asserts that the RouteNode is defined.\n *\n * @param routeNode - The RouteNode to check.\n * @returns A boolean indicating whether the RouteNode is defined.\n */\nexport function isRouteNodeValidForAugmentation(\n  routeNode?: RouteNode,\n): routeNode is RouteNode {\n  if (!routeNode || routeNode.isVirtual) {\n    return false\n  }\n  return true\n}\n\n/**\n * Infers the path for use by TS\n */\nexport const 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    removeUnderscoresWithEscape(\n      removeLayoutSegmentsWithEscape(\n        routeNode.routePath,\n        routeNode.originalRoutePath,\n      ),\n      routeNode.originalRoutePath,\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\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    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    if (to === '/' && map.has('/')) {\n      const existing = map.get('/')!\n      if (shouldPreferIndexRoute(routeNode, existing)) {\n        continue\n      }\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 */\nexport const 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 */\nexport const 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 lowerCaseFirstChar(value: string) {\n  if (!value[0]) {\n    return value\n  }\n\n  return value[0].toLowerCase() + value.slice(1)\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\nexport function 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"],"names":["path","children"],"mappings":"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"}