{"version":3,"sources":["../../../../src/lib/metadata/get-metadata-route.ts"],"sourcesContent":["import { isMetadataPage } from './is-metadata-route'\nimport path from '../../shared/lib/isomorphic/path'\nimport { interpolateDynamicPath } from '../../server/server-utils'\nimport { getNamedRouteRegex } from '../../shared/lib/router/utils/route-regex'\nimport { djb2Hash } from '../../shared/lib/hash'\nimport { normalizeAppPath } from '../../shared/lib/router/utils/app-paths'\nimport { normalizePathSep } from '../../shared/lib/page-path/normalize-path-sep'\nimport {\n  isGroupSegment,\n  isParallelRouteSegment,\n} from '../../shared/lib/segment'\n\n/*\n * If there's special convention like (...) or @ in the page path,\n * Give it a unique hash suffix to avoid conflicts\n *\n * e.g.\n * /opengraph-image -> /opengraph-image\n * /(post)/opengraph-image.tsx -> /opengraph-image-[0-9a-z]{6}\n *\n * Sitemap is an exception, it should not have a suffix.\n * Each sitemap contains all the urls of sub routes, we don't have the case of duplicates `/(group)/sitemap.[ext]` and `/sitemap.[ext]` since they should be the same.\n * Hence we always normalize the urls for sitemap and do not append hash suffix, and ensure user-land only contains one sitemap per pathname.\n *\n * /sitemap -> /sitemap\n * /(post)/sitemap -> /sitemap\n */\nfunction getMetadataRouteSuffix(page: string) {\n  // Remove the last segment and get the parent pathname\n  // e.g. /parent/a/b/c -> /parent/a/b\n  // e.g. /parent/opengraph-image -> /parent\n  const parentPathname = path.dirname(page)\n  // Only apply suffix to metadata routes except for sitemaps\n  if (page.endsWith('/sitemap') || page.endsWith('/sitemap.xml')) {\n    return ''\n  }\n\n  // Calculate the hash suffix based on the parent path\n  let suffix = ''\n  // Check if there's any special characters in the parent pathname.\n  const segments = parentPathname.split('/')\n  if (\n    segments.some((seg) => isGroupSegment(seg) || isParallelRouteSegment(seg))\n  ) {\n    // Hash the parent path to get a unique suffix\n    suffix = djb2Hash(parentPathname).toString(36).slice(0, 6)\n  }\n  return suffix\n}\n\n/**\n * Fill the dynamic segment in the metadata route\n *\n * Example:\n * fillMetadataSegment('/a/[slug]', { params: { slug: 'b' } }, 'open-graph', false) -> '/a/b/open-graph'\n *\n * When isStatic is true, all dynamic segments are filled with \"-\" placeholder\n * since static metadata files have consistent responses regardless of params.\n * Example:\n * fillMetadataSegment('/a/[slug]', {}, 'icon.png', true) -> '/a/-/icon.png'\n *\n */\nexport function fillMetadataSegment(\n  segment: string,\n  params: any,\n  lastSegment: string,\n  isStatic: boolean\n) {\n  const pathname = normalizeAppPath(segment)\n  const routeRegex = getNamedRouteRegex(pathname, {\n    prefixRouteKeys: false,\n  })\n\n  // For static metadata files, fill all dynamic segments with \"-\" placeholder\n  const routeParams = isStatic\n    ? Object.keys(routeRegex.groups).reduce(\n        (acc, key) => {\n          const { repeat } = routeRegex.groups[key]\n          // Use array for catch-all segments, string for regular segments\n          acc[key] = repeat ? ['-'] : '-'\n          return acc\n        },\n        {} as Record<string, string | string[]>\n      )\n    : params\n\n  const route = interpolateDynamicPath(pathname, routeParams, routeRegex)\n  const { name, ext } = path.parse(lastSegment)\n  const pagePath = path.posix.join(segment, name)\n  const suffix = getMetadataRouteSuffix(pagePath)\n  const routeSuffix = suffix ? `-${suffix}` : ''\n\n  return normalizePathSep(path.join(route, `${name}${routeSuffix}${ext}`))\n}\n\n/**\n * Map metadata page key to the corresponding route\n *\n * static file page key:    /app/robots.txt -> /robots.xml -> /robots.txt/route\n * dynamic route page key:  /app/robots.tsx -> /robots -> /robots.txt/route\n *\n * @param page\n * @returns\n */\nexport function normalizeMetadataRoute(page: string) {\n  if (!isMetadataPage(page)) {\n    return page\n  }\n  let route = page\n  let suffix = ''\n  if (page === '/robots') {\n    route += '.txt'\n  } else if (page === '/manifest') {\n    route += '.webmanifest'\n  } else {\n    suffix = getMetadataRouteSuffix(page)\n  }\n  // Support both /<metadata-route.ext> and custom routes /<metadata-route>/route.ts.\n  // If it's a metadata file route, we need to append /[id]/route to the page.\n  if (!route.endsWith('/route')) {\n    const { dir, name: baseName, ext } = path.parse(route)\n    route = path.posix.join(\n      dir,\n      `${baseName}${suffix ? `-${suffix}` : ''}${ext}`,\n      'route'\n    )\n  }\n\n  return route\n}\n\n// Normalize metadata route page to either a single route or a dynamic route.\n// e.g. Input: /sitemap/route\n// when isDynamic is false, single route -> /sitemap.xml/route\n// when isDynamic is false, dynamic route -> /sitemap/[__metadata_id__]/route\n// also works for pathname such as /sitemap -> /sitemap.xml, but will not append /route suffix\nexport function normalizeMetadataPageToRoute(page: string, isDynamic: boolean) {\n  const isRoute = page.endsWith('/route')\n  const routePagePath = isRoute ? page.slice(0, -'/route'.length) : page\n  const metadataRouteExtension = routePagePath.endsWith('/sitemap')\n    ? '.xml'\n    : ''\n  const mapped = isDynamic\n    ? `${routePagePath}/[__metadata_id__]`\n    : `${routePagePath}${metadataRouteExtension}`\n\n  return mapped + (isRoute ? '/route' : '')\n}\n"],"names":["isMetadataPage","path","interpolateDynamicPath","getNamedRouteRegex","djb2Hash","normalizeAppPath","normalizePathSep","isGroupSegment","isParallelRouteSegment","getMetadataRouteSuffix","page","parentPathname","dirname","endsWith","suffix","segments","split","some","seg","toString","slice","fillMetadataSegment","segment","params","lastSegment","isStatic","pathname","routeRegex","prefixRouteKeys","routeParams","Object","keys","groups","reduce","acc","key","repeat","route","name","ext","parse","pagePath","posix","join","routeSuffix","normalizeMetadataRoute","dir","baseName","normalizeMetadataPageToRoute","isDynamic","isRoute","routePagePath","length","metadataRouteExtension","mapped"],"mappings":"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","ignoreList":[0]}