{"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') -> '/a/b/open-graph'\n *\n */\nexport function fillMetadataSegment(\n segment: string,\n params: any,\n lastSegment: string\n) {\n const pathname = normalizeAppPath(segment)\n const routeRegex = getNamedRouteRegex(pathname, {\n prefixRouteKeys: false,\n })\n const route = interpolateDynamicPath(pathname, params, 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 / and custom routes //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":["fillMetadataSegment","normalizeMetadataPageToRoute","normalizeMetadataRoute","getMetadataRouteSuffix","page","parentPathname","path","dirname","endsWith","suffix","segments","split","some","seg","isGroupSegment","isParallelRouteSegment","djb2Hash","toString","slice","segment","params","lastSegment","pathname","normalizeAppPath","routeRegex","getNamedRouteRegex","prefixRouteKeys","route","interpolateDynamicPath","name","ext","parse","pagePath","posix","join","routeSuffix","normalizePathSep","isMetadataPage","dir","baseName","isDynamic","isRoute","routePagePath","length","metadataRouteExtension","mapped"],"mappings":";;;;;;;;;;;;;;;;IAyDgBA,mBAAmB;eAAnBA;;IA2DAC,4BAA4B;eAA5BA;;IAhCAC,sBAAsB;eAAtBA;;;iCApFe;6DACd;6BACsB;4BACJ;sBACV;0BACQ;kCACA;yBAI1B;;;;;;AAEP;;;;;;;;;;;;;;CAcC,GACD,SAASC,uBAAuBC,IAAY;IAC1C,sDAAsD;IACtD,oCAAoC;IACpC,0CAA0C;IAC1C,MAAMC,iBAAiBC,aAAI,CAACC,OAAO,CAACH;IACpC,2DAA2D;IAC3D,IAAIA,KAAKI,QAAQ,CAAC,eAAeJ,KAAKI,QAAQ,CAAC,iBAAiB;QAC9D,OAAO;IACT;IAEA,qDAAqD;IACrD,IAAIC,SAAS;IACb,kEAAkE;IAClE,MAAMC,WAAWL,eAAeM,KAAK,CAAC;IACtC,IACED,SAASE,IAAI,CAAC,CAACC,MAAQC,IAAAA,uBAAc,EAACD,QAAQE,IAAAA,+BAAsB,EAACF,OACrE;QACA,8CAA8C;QAC9CJ,SAASO,IAAAA,cAAQ,EAACX,gBAAgBY,QAAQ,CAAC,IAAIC,KAAK,CAAC,GAAG;IAC1D;IACA,OAAOT;AACT;AASO,SAAST,oBACdmB,OAAe,EACfC,MAAW,EACXC,WAAmB;IAEnB,MAAMC,WAAWC,IAAAA,0BAAgB,EAACJ;IAClC,MAAMK,aAAaC,IAAAA,8BAAkB,EAACH,UAAU;QAC9CI,iBAAiB;IACnB;IACA,MAAMC,QAAQC,IAAAA,mCAAsB,EAACN,UAAUF,QAAQI;IACvD,MAAM,EAAEK,IAAI,EAAEC,GAAG,EAAE,GAAGxB,aAAI,CAACyB,KAAK,CAACV;IACjC,MAAMW,WAAW1B,aAAI,CAAC2B,KAAK,CAACC,IAAI,CAACf,SAASU;IAC1C,MAAMpB,SAASN,uBAAuB6B;IACtC,MAAMG,cAAc1B,SAAS,CAAC,CAAC,EAAEA,QAAQ,GAAG;IAE5C,OAAO2B,IAAAA,kCAAgB,EAAC9B,aAAI,CAAC4B,IAAI,CAACP,OAAO,GAAGE,OAAOM,cAAcL,KAAK;AACxE;AAWO,SAAS5B,uBAAuBE,IAAY;IACjD,IAAI,CAACiC,IAAAA,+BAAc,EAACjC,OAAO;QACzB,OAAOA;IACT;IACA,IAAIuB,QAAQvB;IACZ,IAAIK,SAAS;IACb,IAAIL,SAAS,WAAW;QACtBuB,SAAS;IACX,OAAO,IAAIvB,SAAS,aAAa;QAC/BuB,SAAS;IACX,OAAO;QACLlB,SAASN,uBAAuBC;IAClC;IACA,mFAAmF;IACnF,4EAA4E;IAC5E,IAAI,CAACuB,MAAMnB,QAAQ,CAAC,WAAW;QAC7B,MAAM,EAAE8B,GAAG,EAAET,MAAMU,QAAQ,EAAET,GAAG,EAAE,GAAGxB,aAAI,CAACyB,KAAK,CAACJ;QAChDA,QAAQrB,aAAI,CAAC2B,KAAK,CAACC,IAAI,CACrBI,KACA,GAAGC,WAAW9B,SAAS,CAAC,CAAC,EAAEA,QAAQ,GAAG,KAAKqB,KAAK,EAChD;IAEJ;IAEA,OAAOH;AACT;AAOO,SAAS1B,6BAA6BG,IAAY,EAAEoC,SAAkB;IAC3E,MAAMC,UAAUrC,KAAKI,QAAQ,CAAC;IAC9B,MAAMkC,gBAAgBD,UAAUrC,KAAKc,KAAK,CAAC,GAAG,CAAC,SAASyB,MAAM,IAAIvC;IAClE,MAAMwC,yBAAyBF,cAAclC,QAAQ,CAAC,cAClD,SACA;IACJ,MAAMqC,SAASL,YACX,GAAGE,cAAc,kBAAkB,CAAC,GACpC,GAAGA,gBAAgBE,wBAAwB;IAE/C,OAAOC,SAAUJ,CAAAA,UAAU,WAAW,EAAC;AACzC","ignoreList":[0]}