{"version":3,"sources":["../../../src/build/static-paths/utils.ts"],"sourcesContent":["import type { LoaderTree } from '../../server/lib/app-dir-module'\nimport type { Params } from '../../server/request/params'\nimport type { AppPageRouteModule } from '../../server/route-modules/app-page/module.compiled'\nimport type { AppRouteRouteModule } from '../../server/route-modules/app-route/module.compiled'\nimport { isAppPageRouteModule } from '../../server/route-modules/checks'\nimport type { DynamicParamTypes } from '../../shared/lib/app-router-types'\nimport {\n  parseAppRouteSegment,\n  type NormalizedAppRoute,\n} from '../../shared/lib/router/routes/app'\nimport { parseLoaderTree } from '../../shared/lib/router/utils/parse-loader-tree'\nimport type { AppSegment } from '../segment-config/app/app-segments'\nimport { extractPathnameRouteParamSegmentsFromLoaderTree } from './app/extract-pathname-route-param-segments-from-loader-tree'\nimport { resolveParamValue } from '../../shared/lib/router/utils/resolve-param-value'\nimport type { FallbackRouteParam } from './types'\n\n/**\n * Encodes a parameter value using the provided encoder.\n *\n * @param value - The value to encode.\n * @param encoder - The encoder to use.\n * @returns The encoded value.\n */\nexport function encodeParam(\n  value: string | string[],\n  encoder: (value: string) => string\n) {\n  let replaceValue: string\n  if (Array.isArray(value)) {\n    replaceValue = value.map(encoder).join('/')\n  } else {\n    replaceValue = encoder(value)\n  }\n\n  return replaceValue\n}\n\n/**\n * Normalizes a pathname to a consistent format.\n *\n * @param pathname - The pathname to normalize.\n * @returns The normalized pathname.\n */\nexport function normalizePathname(pathname: string) {\n  return pathname.replace(/\\\\/g, '/').replace(/(?!^)\\/$/, '')\n}\n\n/**\n * Extracts segments that contribute to the pathname by traversing the loader tree\n * based on the route module type.\n *\n * @param routeModule - The app route module (page or route handler)\n * @param segments - Array of AppSegment objects collected from the route\n * @param page - The target pathname to match against, INCLUDING interception\n *               markers (e.g., \"/blog/[slug]\", \"/(.)photo/[id]\")\n * @returns Array of segments with param info that contribute to the pathname\n */\nexport function extractPathnameRouteParamSegments(\n  routeModule: AppRouteRouteModule | AppPageRouteModule,\n  segments: readonly Readonly<AppSegment>[],\n  route: NormalizedAppRoute\n): Array<{\n  readonly name: string\n  readonly paramName: string\n  readonly paramType: DynamicParamTypes\n}> {\n  // For AppPageRouteModule, use the loaderTree traversal approach\n  if (isAppPageRouteModule(routeModule)) {\n    const { pathnameRouteParamSegments } =\n      extractPathnameRouteParamSegmentsFromLoaderTree(\n        routeModule.userland.loaderTree,\n        route\n      )\n    return pathnameRouteParamSegments\n  }\n\n  return extractPathnameRouteParamSegmentsFromSegments(segments)\n}\n\nexport function extractPathnameRouteParamSegmentsFromSegments(\n  segments: readonly Readonly<AppSegment>[]\n): Array<{\n  readonly name: string\n  readonly paramName: string\n  readonly paramType: DynamicParamTypes\n}> {\n  // TODO: should we consider what values are already present in the page?\n\n  // For AppRouteRouteModule, filter the segments array to get the route params\n  // that contribute to the pathname.\n  const result: Array<{\n    readonly name: string\n    readonly paramName: string\n    readonly paramType: DynamicParamTypes\n  }> = []\n\n  for (const segment of segments) {\n    // Skip segments without param info.\n    if (!segment.paramName || !segment.paramType) continue\n\n    // Collect all the route param keys that contribute to the pathname.\n    result.push({\n      name: segment.name,\n      paramName: segment.paramName,\n      paramType: segment.paramType,\n    })\n  }\n\n  return result\n}\n\n/**\n * Resolves all route parameters from the loader tree. This function uses\n * tree-based traversal to correctly handle the hierarchical structure of routes\n * and accurately determine parameter values based on their depth in the tree.\n *\n * This processes both regular route parameters (from the main children route) and\n * parallel route parameters (from slots like @modal, @sidebar).\n *\n * Unlike interpolateParallelRouteParams (which has a complete URL at runtime),\n * this build-time function determines which route params are unknown.\n * The pathname may contain placeholders like [slug], making it incomplete.\n *\n * @param loaderTree - The loader tree structure containing route hierarchy\n * @param params - The current route parameters object (will be mutated)\n * @param route - The current route being processed\n * @param fallbackRouteParams - Array of fallback route parameters (will be mutated)\n */\nexport function resolveRouteParamsFromTree(\n  loaderTree: LoaderTree,\n  params: Params,\n  route: NormalizedAppRoute,\n  fallbackRouteParams: FallbackRouteParam[]\n): void {\n  // Stack-based traversal with depth tracking\n  const stack: Array<{\n    tree: LoaderTree\n    depth: number\n  }> = [{ tree: loaderTree, depth: 0 }]\n\n  while (stack.length > 0) {\n    const { tree, depth } = stack.pop()!\n    const { segment, parallelRoutes } = parseLoaderTree(tree)\n\n    const appSegment = parseAppRouteSegment(segment)\n\n    // If this segment is a route parameter, then we should process it if it's\n    // not already known and is not already marked as a fallback route param.\n    if (\n      appSegment?.type === 'dynamic' &&\n      !params.hasOwnProperty(appSegment.param.paramName) &&\n      !fallbackRouteParams.some(\n        (param) => param.paramName === appSegment.param.paramName\n      )\n    ) {\n      const { paramName, paramType } = appSegment.param\n\n      const paramValue = resolveParamValue(\n        paramName,\n        paramType,\n        depth,\n        route,\n        params\n      )\n\n      if (paramValue !== undefined) {\n        params[paramName] = paramValue\n      } else if (paramType !== 'optional-catchall') {\n        // If we couldn't resolve the param, mark it as a fallback\n        fallbackRouteParams.push({ paramName, paramType })\n      }\n    }\n\n    // Calculate next depth - increment if this is not a route group and not empty\n    let nextDepth = depth\n    if (\n      appSegment &&\n      appSegment.type !== 'route-group' &&\n      appSegment.type !== 'parallel-route'\n    ) {\n      nextDepth++\n    }\n\n    // Add all parallel routes to the stack for processing.\n    for (const parallelRoute of Object.values(parallelRoutes)) {\n      stack.push({ tree: parallelRoute, depth: nextDepth })\n    }\n  }\n}\n"],"names":["encodeParam","extractPathnameRouteParamSegments","extractPathnameRouteParamSegmentsFromSegments","normalizePathname","resolveRouteParamsFromTree","value","encoder","replaceValue","Array","isArray","map","join","pathname","replace","routeModule","segments","route","isAppPageRouteModule","pathnameRouteParamSegments","extractPathnameRouteParamSegmentsFromLoaderTree","userland","loaderTree","result","segment","paramName","paramType","push","name","params","fallbackRouteParams","stack","tree","depth","length","pop","parallelRoutes","parseLoaderTree","appSegment","parseAppRouteSegment","type","hasOwnProperty","param","some","paramValue","resolveParamValue","undefined","nextDepth","parallelRoute","Object","values"],"mappings":"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","ignoreList":[0]}