@inlang/paraglide-js 2.25.4 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/compiler/runtime/create-runtime.js +24 -1
  2. package/dist/compiler/runtime/create-runtime.js.map +1 -1
  3. package/dist/compiler/runtime/extract-locale-from-url.js +11 -4
  4. package/dist/compiler/runtime/extract-locale-from-url.js.map +1 -1
  5. package/dist/compiler/runtime/generate-static-localized-urls.js +5 -3
  6. package/dist/compiler/runtime/generate-static-localized-urls.js.map +1 -1
  7. package/dist/compiler/runtime/localize-url.js +25 -54
  8. package/dist/compiler/runtime/localize-url.js.map +1 -1
  9. package/dist/compiler/runtime/route-strategy.js +9 -3
  10. package/dist/compiler/runtime/route-strategy.js.map +1 -1
  11. package/dist/compiler/runtime/type.test.js +9 -0
  12. package/dist/compiler/runtime/type.test.js.map +1 -1
  13. package/dist/compiler/runtime/url-pattern-cache.d.ts +11 -0
  14. package/dist/compiler/runtime/url-pattern-cache.js +42 -0
  15. package/dist/compiler/runtime/url-pattern-cache.js.map +1 -0
  16. package/dist/compiler/runtime/url-pattern-index.d.ts +24 -0
  17. package/dist/compiler/runtime/url-pattern-index.differential.test.d.ts +1 -0
  18. package/dist/compiler/runtime/url-pattern-index.differential.test.js +152 -0
  19. package/dist/compiler/runtime/url-pattern-index.differential.test.js.map +1 -0
  20. package/dist/compiler/runtime/url-pattern-index.js +168 -0
  21. package/dist/compiler/runtime/url-pattern-index.js.map +1 -0
  22. package/dist/compiler/runtime/url-pattern-index.test.d.ts +1 -0
  23. package/dist/compiler/runtime/url-pattern-index.test.js +262 -0
  24. package/dist/compiler/runtime/url-pattern-index.test.js.map +1 -0
  25. package/dist/compiler/server/create-server-file.js +1 -1
  26. package/dist/compiler/server/create-server-file.js.map +1 -1
  27. package/dist/compiler/server/create-server-file.test.js +12 -0
  28. package/dist/compiler/server/create-server-file.test.js.map +1 -1
  29. package/dist/services/env-variables/index.js +1 -1
  30. package/dist/services/env-variables/index.js.map +1 -1
  31. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"localize-url.js","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-url.js"],"names":[],"mappings":"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","sourcesContent":["import { extractLocaleFromUrl } from \"./extract-locale-from-url.js\";\nimport { getLocale } from \"./get-locale.js\";\nimport { getUrlOrigin } from \"./get-url-origin.js\";\nimport { assertIsLocale, toLocale } from \"./check-locale.js\";\nimport {\n\tbaseLocale,\n\tTREE_SHAKE_DEFAULT_URL_PATTERN_USED,\n\ttrailingSlash,\n\turlPatterns,\n} from \"./variables.js\";\nimport { normalizeTrailingSlash } from \"./normalize-trailing-slash.js\";\nimport { execUrlPattern } from \"./exec-url-pattern.js\";\n\n/**\n * Lower-level URL localization function, primarily used in server contexts.\n *\n * This function is designed for server-side usage where you need precise control\n * over URL localization, such as in middleware or request handlers. It works with\n * URL objects and always returns absolute URLs.\n *\n * For client-side UI components, use `localizeHref()` instead, which provides\n * a more convenient API with relative paths and automatic locale detection.\n *\n * @see https://paraglidejs.com/i18n-routing\n *\n * @example\n * ```typescript\n * // Server middleware example\n * app.use((req, res, next) => {\n * const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);\n * const localized = localizeUrl(url, { locale: \"de\" });\n *\n * if (localized.href !== url.href) {\n * return res.redirect(localized.href);\n * }\n * next();\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Using with URL patterns\n * const url = new URL(\"https://example.com/about\");\n * localizeUrl(url, { locale: \"de\" });\n * // => URL(\"https://example.com/de/about\")\n *\n * // Using with domain-based localization\n * const url = new URL(\"https://example.com/store\");\n * localizeUrl(url, { locale: \"de\" });\n * // => URL(\"https://de.example.com/store\")\n * ```\n *\n * @param {string | URL} url - The URL to localize. If string, must be absolute.\n * @param {object} [options] - Options for localization\n * @param {Locale} [options.locale] - Target locale. If not provided, uses getLocale()\n * @returns {URL} The localized URL, always absolute\n */\nexport function localizeUrl(url, options) {\n\tconst targetLocale = options?.locale\n\t\t? assertIsLocale(options?.locale)\n\t\t: getLocale();\n\n\tif (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {\n\t\treturn localizeUrlDefaultPattern(url, targetLocale);\n\t}\n\n\tconst originalUrl = typeof url === \"string\" ? new URL(url) : url;\n\tconst urlObj =\n\t\ttrailingSlash === undefined\n\t\t\t? originalUrl\n\t\t\t: normalizeTrailingSlash(new URL(originalUrl));\n\n\t// Iterate over URL patterns\n\tfor (const element of urlPatterns) {\n\t\t// Most applications use a locale prefix (and sometimes a fixed domain)\n\t\t// with a trailing catch-all path. Those routes do not need URLPattern's\n\t\t// parser or matcher on every call. Keep the generic matcher below as the\n\t\t// fallback for every other URLPattern shape. This stays inside the outer\n\t\t// loop so specific patterns retain precedence over a later catch-all.\n\t\tconst fastPathLocalized = localizeUrlFastPath(\n\t\t\turlObj,\n\t\t\ttargetLocale,\n\t\t\telement\n\t\t);\n\t\tif (fastPathLocalized !== undefined) {\n\t\t\treturn fastPathLocalized;\n\t\t}\n\n\t\t// match localized patterns\n\t\tfor (const [, localizedPattern] of element.localized) {\n\t\t\tconst match = execUrlPattern(\n\t\t\t\tgetUrlPattern(localizedPattern, urlObj),\n\t\t\t\turlObj\n\t\t\t);\n\n\t\t\tif (!match) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst targetPattern = element.localized.find(\n\t\t\t\t([locale]) => locale === targetLocale\n\t\t\t)?.[1];\n\n\t\t\tif (!targetPattern) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst localizedUrl = fillPattern(\n\t\t\t\ttargetPattern,\n\t\t\t\taggregateGroups(match),\n\t\t\t\turlObj.origin\n\t\t\t);\n\t\t\treturn normalizeTrailingSlash(fillMissingUrlParts(localizedUrl, match));\n\t\t}\n\t\tconst unlocalizedMatch = execUrlPattern(\n\t\t\tgetUrlPattern(element.pattern, urlObj),\n\t\t\turlObj\n\t\t);\n\t\tif (unlocalizedMatch) {\n\t\t\tconst targetPattern = element.localized.find(\n\t\t\t\t([locale]) => locale === targetLocale\n\t\t\t)?.[1];\n\t\t\tif (targetPattern) {\n\t\t\t\tconst localizedUrl = fillPattern(\n\t\t\t\t\ttargetPattern,\n\t\t\t\t\taggregateGroups(unlocalizedMatch),\n\t\t\t\t\turlObj.origin\n\t\t\t\t);\n\t\t\t\treturn normalizeTrailingSlash(\n\t\t\t\t\tfillMissingUrlParts(localizedUrl, unlocalizedMatch)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\t// If no match found, return the original URL\n\treturn originalUrl;\n}\n\n/**\n * https://github.com/opral/inlang-paraglide-js/issues/381\n *\n * @param {string | URL} url\n * @param {Locale} locale\n * @returns {URL}\n */\nfunction localizeUrlDefaultPattern(url, locale) {\n\tconst urlObj = normalizeTrailingSlash(\n\t\ttypeof url === \"string\" ? new URL(url, getUrlOrigin()) : new URL(url)\n\t);\n\n\tconst currentLocale = extractLocaleFromUrl(urlObj);\n\n\t// If current locale matches target locale, no change needed\n\tif (currentLocale === locale) {\n\t\treturn normalizeTrailingSlash(urlObj);\n\t}\n\n\t// Ignore leading separators like locale detection, preserving the remaining path.\n\tconst pathSegments = urlObj.pathname.replace(/^\\/+/, \"\").split(\"/\");\n\n\t// If current path starts with a locale, remove it\n\tif (pathSegments.length > 0 && toLocale(pathSegments[0])) {\n\t\tpathSegments.shift();\n\t}\n\n\t// For base locale, don't add prefix\n\tif (locale === baseLocale) {\n\t\turlObj.pathname = \"/\" + pathSegments.join(\"/\");\n\t} else {\n\t\t// For other locales, add prefix\n\t\turlObj.pathname = \"/\" + locale + \"/\" + pathSegments.join(\"/\");\n\t}\n\n\treturn normalizeTrailingSlash(urlObj);\n}\n\n/**\n * Low-level URL de-localization function, primarily used in server contexts.\n *\n * This function is designed for server-side usage where you need precise control\n * over URL de-localization, such as in middleware or request handlers. It works with\n * URL objects and always returns absolute URLs.\n *\n * For client-side UI components, use `deLocalizeHref()` instead, which provides\n * a more convenient API with relative paths.\n *\n * @see https://paraglidejs.com/i18n-routing\n *\n * @example\n * ```typescript\n * // Server middleware example\n * app.use((req, res, next) => {\n * const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);\n * const baseUrl = deLocalizeUrl(url);\n *\n * // Store the base URL for later use\n * req.baseUrl = baseUrl;\n * next();\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Using with URL patterns\n * const url = new URL(\"https://example.com/de/about\");\n * deLocalizeUrl(url); // => URL(\"https://example.com/about\")\n *\n * // Using with domain-based localization\n * const url = new URL(\"https://de.example.com/store\");\n * deLocalizeUrl(url); // => URL(\"https://example.com/store\")\n * ```\n *\n * @param {string | URL} url - The URL to de-localize. If string, must be absolute.\n * @returns {URL} The de-localized URL, always absolute\n */\nexport function deLocalizeUrl(url) {\n\tif (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {\n\t\treturn deLocalizeUrlDefaultPattern(url);\n\t}\n\n\tconst originalUrl = typeof url === \"string\" ? new URL(url) : url;\n\tconst urlObj =\n\t\ttrailingSlash === undefined\n\t\t\t? originalUrl\n\t\t\t: normalizeTrailingSlash(new URL(originalUrl));\n\n\t// Iterate over URL patterns\n\tfor (const element of urlPatterns) {\n\t\tconst fastPathDeLocalized = deLocalizeUrlFastPath(urlObj, element);\n\t\tif (fastPathDeLocalized !== undefined) {\n\t\t\treturn fastPathDeLocalized;\n\t\t}\n\n\t\t// Iterate over localized versions\n\t\tfor (const [, localizedPattern] of element.localized) {\n\t\t\tconst match = execUrlPattern(\n\t\t\t\tgetUrlPattern(localizedPattern, urlObj),\n\t\t\t\turlObj\n\t\t\t);\n\n\t\t\tif (match) {\n\t\t\t\t// Convert localized URL back to the base pattern\n\t\t\t\tconst groups = aggregateGroups(match);\n\n\t\t\t\tconst baseUrl = fillPattern(element.pattern, groups, urlObj.origin);\n\t\t\t\treturn normalizeTrailingSlash(fillMissingUrlParts(baseUrl, match));\n\t\t\t}\n\t\t}\n\t\t// match unlocalized pattern\n\t\tconst unlocalizedMatch = execUrlPattern(\n\t\t\tgetUrlPattern(element.pattern, urlObj),\n\t\t\turlObj\n\t\t);\n\t\tif (unlocalizedMatch) {\n\t\t\tconst baseUrl = fillPattern(\n\t\t\t\telement.pattern,\n\t\t\t\taggregateGroups(unlocalizedMatch),\n\t\t\t\turlObj.origin\n\t\t\t);\n\t\t\treturn normalizeTrailingSlash(\n\t\t\t\tfillMissingUrlParts(baseUrl, unlocalizedMatch)\n\t\t\t);\n\t\t}\n\t}\n\t// no match found return the original url\n\treturn originalUrl;\n}\n\n/**\n * De-localizes a URL using the default pattern (/:locale/*)\n * @param {string|URL} url\n * @returns {URL}\n */\nfunction deLocalizeUrlDefaultPattern(url) {\n\tconst urlObj = normalizeTrailingSlash(\n\t\ttypeof url === \"string\" ? new URL(url, getUrlOrigin()) : new URL(url)\n\t);\n\t// Ignore leading separators like locale detection, preserving the remaining path.\n\tconst pathSegments = urlObj.pathname.replace(/^\\/+/, \"\").split(\"/\");\n\n\t// If first segment is a locale, remove it\n\tif (pathSegments.length > 0 && toLocale(pathSegments[0])) {\n\t\turlObj.pathname = \"/\" + pathSegments.slice(1).join(\"/\");\n\t}\n\n\treturn normalizeTrailingSlash(urlObj);\n}\n\n/**\n * Takes matches of implicit wildcards in the UrlPattern (when a part is missing\n * it is equal to '*') and adds them back to the result of fillPattern.\n *\n * At least protocol and hostname are required to create a valid URL inside fillPattern.\n *\n * @param {URL} url\n * @param {any} match\n * @returns {URL}\n */\nfunction fillMissingUrlParts(url, match) {\n\tif (match.protocol.groups[\"0\"]) {\n\t\turl.protocol = match.protocol.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.hostname.groups[\"0\"]) {\n\t\turl.hostname = match.hostname.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.username.groups[\"0\"]) {\n\t\turl.username = match.username.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.password.groups[\"0\"]) {\n\t\turl.password = match.password.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.port.groups[\"0\"]) {\n\t\turl.port = match.port.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.pathname.groups[\"0\"]) {\n\t\turl.pathname = match.pathname.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.search.groups[\"0\"]) {\n\t\turl.search = match.search.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.hash.groups[\"0\"]) {\n\t\turl.hash = match.hash.groups[\"0\"] ?? \"\";\n\t}\n\n\treturn url;\n}\n\n/**\n * Fills a URL pattern with values for named groups, supporting all URLPattern-style modifiers.\n *\n * This function will eventually be replaced by https://github.com/whatwg/urlpattern/issues/73\n *\n * Matches:\n * - :name -> Simple\n * - :name? -> Optional\n * - :name+ -> One or more\n * - :name* -> Zero or more\n * - :name(...) -> Regex group\n * - {text} -> Group delimiter\n * - {text}? -> Optional group delimiter\n *\n * If the value is `null`, the segment is removed.\n *\n * @param {string} pattern - The URL pattern containing named groups.\n * @param {Record<string, string | null | undefined>} values - Object of values for named groups.\n * @param {string} origin - Base URL to use for URL construction.\n * @returns {URL} - The constructed URL with named groups filled.\n */\nfunction fillPattern(pattern, values, origin) {\n\t// Pre-process the pattern to handle explicit port numbers\n\t// This detects patterns like \"http://localhost:5173\" and protects the port number\n\t// from being interpreted as a parameter\n\tlet processedPattern = pattern.replace(\n\t\t/(https?:\\/\\/[^:/]+):(\\d+)(\\/|$)/g,\n\t\t(_, protocol, port, slash) => {\n\t\t\t// Replace \":5173\" with \"#PORT-5173#\" to protect it from parameter replacement\n\t\t\treturn `${protocol}#PORT-${port}#${slash}`;\n\t\t}\n\t);\n\n\t// First, handle group delimiters with curly braces\n\tlet processedGroupDelimiters = processedPattern.replace(\n\t\t/\\{([^{}]*)\\}([?+*]?)/g,\n\t\t(_, content, modifier) => {\n\t\t\t// For optional group delimiters\n\t\t\tif (modifier === \"?\") {\n\t\t\t\t// For optional groups, we'll include the content\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\t// For non-optional group delimiters, always include the content\n\t\t\treturn content;\n\t\t}\n\t);\n\n\t// Then handle named groups\n\tlet filled = processedGroupDelimiters.replace(\n\t\t/(\\/?):([a-zA-Z0-9_]+)(\\([^)]*\\))?([?+*]?)/g,\n\t\t(_, slash, name, __, modifier) => {\n\t\t\tconst value = values[name];\n\n\t\t\tif (value === null) {\n\t\t\t\t// If value is null, remove the entire segment including the preceding slash\n\t\t\t\treturn \"\";\n\t\t\t}\n\n\t\t\tif (modifier === \"?\") {\n\t\t\t\t// Optional segment\n\t\t\t\treturn value !== undefined ? `${slash}${value}` : \"\";\n\t\t\t}\n\n\t\t\tif (modifier === \"+\" || modifier === \"*\") {\n\t\t\t\t// Repeatable segments\n\t\t\t\tif (value === undefined && modifier === \"+\") {\n\t\t\t\t\tthrow new Error(`Missing value for \"${name}\" (one or more required)`);\n\t\t\t\t}\n\t\t\t\treturn value ? `${slash}${value}` : \"\";\n\t\t\t}\n\n\t\t\t// Simple named group (no modifier)\n\t\t\tif (value === undefined) {\n\t\t\t\tthrow new Error(`Missing value for \"${name}\"`);\n\t\t\t}\n\n\t\t\treturn `${slash}${value}`;\n\t\t}\n\t);\n\n\t// Restore port numbers\n\tfilled = filled.replace(/#PORT-(\\d+)#/g, \":$1\");\n\n\treturn new URL(filled, origin);\n}\n\n/**\n * Aggregates named groups from various parts of the URLPattern match result.\n *\n *\n * @param {any} match - The URLPattern match result object.\n * @returns {Record<string, string | null | undefined>} An object containing all named groups from the match.\n */\nexport function aggregateGroups(match) {\n\treturn {\n\t\t...match.hash.groups,\n\t\t...match.hostname.groups,\n\t\t...match.password.groups,\n\t\t...match.pathname.groups,\n\t\t...match.port.groups,\n\t\t...match.protocol.groups,\n\t\t...match.search.groups,\n\t\t...match.username.groups,\n\t};\n}\n\n/** @type {Map<string, URLPattern>} */\nconst urlPatternCache = new Map();\n\nconst URL_PATTERN_CACHE_LIMIT = 128;\nconst ABSOLUTE_URL_PATTERN = /^(?:[A-Za-z][A-Za-z\\d+.-]*|:[A-Za-z][A-Za-z\\d_-]*):\\/\\//;\n\n/**\n * URLPattern's base URL affects relative patterns. Absolute patterns only\n * depend on the pattern itself, while root-relative patterns also depend on\n * the URL origin. Other relative patterns are deliberately not cached because\n * their semantics depend on the complete base URL.\n *\n * @param {string} pattern\n * @param {URL} url\n * @returns {URLPattern}\n */\nfunction getUrlPattern(pattern, url) {\n\tconst isAbsolutePattern = ABSOLUTE_URL_PATTERN.test(pattern);\n\tconst isRootRelativePattern = pattern.startsWith(\"/\");\n\tif (!isAbsolutePattern && !isRootRelativePattern) {\n\t\treturn new URLPattern(pattern, url.href);\n\t}\n\n\tconst key = isAbsolutePattern\n\t\t? pattern\n\t\t: JSON.stringify([url.origin, pattern]);\n\tconst cached = urlPatternCache.get(key);\n\tif (cached !== undefined) {\n\t\t// Refresh the entry so frequently used patterns stay in the bounded cache.\n\t\turlPatternCache.delete(key);\n\t\turlPatternCache.set(key, cached);\n\t\treturn cached;\n\t}\n\n\tconst compiled = new URLPattern(pattern, url.href);\n\tif (urlPatternCache.size >= URL_PATTERN_CACHE_LIMIT) {\n\t\tconst oldestKey = urlPatternCache.keys().next().value;\n\t\tif (oldestKey !== undefined) urlPatternCache.delete(oldestKey);\n\t}\n\turlPatternCache.set(key, compiled);\n\treturn compiled;\n}\n\n/**\n * A small, deliberately conservative subset of URLPattern routing.\n *\n * The compiler emits routes such as `/:path(.*)?`, `/de/:path*`, or\n * `https://example.com/:path*`. For those routes matching is equivalent to a\n * pathname prefix check and (optionally) an origin check. Everything that has\n * a dynamic host, a custom path regexp, or another URLPattern modifier keeps\n * using the generic implementation above.\n *\n * @typedef {{\n * protocol: string | undefined;\n * hostname: string | undefined;\n * port: string | undefined;\n * pathnamePrefix: string;\n * pathMode: \"segments\" | \"catch-all-optional\" | \"catch-all-required\";\n * }} FastPathPattern\n * @typedef {{\n * base: FastPathPattern;\n * localized: Array<{ locale: string; pattern: FastPathPattern }>;\n * }} FastPathRoute\n */\n\n/** @type {WeakMap<object, FastPathRoute | null>} */\nconst fastPathRouteCache = new WeakMap();\n\n/**\n * @param {URL} urlObj\n * @param {string} targetLocale\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {URL | undefined}\n */\nfunction localizeUrlFastPath(urlObj, targetLocale, element) {\n\tconst route = getFastPathRoute(element);\n\tif (route === null) return undefined;\n\n\t// Preserve URLPattern's ordering: localized patterns are checked before\n\t// the unlocalized pattern, and the first matching pattern wins.\n\tfor (const localized of route.localized) {\n\t\tconst suffix = matchFastPathPattern(localized.pattern, urlObj);\n\t\tif (suffix === undefined) continue;\n\n\t\tconst target = route.localized.find(\n\t\t\t(candidate) => candidate.locale === targetLocale\n\t\t)?.pattern;\n\t\tif (target === undefined) continue;\n\n\t\treturn applyFastPathPattern(target, suffix, urlObj);\n\t}\n\n\tconst suffix = matchFastPathPattern(route.base, urlObj);\n\tif (suffix !== undefined) {\n\t\tconst target = route.localized.find(\n\t\t\t(candidate) => candidate.locale === targetLocale\n\t\t)?.pattern;\n\t\tif (target !== undefined) {\n\t\t\treturn applyFastPathPattern(target, suffix, urlObj);\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\n/**\n * @param {URL} urlObj\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {URL | undefined}\n */\nfunction deLocalizeUrlFastPath(urlObj, element) {\n\tconst route = getFastPathRoute(element);\n\tif (route === null) return undefined;\n\n\tfor (const localized of route.localized) {\n\t\tconst suffix = matchFastPathPattern(localized.pattern, urlObj);\n\t\tif (suffix !== undefined) {\n\t\t\treturn applyFastPathPattern(route.base, suffix, urlObj);\n\t\t}\n\t}\n\n\tconst suffix = matchFastPathPattern(route.base, urlObj);\n\tif (suffix !== undefined) {\n\t\treturn applyFastPathPattern(route.base, suffix, urlObj);\n\t}\n\n\treturn undefined;\n}\n\n/**\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {FastPathRoute | null}\n */\nfunction getFastPathRoute(element) {\n\tconst cached = fastPathRouteCache.get(element);\n\tif (cached !== undefined) return cached;\n\n\tconst base = parseFastPathPattern(element.pattern);\n\tif (base === undefined) {\n\t\tfastPathRouteCache.set(element, null);\n\t\treturn null;\n\t}\n\n\tconst localized = [];\n\tfor (const [locale, pattern] of element.localized) {\n\t\tconst parsed = parseFastPathPattern(pattern);\n\t\tif (parsed === undefined || parsed.pathMode !== base.pathMode) {\n\t\t\tfastPathRouteCache.set(element, null);\n\t\t\treturn null;\n\t\t}\n\t\tlocalized.push({ locale, pattern: parsed });\n\t}\n\n\tconst route = { base, localized };\n\tfastPathRouteCache.set(element, route);\n\treturn route;\n}\n\n/**\n * Parse only catch-all path patterns. In particular, do not treat `:path(.)?`\n * as a catch-all: URLPattern's `(.)` means exactly one character and cannot be\n * represented by this prefix matcher without changing routing semantics.\n *\n * @param {string} pattern\n * @returns {FastPathPattern | undefined}\n */\nfunction parseFastPathPattern(pattern) {\n\tconst wildcard = pattern.match(/\\/:path(?:\\(\\.\\*\\)(?:\\?)?|\\*)$/);\n\tif (wildcard === null || wildcard.index === undefined) return undefined;\n\n\tconst prefix = pattern.slice(0, wildcard.index);\n\tconst originAndPath = parseFastPathOriginAndPath(prefix);\n\tif (originAndPath === undefined) return undefined;\n\tconst pathMode = wildcard[0].endsWith(\"*\")\n\t\t? \"segments\"\n\t\t: wildcard[0].endsWith(\"?\")\n\t\t\t? \"catch-all-optional\"\n\t\t\t: \"catch-all-required\";\n\n\treturn { ...originAndPath, pathMode };\n}\n\n/**\n * @param {string} prefix\n * @returns {FastPathPattern | undefined}\n */\nfunction parseFastPathOriginAndPath(prefix) {\n\tif (prefix === \"\" || prefix.startsWith(\"/\")) {\n\t\tif (hasUrlPatternSyntax(prefix)) return undefined;\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\thostname: undefined,\n\t\t\tport: undefined,\n\t\t\tpathnamePrefix: normalizePathPrefix(prefix),\n\t\t\tpathMode: \"catch-all-optional\",\n\t\t};\n\t}\n\n\t// A `:protocol://host` pattern is common in generated configurations. The\n\t// protocol is intentionally left unconstrained, just like URLPattern.\n\tconst dynamicProtocol = prefix.match(/^:protocol:\\/\\/([^/]+)(\\/.*)?$/);\n\tconst staticOrigin = prefix.match(\n\t\t/^([A-Za-z][A-Za-z\\d+.-]*):\\/\\/([^/]+)(\\/.*)?$/\n\t);\n\tif (dynamicProtocol !== null) {\n\t\tconst dynamicHost = dynamicProtocol[1] ?? \"\";\n\t\tconst hostMatch = dynamicHost.match(/^([^:(){}?*+]+)(?::(\\d+))?$/);\n\t\tif (\n\t\t\thostMatch === null ||\n\t\t\t(dynamicProtocol[2] !== undefined &&\n\t\t\t\thasUrlPatternSyntax(dynamicProtocol[2]))\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\thostname: (hostMatch[1] ?? \"\").toLowerCase(),\n\t\t\tport: hostMatch[2],\n\t\t\tpathnamePrefix: normalizePathPrefix(dynamicProtocol[2] ?? \"\"),\n\t\t\tpathMode: \"catch-all-optional\",\n\t\t};\n\t}\n\n\tif (staticOrigin === null) return undefined;\n\n\tconst host = staticOrigin[2] ?? \"\";\n\tconst pathname = staticOrigin[3];\n\tconst hostMatch = host.match(/^([^:(){}?*+]+)(?::(\\d+))?$/);\n\tif (\n\t\thostMatch === null ||\n\t\t(pathname !== undefined && hasUrlPatternSyntax(pathname))\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tprotocol: `${staticOrigin[1]}:`,\n\t\thostname: (hostMatch[1] ?? \"\").toLowerCase(),\n\t\tport: normalizePatternPort(hostMatch[2], `${staticOrigin[1]}:`),\n\t\tpathnamePrefix: normalizePathPrefix(pathname ?? \"\"),\n\t\tpathMode: \"catch-all-optional\",\n\t};\n}\n\n/**\n * @param {string | undefined} port\n * @param {string} protocol\n * @returns {string | undefined}\n */\nfunction normalizePatternPort(port, protocol) {\n\tif (port === \"80\" && protocol === \"http:\") return \"\";\n\tif (port === \"443\" && protocol === \"https:\") return \"\";\n\treturn port;\n}\n\n/**\n * @param {string} value\n * @returns {boolean}\n */\nfunction hasUrlPatternSyntax(value) {\n\treturn /[:(){}?*+]/.test(value);\n}\n\n/**\n * @param {string} pathname\n * @returns {string}\n */\nfunction normalizePathPrefix(pathname) {\n\tif (pathname === \"\" || pathname === \"/\") return \"/\";\n\treturn pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n}\n\n/**\n * @param {FastPathPattern} pattern\n * @param {URL} urlObj\n * @returns {string | undefined}\n */\nfunction matchFastPathPattern(pattern, urlObj) {\n\tif (pattern.protocol !== undefined && pattern.protocol !== urlObj.protocol) {\n\t\treturn undefined;\n\t}\n\tif (\n\t\tpattern.hostname !== undefined &&\n\t\tpattern.hostname !== urlObj.hostname.toLowerCase()\n\t) {\n\t\treturn undefined;\n\t}\n\tif (pattern.hostname !== undefined) {\n\t\tconst expectedPort =\n\t\t\tpattern.port ?? defaultPortForProtocol(pattern.protocol ?? urlObj.protocol);\n\t\tif (expectedPort !== urlObj.port) return undefined;\n\t}\n\n\tconst prefix = pattern.pathnamePrefix;\n\tif (prefix === \"/\") {\n\t\tif (urlObj.pathname.startsWith(\"//\")) return undefined;\n\t\tif (pattern.pathMode === \"segments\") {\n\t\t\treturn isNonEmptyPathSegments(urlObj.pathname)\n\t\t\t\t? urlObj.pathname\n\t\t\t\t: undefined;\n\t\t}\n\t\treturn urlObj.pathname;\n\t}\n\tif (urlObj.pathname === prefix) {\n\t\treturn pattern.pathMode === \"catch-all-required\" ? undefined : \"\";\n\t}\n\tif (urlObj.pathname.startsWith(`${prefix}/`)) {\n\t\tconst suffix = urlObj.pathname.slice(prefix.length);\n\t\tif (suffix.startsWith(\"//\")) return undefined;\n\t\tif (\n\t\t\tpattern.pathMode === \"segments\" &&\n\t\t\t!isNonEmptyPathSegments(suffix)\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn suffix;\n\t}\n\treturn undefined;\n}\n\n/**\n * @param {string} pathname\n * @returns {boolean}\n */\nfunction isNonEmptyPathSegments(pathname) {\n\treturn pathname.length > 1 && !pathname.endsWith(\"/\") && !pathname.includes(\"//\");\n}\n\n/**\n * URLPattern treats the default port as empty in URL instances.\n *\n * @param {string} protocol\n * @returns {string}\n */\nfunction defaultPortForProtocol(protocol) {\n\tif (protocol === \"http:\") return \"\";\n\tif (protocol === \"https:\") return \"\";\n\treturn \"\";\n}\n\n/**\n * @param {FastPathPattern} pattern\n * @param {string} suffix\n * @param {URL} source\n * @returns {URL}\n */\nfunction applyFastPathPattern(pattern, suffix, source) {\n\tconst localized = new URL(source.href);\n\tif (pattern.protocol !== undefined) localized.protocol = pattern.protocol;\n\tif (pattern.hostname !== undefined) {\n\t\tlocalized.hostname = pattern.hostname;\n\t\tlocalized.port =\n\t\t\tpattern.port ?? defaultPortForProtocol(localized.protocol);\n\t}\n\tlocalized.pathname = joinFastPathPrefix(pattern.pathnamePrefix, suffix);\n\treturn localized;\n}\n\n/**\n * @param {string} prefix\n * @param {string} suffix\n * @returns {string}\n */\nfunction joinFastPathPrefix(prefix, suffix) {\n\tif (prefix === \"/\") return suffix === \"\" ? \"/\" : suffix;\n\tif (suffix === \"\") return prefix;\n\treturn `${prefix}${suffix.startsWith(\"/\") ? suffix : `/${suffix}`}`;\n}\n"]}
1
+ {"version":3,"file":"localize-url.js","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-url.js"],"names":[],"mappings":"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","sourcesContent":["import { extractLocaleFromUrl } from \"./extract-locale-from-url.js\";\nimport { getLocale } from \"./get-locale.js\";\nimport { getUrlOrigin } from \"./get-url-origin.js\";\nimport { assertIsLocale, toLocale } from \"./check-locale.js\";\nimport {\n\tbaseLocale,\n\tTREE_SHAKE_DEFAULT_URL_PATTERN_USED,\n\ttrailingSlash,\n} from \"./variables.js\";\nimport { normalizeTrailingSlash } from \"./normalize-trailing-slash.js\";\nimport { execUrlPattern } from \"./exec-url-pattern.js\";\nimport { getUrlPattern } from \"./url-pattern-cache.js\";\nimport {\n\tgetUrlPatternCandidates,\n\tcurrentRoutingConfigVersion,\n} from \"./url-pattern-index.js\";\n\n/**\n * Lower-level URL localization function, primarily used in server contexts.\n *\n * This function is designed for server-side usage where you need precise control\n * over URL localization, such as in middleware or request handlers. It works with\n * URL objects and always returns absolute URLs.\n *\n * For client-side UI components, use `localizeHref()` instead, which provides\n * a more convenient API with relative paths and automatic locale detection.\n *\n * @see https://paraglidejs.com/i18n-routing\n *\n * @example\n * ```typescript\n * // Server middleware example\n * app.use((req, res, next) => {\n * const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);\n * const localized = localizeUrl(url, { locale: \"de\" });\n *\n * if (localized.href !== url.href) {\n * return res.redirect(localized.href);\n * }\n * next();\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Using with URL patterns\n * const url = new URL(\"https://example.com/about\");\n * localizeUrl(url, { locale: \"de\" });\n * // => URL(\"https://example.com/de/about\")\n *\n * // Using with domain-based localization\n * const url = new URL(\"https://example.com/store\");\n * localizeUrl(url, { locale: \"de\" });\n * // => URL(\"https://de.example.com/store\")\n * ```\n *\n * @param {string | URL} url - The URL to localize. If string, must be absolute.\n * @param {object} [options] - Options for localization\n * @param {Locale} [options.locale] - Target locale. If not provided, uses getLocale()\n * @returns {URL} The localized URL, always absolute\n */\nexport function localizeUrl(url, options) {\n\tconst targetLocale = options?.locale\n\t\t? assertIsLocale(options?.locale)\n\t\t: getLocale();\n\n\tif (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {\n\t\treturn localizeUrlDefaultPattern(url, targetLocale);\n\t}\n\n\tconst originalUrl = typeof url === \"string\" ? new URL(url) : url;\n\tconst urlObj =\n\t\ttrailingSlash === undefined\n\t\t\t? originalUrl\n\t\t\t: normalizeTrailingSlash(new URL(originalUrl));\n\n\t// Iterate over URL patterns\n\tfor (const element of getUrlPatternCandidates(urlObj)) {\n\t\t// Most applications use a locale prefix (and sometimes a fixed domain)\n\t\t// with a trailing catch-all path. Those routes do not need URLPattern's\n\t\t// parser or matcher on every call. Keep the generic matcher below as the\n\t\t// fallback for every other URLPattern shape. This stays inside the outer\n\t\t// loop so specific patterns retain precedence over a later catch-all.\n\t\tconst fastPathLocalized = localizeUrlFastPath(\n\t\t\turlObj,\n\t\t\ttargetLocale,\n\t\t\telement\n\t\t);\n\t\tif (fastPathLocalized !== undefined) {\n\t\t\treturn fastPathLocalized;\n\t\t}\n\n\t\t// match localized patterns\n\t\tfor (const [, localizedPattern] of element.localized) {\n\t\t\tconst match = execUrlPattern(\n\t\t\t\tgetUrlPattern(localizedPattern, urlObj),\n\t\t\t\turlObj\n\t\t\t);\n\n\t\t\tif (!match) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst targetPattern = element.localized.find(\n\t\t\t\t([locale]) => locale === targetLocale\n\t\t\t)?.[1];\n\n\t\t\tif (!targetPattern) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst localizedUrl = fillPattern(\n\t\t\t\ttargetPattern,\n\t\t\t\taggregateGroups(match),\n\t\t\t\turlObj.origin\n\t\t\t);\n\t\t\treturn normalizeTrailingSlash(fillMissingUrlParts(localizedUrl, match));\n\t\t}\n\t\tconst unlocalizedMatch = execUrlPattern(\n\t\t\tgetUrlPattern(element.pattern, urlObj),\n\t\t\turlObj\n\t\t);\n\t\tif (unlocalizedMatch) {\n\t\t\tconst targetPattern = element.localized.find(\n\t\t\t\t([locale]) => locale === targetLocale\n\t\t\t)?.[1];\n\t\t\tif (targetPattern) {\n\t\t\t\tconst localizedUrl = fillPattern(\n\t\t\t\t\ttargetPattern,\n\t\t\t\t\taggregateGroups(unlocalizedMatch),\n\t\t\t\t\turlObj.origin\n\t\t\t\t);\n\t\t\t\treturn normalizeTrailingSlash(\n\t\t\t\t\tfillMissingUrlParts(localizedUrl, unlocalizedMatch)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\t// If no match found, return the original URL\n\treturn originalUrl;\n}\n\n/**\n * https://github.com/opral/inlang-paraglide-js/issues/381\n *\n * @param {string | URL} url\n * @param {Locale} locale\n * @returns {URL}\n */\nfunction localizeUrlDefaultPattern(url, locale) {\n\tconst urlObj = normalizeTrailingSlash(\n\t\ttypeof url === \"string\" ? new URL(url, getUrlOrigin()) : new URL(url)\n\t);\n\n\tconst currentLocale = extractLocaleFromUrl(urlObj);\n\n\t// If current locale matches target locale, no change needed\n\tif (currentLocale === locale) {\n\t\treturn normalizeTrailingSlash(urlObj);\n\t}\n\n\t// Ignore leading separators like locale detection, preserving the remaining path.\n\tconst pathSegments = urlObj.pathname.replace(/^\\/+/, \"\").split(\"/\");\n\n\t// If current path starts with a locale, remove it\n\tif (pathSegments.length > 0 && toLocale(pathSegments[0])) {\n\t\tpathSegments.shift();\n\t}\n\n\t// For base locale, don't add prefix\n\tif (locale === baseLocale) {\n\t\turlObj.pathname = \"/\" + pathSegments.join(\"/\");\n\t} else {\n\t\t// For other locales, add prefix\n\t\turlObj.pathname = \"/\" + locale + \"/\" + pathSegments.join(\"/\");\n\t}\n\n\treturn normalizeTrailingSlash(urlObj);\n}\n\n/**\n * Low-level URL de-localization function, primarily used in server contexts.\n *\n * This function is designed for server-side usage where you need precise control\n * over URL de-localization, such as in middleware or request handlers. It works with\n * URL objects and always returns absolute URLs.\n *\n * For client-side UI components, use `deLocalizeHref()` instead, which provides\n * a more convenient API with relative paths.\n *\n * @see https://paraglidejs.com/i18n-routing\n *\n * @example\n * ```typescript\n * // Server middleware example\n * app.use((req, res, next) => {\n * const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);\n * const baseUrl = deLocalizeUrl(url);\n *\n * // Store the base URL for later use\n * req.baseUrl = baseUrl;\n * next();\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Using with URL patterns\n * const url = new URL(\"https://example.com/de/about\");\n * deLocalizeUrl(url); // => URL(\"https://example.com/about\")\n *\n * // Using with domain-based localization\n * const url = new URL(\"https://de.example.com/store\");\n * deLocalizeUrl(url); // => URL(\"https://example.com/store\")\n * ```\n *\n * @param {string | URL} url - The URL to de-localize. If string, must be absolute.\n * @returns {URL} The de-localized URL, always absolute\n */\nexport function deLocalizeUrl(url) {\n\tif (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {\n\t\treturn deLocalizeUrlDefaultPattern(url);\n\t}\n\n\tconst originalUrl = typeof url === \"string\" ? new URL(url) : url;\n\tconst urlObj =\n\t\ttrailingSlash === undefined\n\t\t\t? originalUrl\n\t\t\t: normalizeTrailingSlash(new URL(originalUrl));\n\n\t// Iterate over URL patterns\n\tfor (const element of getUrlPatternCandidates(urlObj)) {\n\t\tconst fastPathDeLocalized = deLocalizeUrlFastPath(urlObj, element);\n\t\tif (fastPathDeLocalized !== undefined) {\n\t\t\treturn fastPathDeLocalized;\n\t\t}\n\n\t\t// Iterate over localized versions\n\t\tfor (const [, localizedPattern] of element.localized) {\n\t\t\tconst match = execUrlPattern(\n\t\t\t\tgetUrlPattern(localizedPattern, urlObj),\n\t\t\t\turlObj\n\t\t\t);\n\n\t\t\tif (match) {\n\t\t\t\t// Convert localized URL back to the base pattern\n\t\t\t\tconst groups = aggregateGroups(match);\n\n\t\t\t\tconst baseUrl = fillPattern(element.pattern, groups, urlObj.origin);\n\t\t\t\treturn normalizeTrailingSlash(fillMissingUrlParts(baseUrl, match));\n\t\t\t}\n\t\t}\n\t\t// match unlocalized pattern\n\t\tconst unlocalizedMatch = execUrlPattern(\n\t\t\tgetUrlPattern(element.pattern, urlObj),\n\t\t\turlObj\n\t\t);\n\t\tif (unlocalizedMatch) {\n\t\t\tconst baseUrl = fillPattern(\n\t\t\t\telement.pattern,\n\t\t\t\taggregateGroups(unlocalizedMatch),\n\t\t\t\turlObj.origin\n\t\t\t);\n\t\t\treturn normalizeTrailingSlash(\n\t\t\t\tfillMissingUrlParts(baseUrl, unlocalizedMatch)\n\t\t\t);\n\t\t}\n\t}\n\t// no match found return the original url\n\treturn originalUrl;\n}\n\n/**\n * De-localizes a URL using the default pattern (/:locale/*)\n * @param {string|URL} url\n * @returns {URL}\n */\nfunction deLocalizeUrlDefaultPattern(url) {\n\tconst urlObj = normalizeTrailingSlash(\n\t\ttypeof url === \"string\" ? new URL(url, getUrlOrigin()) : new URL(url)\n\t);\n\t// Ignore leading separators like locale detection, preserving the remaining path.\n\tconst pathSegments = urlObj.pathname.replace(/^\\/+/, \"\").split(\"/\");\n\n\t// If first segment is a locale, remove it\n\tif (pathSegments.length > 0 && toLocale(pathSegments[0])) {\n\t\turlObj.pathname = \"/\" + pathSegments.slice(1).join(\"/\");\n\t}\n\n\treturn normalizeTrailingSlash(urlObj);\n}\n\n/**\n * Takes matches of implicit wildcards in the UrlPattern (when a part is missing\n * it is equal to '*') and adds them back to the result of fillPattern.\n *\n * At least protocol and hostname are required to create a valid URL inside fillPattern.\n *\n * @param {URL} url\n * @param {any} match\n * @returns {URL}\n */\nfunction fillMissingUrlParts(url, match) {\n\tif (match.protocol.groups[\"0\"]) {\n\t\turl.protocol = match.protocol.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.hostname.groups[\"0\"]) {\n\t\turl.hostname = match.hostname.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.username.groups[\"0\"]) {\n\t\turl.username = match.username.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.password.groups[\"0\"]) {\n\t\turl.password = match.password.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.port.groups[\"0\"]) {\n\t\turl.port = match.port.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.pathname.groups[\"0\"]) {\n\t\turl.pathname = match.pathname.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.search.groups[\"0\"]) {\n\t\turl.search = match.search.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.hash.groups[\"0\"]) {\n\t\turl.hash = match.hash.groups[\"0\"] ?? \"\";\n\t}\n\n\treturn url;\n}\n\n/**\n * Fills a URL pattern with values for named groups, supporting all URLPattern-style modifiers.\n *\n * This function will eventually be replaced by https://github.com/whatwg/urlpattern/issues/73\n *\n * Matches:\n * - :name -> Simple\n * - :name? -> Optional\n * - :name+ -> One or more\n * - :name* -> Zero or more\n * - :name(...) -> Regex group\n * - {text} -> Group delimiter\n * - {text}? -> Optional group delimiter\n *\n * If the value is `null`, the segment is removed.\n *\n * @param {string} pattern - The URL pattern containing named groups.\n * @param {Record<string, string | null | undefined>} values - Object of values for named groups.\n * @param {string} origin - Base URL to use for URL construction.\n * @returns {URL} - The constructed URL with named groups filled.\n */\nfunction fillPattern(pattern, values, origin) {\n\t// Pre-process the pattern to handle explicit port numbers\n\t// This detects patterns like \"http://localhost:5173\" and protects the port number\n\t// from being interpreted as a parameter\n\tlet processedPattern = pattern.replace(\n\t\t/(https?:\\/\\/[^:/]+):(\\d+)(\\/|$)/g,\n\t\t(_, protocol, port, slash) => {\n\t\t\t// Replace \":5173\" with \"#PORT-5173#\" to protect it from parameter replacement\n\t\t\treturn `${protocol}#PORT-${port}#${slash}`;\n\t\t}\n\t);\n\n\t// First, handle group delimiters with curly braces\n\tlet processedGroupDelimiters = processedPattern.replace(\n\t\t/\\{([^{}]*)\\}([?+*]?)/g,\n\t\t(_, content, modifier) => {\n\t\t\t// For optional group delimiters\n\t\t\tif (modifier === \"?\") {\n\t\t\t\t// For optional groups, we'll include the content\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\t// For non-optional group delimiters, always include the content\n\t\t\treturn content;\n\t\t}\n\t);\n\n\t// Then handle named groups\n\tlet filled = processedGroupDelimiters.replace(\n\t\t/(\\/?):([a-zA-Z0-9_]+)(\\([^)]*\\))?([?+*]?)/g,\n\t\t(_, slash, name, __, modifier) => {\n\t\t\tconst value = values[name];\n\n\t\t\tif (value === null) {\n\t\t\t\t// If value is null, remove the entire segment including the preceding slash\n\t\t\t\treturn \"\";\n\t\t\t}\n\n\t\t\tif (modifier === \"?\") {\n\t\t\t\t// Optional segment\n\t\t\t\treturn value !== undefined ? `${slash}${value}` : \"\";\n\t\t\t}\n\n\t\t\tif (modifier === \"+\" || modifier === \"*\") {\n\t\t\t\t// Repeatable segments\n\t\t\t\tif (value === undefined && modifier === \"+\") {\n\t\t\t\t\tthrow new Error(`Missing value for \"${name}\" (one or more required)`);\n\t\t\t\t}\n\t\t\t\treturn value ? `${slash}${value}` : \"\";\n\t\t\t}\n\n\t\t\t// Simple named group (no modifier)\n\t\t\tif (value === undefined) {\n\t\t\t\tthrow new Error(`Missing value for \"${name}\"`);\n\t\t\t}\n\n\t\t\treturn `${slash}${value}`;\n\t\t}\n\t);\n\n\t// Restore port numbers\n\tfilled = filled.replace(/#PORT-(\\d+)#/g, \":$1\");\n\n\treturn new URL(filled, origin);\n}\n\n/**\n * Aggregates named groups from various parts of the URLPattern match result.\n *\n *\n * @param {any} match - The URLPattern match result object.\n * @returns {Record<string, string | null | undefined>} An object containing all named groups from the match.\n */\nexport function aggregateGroups(match) {\n\treturn {\n\t\t...match.hash.groups,\n\t\t...match.hostname.groups,\n\t\t...match.password.groups,\n\t\t...match.pathname.groups,\n\t\t...match.port.groups,\n\t\t...match.protocol.groups,\n\t\t...match.search.groups,\n\t\t...match.username.groups,\n\t};\n}\n\n/**\n * A small, deliberately conservative subset of URLPattern routing.\n *\n * The compiler emits routes such as `/:path(.*)?`, `/de/:path*`, or\n * `https://example.com/:path*`. For those routes matching is equivalent to a\n * pathname prefix check and (optionally) an origin check. Everything that has\n * a dynamic host, a custom path regexp, or another URLPattern modifier keeps\n * using the generic implementation above.\n *\n * @typedef {{\n * protocol: string | undefined;\n * hostname: string | undefined;\n * port: string | undefined;\n * pathnamePrefix: string;\n * pathMode: \"segments\" | \"catch-all-optional\" | \"catch-all-required\";\n * }} FastPathPattern\n * @typedef {{\n * base: FastPathPattern;\n * localized: Array<{ locale: string; pattern: FastPathPattern }>;\n * }} FastPathRoute\n */\n\n/** @type {WeakMap<object, { version: number; route: FastPathRoute | null }>} */\nconst fastPathRouteCache = new WeakMap();\n\n/**\n * @param {URL} urlObj\n * @param {string} targetLocale\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {URL | undefined}\n */\nfunction localizeUrlFastPath(urlObj, targetLocale, element) {\n\tconst route = getFastPathRoute(element);\n\tif (route === null) return undefined;\n\n\t// Preserve URLPattern's ordering: localized patterns are checked before\n\t// the unlocalized pattern, and the first matching pattern wins.\n\tfor (const localized of route.localized) {\n\t\tconst suffix = matchFastPathPattern(localized.pattern, urlObj);\n\t\tif (suffix === undefined) continue;\n\n\t\tconst target = route.localized.find(\n\t\t\t(candidate) => candidate.locale === targetLocale\n\t\t)?.pattern;\n\t\tif (target === undefined) continue;\n\n\t\treturn applyFastPathPattern(target, suffix, urlObj);\n\t}\n\n\tconst suffix = matchFastPathPattern(route.base, urlObj);\n\tif (suffix !== undefined) {\n\t\tconst target = route.localized.find(\n\t\t\t(candidate) => candidate.locale === targetLocale\n\t\t)?.pattern;\n\t\tif (target !== undefined) {\n\t\t\treturn applyFastPathPattern(target, suffix, urlObj);\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\n/**\n * @param {URL} urlObj\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {URL | undefined}\n */\nfunction deLocalizeUrlFastPath(urlObj, element) {\n\tconst route = getFastPathRoute(element);\n\tif (route === null) return undefined;\n\n\tfor (const localized of route.localized) {\n\t\tconst suffix = matchFastPathPattern(localized.pattern, urlObj);\n\t\tif (suffix !== undefined) {\n\t\t\treturn applyFastPathPattern(route.base, suffix, urlObj);\n\t\t}\n\t}\n\n\tconst suffix = matchFastPathPattern(route.base, urlObj);\n\tif (suffix !== undefined) {\n\t\treturn applyFastPathPattern(route.base, suffix, urlObj);\n\t}\n\n\treturn undefined;\n}\n\n/**\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {FastPathRoute | null}\n */\nfunction getFastPathRoute(element) {\n\tconst cached = fastPathRouteCache.get(element);\n\tif (cached?.version === currentRoutingConfigVersion()) return cached.route;\n\n\tconst base = parseFastPathPattern(element.pattern);\n\tif (base === undefined) {\n\t\tfastPathRouteCache.set(element, {\n\t\t\tversion: currentRoutingConfigVersion(),\n\t\t\troute: null,\n\t\t});\n\t\treturn null;\n\t}\n\n\tconst localized = [];\n\tfor (const [locale, pattern] of element.localized) {\n\t\tconst parsed = parseFastPathPattern(pattern);\n\t\tif (parsed === undefined || parsed.pathMode !== base.pathMode) {\n\t\t\tfastPathRouteCache.set(element, {\n\t\t\t\tversion: currentRoutingConfigVersion(),\n\t\t\t\troute: null,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t\tlocalized.push({ locale, pattern: parsed });\n\t}\n\n\tconst route = { base, localized };\n\tfastPathRouteCache.set(element, {\n\t\tversion: currentRoutingConfigVersion(),\n\t\troute,\n\t});\n\treturn route;\n}\n\n/**\n * Parse only catch-all path patterns. In particular, do not treat `:path(.)?`\n * as a catch-all: URLPattern's `(.)` means exactly one character and cannot be\n * represented by this prefix matcher without changing routing semantics.\n *\n * @param {string} pattern\n * @returns {FastPathPattern | undefined}\n */\nfunction parseFastPathPattern(pattern) {\n\tconst wildcard = pattern.match(/\\/:path(?:\\(\\.\\*\\)(?:\\?)?|\\*)$/);\n\tif (wildcard === null || wildcard.index === undefined) return undefined;\n\n\tconst prefix = pattern.slice(0, wildcard.index);\n\tconst originAndPath = parseFastPathOriginAndPath(prefix);\n\tif (originAndPath === undefined) return undefined;\n\tconst pathMode = wildcard[0].endsWith(\"*\")\n\t\t? \"segments\"\n\t\t: wildcard[0].endsWith(\"?\")\n\t\t\t? \"catch-all-optional\"\n\t\t\t: \"catch-all-required\";\n\n\treturn { ...originAndPath, pathMode };\n}\n\n/**\n * @param {string} prefix\n * @returns {FastPathPattern | undefined}\n */\nfunction parseFastPathOriginAndPath(prefix) {\n\tif (prefix === \"\" || prefix.startsWith(\"/\")) {\n\t\tif (hasUrlPatternSyntax(prefix)) return undefined;\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\thostname: undefined,\n\t\t\tport: undefined,\n\t\t\tpathnamePrefix: normalizePathPrefix(prefix),\n\t\t\tpathMode: \"catch-all-optional\",\n\t\t};\n\t}\n\n\t// A `:protocol://host` pattern is common in generated configurations. The\n\t// protocol is intentionally left unconstrained, just like URLPattern.\n\tconst dynamicProtocol = prefix.match(/^:protocol:\\/\\/([^/]+)(\\/.*)?$/);\n\tconst staticOrigin = prefix.match(\n\t\t/^([A-Za-z][A-Za-z\\d+.-]*):\\/\\/([^/]+)(\\/.*)?$/\n\t);\n\tif (dynamicProtocol !== null) {\n\t\tconst dynamicHost = dynamicProtocol[1] ?? \"\";\n\t\tconst hostMatch = dynamicHost.match(/^([^:(){}?*+]+)(?::(\\d+))?$/);\n\t\tif (\n\t\t\thostMatch === null ||\n\t\t\t(dynamicProtocol[2] !== undefined &&\n\t\t\t\thasUrlPatternSyntax(dynamicProtocol[2]))\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\thostname: (hostMatch[1] ?? \"\").toLowerCase(),\n\t\t\tport: hostMatch[2],\n\t\t\tpathnamePrefix: normalizePathPrefix(dynamicProtocol[2] ?? \"\"),\n\t\t\tpathMode: \"catch-all-optional\",\n\t\t};\n\t}\n\n\tif (staticOrigin === null) return undefined;\n\n\tconst host = staticOrigin[2] ?? \"\";\n\tconst pathname = staticOrigin[3];\n\tconst hostMatch = host.match(/^([^:(){}?*+]+)(?::(\\d+))?$/);\n\tif (\n\t\thostMatch === null ||\n\t\t(pathname !== undefined && hasUrlPatternSyntax(pathname))\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tprotocol: `${staticOrigin[1]}:`,\n\t\thostname: (hostMatch[1] ?? \"\").toLowerCase(),\n\t\tport: normalizePatternPort(hostMatch[2], `${staticOrigin[1]}:`),\n\t\tpathnamePrefix: normalizePathPrefix(pathname ?? \"\"),\n\t\tpathMode: \"catch-all-optional\",\n\t};\n}\n\n/**\n * @param {string | undefined} port\n * @param {string} protocol\n * @returns {string | undefined}\n */\nfunction normalizePatternPort(port, protocol) {\n\tif (port === \"80\" && protocol === \"http:\") return \"\";\n\tif (port === \"443\" && protocol === \"https:\") return \"\";\n\treturn port;\n}\n\n/**\n * @param {string} value\n * @returns {boolean}\n */\nfunction hasUrlPatternSyntax(value) {\n\treturn /[:(){}?*+]/.test(value);\n}\n\n/**\n * @param {string} pathname\n * @returns {string}\n */\nfunction normalizePathPrefix(pathname) {\n\tif (pathname === \"\" || pathname === \"/\") return \"/\";\n\treturn pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n}\n\n/**\n * @param {FastPathPattern} pattern\n * @param {URL} urlObj\n * @returns {string | undefined}\n */\nfunction matchFastPathPattern(pattern, urlObj) {\n\tif (pattern.protocol !== undefined && pattern.protocol !== urlObj.protocol) {\n\t\treturn undefined;\n\t}\n\tif (\n\t\tpattern.hostname !== undefined &&\n\t\tpattern.hostname !== urlObj.hostname.toLowerCase()\n\t) {\n\t\treturn undefined;\n\t}\n\tif (pattern.hostname !== undefined) {\n\t\tconst expectedPort =\n\t\t\tpattern.port ??\n\t\t\tdefaultPortForProtocol(pattern.protocol ?? urlObj.protocol);\n\t\tif (expectedPort !== urlObj.port) return undefined;\n\t}\n\n\tconst prefix = pattern.pathnamePrefix;\n\tif (prefix === \"/\") {\n\t\tif (urlObj.pathname.startsWith(\"//\")) return undefined;\n\t\tif (pattern.pathMode === \"segments\") {\n\t\t\treturn isNonEmptyPathSegments(urlObj.pathname)\n\t\t\t\t? urlObj.pathname\n\t\t\t\t: undefined;\n\t\t}\n\t\treturn urlObj.pathname;\n\t}\n\tif (urlObj.pathname === prefix) {\n\t\treturn pattern.pathMode === \"catch-all-required\" ? undefined : \"\";\n\t}\n\tif (urlObj.pathname.startsWith(`${prefix}/`)) {\n\t\tconst suffix = urlObj.pathname.slice(prefix.length);\n\t\tif (suffix.startsWith(\"//\")) return undefined;\n\t\tif (pattern.pathMode === \"segments\" && !isNonEmptyPathSegments(suffix)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn suffix;\n\t}\n\treturn undefined;\n}\n\n/**\n * @param {string} pathname\n * @returns {boolean}\n */\nfunction isNonEmptyPathSegments(pathname) {\n\treturn (\n\t\tpathname.length > 1 && !pathname.endsWith(\"/\") && !pathname.includes(\"//\")\n\t);\n}\n\n/**\n * URLPattern treats the default port as empty in URL instances.\n *\n * @param {string} protocol\n * @returns {string}\n */\nfunction defaultPortForProtocol(protocol) {\n\tif (protocol === \"http:\") return \"\";\n\tif (protocol === \"https:\") return \"\";\n\treturn \"\";\n}\n\n/**\n * @param {FastPathPattern} pattern\n * @param {string} suffix\n * @param {URL} source\n * @returns {URL}\n */\nfunction applyFastPathPattern(pattern, suffix, source) {\n\tconst localized = new URL(source.href);\n\tif (pattern.protocol !== undefined) localized.protocol = pattern.protocol;\n\tif (pattern.hostname !== undefined) {\n\t\tlocalized.hostname = pattern.hostname;\n\t\tlocalized.port = pattern.port ?? defaultPortForProtocol(localized.protocol);\n\t}\n\tlocalized.pathname = joinFastPathPrefix(pattern.pathnamePrefix, suffix);\n\treturn localized;\n}\n\n/**\n * @param {string} prefix\n * @param {string} suffix\n * @returns {string}\n */\nfunction joinFastPathPrefix(prefix, suffix) {\n\tif (prefix === \"/\") return suffix === \"\" ? \"/\" : suffix;\n\tif (suffix === \"\") return prefix;\n\treturn `${prefix}${suffix.startsWith(\"/\") ? suffix : `/${suffix}`}`;\n}\n"]}
@@ -1,7 +1,10 @@
1
1
  import { deLocalizeUrl } from "./localize-url.js";
2
2
  import { normalizeTrailingSlash } from "./normalize-trailing-slash.js";
3
3
  import { execUrlPattern } from "./exec-url-pattern.js";
4
+ import { getUrlPattern } from "./url-pattern-cache.js";
5
+ import { getRouteStrategyCandidates, getRoutingConfigVersion, } from "./url-pattern-index.js";
4
6
  import { routeStrategies, strategy } from "./variables.js";
7
+ let cachedRouteConfigVersion = -1;
5
8
  /** @type {string | undefined} */
6
9
  let cachedRouteStrategyUrl;
7
10
  /** @type {{ match: string; strategy?: typeof strategy; exclude?: boolean } | undefined} */
@@ -20,7 +23,9 @@ export function findMatchingRouteStrategy(url) {
20
23
  return undefined;
21
24
  }
22
25
  const urlString = typeof url === "string" ? url : url.href;
23
- if (cachedRouteStrategyUrl === urlString) {
26
+ const configVersion = getRoutingConfigVersion();
27
+ if (cachedRouteStrategyUrl === urlString &&
28
+ cachedRouteConfigVersion === configVersion) {
24
29
  return cachedRouteStrategy;
25
30
  }
26
31
  const publicUrl = normalizeTrailingSlash(new URL(urlString, "http://example.com"));
@@ -30,8 +35,8 @@ export function findMatchingRouteStrategy(url) {
30
35
  : [publicUrl, canonicalUrl];
31
36
  let match;
32
37
  for (const candidateUrl of candidateUrls) {
33
- for (const routeStrategy of routeStrategies) {
34
- const pattern = new URLPattern(routeStrategy.match, candidateUrl.href);
38
+ for (const routeStrategy of getRouteStrategyCandidates(candidateUrl)) {
39
+ const pattern = getUrlPattern(routeStrategy.match, candidateUrl);
35
40
  if (execUrlPattern(pattern, candidateUrl)) {
36
41
  match = routeStrategy;
37
42
  break;
@@ -40,6 +45,7 @@ export function findMatchingRouteStrategy(url) {
40
45
  if (match)
41
46
  break;
42
47
  }
48
+ cachedRouteConfigVersion = configVersion;
43
49
  cachedRouteStrategyUrl = urlString;
44
50
  cachedRouteStrategy = match;
45
51
  return match;
@@ -1 +1 @@
1
- {"version":3,"file":"route-strategy.js","sourceRoot":"","sources":["../../../src/compiler/runtime/route-strategy.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE3D,iCAAiC;AACjC,IAAI,sBAAsB,CAAC;AAC3B,2FAA2F;AAC3F,IAAI,mBAAmB,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAG;IAC5C,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC3D,IAAI,sBAAsB,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,mBAAmB,CAAC;IAC5B,CAAC;IAED,MAAM,SAAS,GAAG,sBAAsB,CACvC,IAAI,GAAG,CAAC,SAAS,EAAE,oBAAoB,CAAC,CACxC,CAAC;IACF,MAAM,YAAY,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,aAAa,GAClB,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;QACnC,CAAC,CAAC,CAAC,SAAS,CAAC;QACb,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC;IACV,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QAC1C,KAAK,MAAM,aAAa,IAAI,eAAe,EAAE,CAAC;YAC7C,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;YACvE,IAAI,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;gBAC3C,KAAK,GAAG,aAAa,CAAC;gBACtB,MAAM;YACP,CAAC;QACF,CAAC;QACD,IAAI,KAAK;YAAE,MAAM;IAClB,CAAC;IAED,sBAAsB,GAAG,SAAS,CAAC;IACnC,mBAAmB,GAAG,KAAK,CAAC;IAC5B,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG;IACpC,MAAM,aAAa,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;IACrD,IACC,aAAa;QACb,aAAa,CAAC,OAAO,KAAK,IAAI;QAC9B,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,EACpC,CAAC;QACF,OAAO,aAAa,CAAC,QAAQ,CAAC;IAC/B,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAG;IAC5C,OAAO,yBAAyB,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AACzD,CAAC","sourcesContent":["import { deLocalizeUrl } from \"./localize-url.js\";\nimport { normalizeTrailingSlash } from \"./normalize-trailing-slash.js\";\nimport { execUrlPattern } from \"./exec-url-pattern.js\";\nimport { routeStrategies, strategy } from \"./variables.js\";\n\n/** @type {string | undefined} */\nlet cachedRouteStrategyUrl;\n/** @type {{ match: string; strategy?: typeof strategy; exclude?: boolean } | undefined} */\nlet cachedRouteStrategy;\n\n/**\n * Match route policy against both the public URL and its canonical URL.\n *\n * The function is deliberately separate from variables.js: configuration is\n * inert data, while canonicalization and route selection form a routing layer.\n *\n * @param {string | URL} url\n * @returns {{ match: string; strategy?: typeof strategy; exclude?: boolean } | undefined}\n */\nexport function findMatchingRouteStrategy(url) {\n\tif (routeStrategies.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tconst urlString = typeof url === \"string\" ? url : url.href;\n\tif (cachedRouteStrategyUrl === urlString) {\n\t\treturn cachedRouteStrategy;\n\t}\n\n\tconst publicUrl = normalizeTrailingSlash(\n\t\tnew URL(urlString, \"http://example.com\")\n\t);\n\tconst canonicalUrl = deLocalizeUrl(publicUrl);\n\tconst candidateUrls =\n\t\tcanonicalUrl.href === publicUrl.href\n\t\t\t? [publicUrl]\n\t\t\t: [publicUrl, canonicalUrl];\n\tlet match;\n\tfor (const candidateUrl of candidateUrls) {\n\t\tfor (const routeStrategy of routeStrategies) {\n\t\t\tconst pattern = new URLPattern(routeStrategy.match, candidateUrl.href);\n\t\t\tif (execUrlPattern(pattern, candidateUrl)) {\n\t\t\t\tmatch = routeStrategy;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (match) break;\n\t}\n\n\tcachedRouteStrategyUrl = urlString;\n\tcachedRouteStrategy = match;\n\treturn match;\n}\n\n/**\n * Returns the strategy to use for a specific URL.\n *\n * If no route strategy matches (or the matching rule is `exclude: true`),\n * the global strategy is returned.\n *\n * @param {string | URL} url\n * @returns {typeof strategy}\n */\nexport function getStrategyForUrl(url) {\n\tconst routeStrategy = findMatchingRouteStrategy(url);\n\tif (\n\t\trouteStrategy &&\n\t\trouteStrategy.exclude !== true &&\n\t\tArray.isArray(routeStrategy.strategy)\n\t) {\n\t\treturn routeStrategy.strategy;\n\t}\n\treturn strategy;\n}\n\n/**\n * Returns whether the given URL is excluded from middleware i18n processing.\n *\n * @param {string | URL} url\n * @returns {boolean}\n */\nexport function isExcludedByRouteStrategy(url) {\n\treturn findMatchingRouteStrategy(url)?.exclude === true;\n}\n"]}
1
+ {"version":3,"file":"route-strategy.js","sourceRoot":"","sources":["../../../src/compiler/runtime/route-strategy.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACN,0BAA0B,EAC1B,uBAAuB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE3D,IAAI,wBAAwB,GAAG,CAAC,CAAC,CAAC;AAElC,iCAAiC;AACjC,IAAI,sBAAsB,CAAC;AAC3B,2FAA2F;AAC3F,IAAI,mBAAmB,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAG;IAC5C,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC3D,MAAM,aAAa,GAAG,uBAAuB,EAAE,CAAC;IAChD,IACC,sBAAsB,KAAK,SAAS;QACpC,wBAAwB,KAAK,aAAa,EACzC,CAAC;QACF,OAAO,mBAAmB,CAAC;IAC5B,CAAC;IAED,MAAM,SAAS,GAAG,sBAAsB,CACvC,IAAI,GAAG,CAAC,SAAS,EAAE,oBAAoB,CAAC,CACxC,CAAC;IACF,MAAM,YAAY,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,aAAa,GAClB,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;QACnC,CAAC,CAAC,CAAC,SAAS,CAAC;QACb,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC;IACV,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QAC1C,KAAK,MAAM,aAAa,IAAI,0BAA0B,CAAC,YAAY,CAAC,EAAE,CAAC;YACtE,MAAM,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;YACjE,IAAI,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;gBAC3C,KAAK,GAAG,aAAa,CAAC;gBACtB,MAAM;YACP,CAAC;QACF,CAAC;QACD,IAAI,KAAK;YAAE,MAAM;IAClB,CAAC;IAED,wBAAwB,GAAG,aAAa,CAAC;IACzC,sBAAsB,GAAG,SAAS,CAAC;IACnC,mBAAmB,GAAG,KAAK,CAAC;IAC5B,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG;IACpC,MAAM,aAAa,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;IACrD,IACC,aAAa;QACb,aAAa,CAAC,OAAO,KAAK,IAAI;QAC9B,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,EACpC,CAAC;QACF,OAAO,aAAa,CAAC,QAAQ,CAAC;IAC/B,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAG;IAC5C,OAAO,yBAAyB,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AACzD,CAAC","sourcesContent":["import { deLocalizeUrl } from \"./localize-url.js\";\nimport { normalizeTrailingSlash } from \"./normalize-trailing-slash.js\";\nimport { execUrlPattern } from \"./exec-url-pattern.js\";\nimport { getUrlPattern } from \"./url-pattern-cache.js\";\nimport {\n\tgetRouteStrategyCandidates,\n\tgetRoutingConfigVersion,\n} from \"./url-pattern-index.js\";\nimport { routeStrategies, strategy } from \"./variables.js\";\n\nlet cachedRouteConfigVersion = -1;\n\n/** @type {string | undefined} */\nlet cachedRouteStrategyUrl;\n/** @type {{ match: string; strategy?: typeof strategy; exclude?: boolean } | undefined} */\nlet cachedRouteStrategy;\n\n/**\n * Match route policy against both the public URL and its canonical URL.\n *\n * The function is deliberately separate from variables.js: configuration is\n * inert data, while canonicalization and route selection form a routing layer.\n *\n * @param {string | URL} url\n * @returns {{ match: string; strategy?: typeof strategy; exclude?: boolean } | undefined}\n */\nexport function findMatchingRouteStrategy(url) {\n\tif (routeStrategies.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tconst urlString = typeof url === \"string\" ? url : url.href;\n\tconst configVersion = getRoutingConfigVersion();\n\tif (\n\t\tcachedRouteStrategyUrl === urlString &&\n\t\tcachedRouteConfigVersion === configVersion\n\t) {\n\t\treturn cachedRouteStrategy;\n\t}\n\n\tconst publicUrl = normalizeTrailingSlash(\n\t\tnew URL(urlString, \"http://example.com\")\n\t);\n\tconst canonicalUrl = deLocalizeUrl(publicUrl);\n\tconst candidateUrls =\n\t\tcanonicalUrl.href === publicUrl.href\n\t\t\t? [publicUrl]\n\t\t\t: [publicUrl, canonicalUrl];\n\tlet match;\n\tfor (const candidateUrl of candidateUrls) {\n\t\tfor (const routeStrategy of getRouteStrategyCandidates(candidateUrl)) {\n\t\t\tconst pattern = getUrlPattern(routeStrategy.match, candidateUrl);\n\t\t\tif (execUrlPattern(pattern, candidateUrl)) {\n\t\t\t\tmatch = routeStrategy;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (match) break;\n\t}\n\n\tcachedRouteConfigVersion = configVersion;\n\tcachedRouteStrategyUrl = urlString;\n\tcachedRouteStrategy = match;\n\treturn match;\n}\n\n/**\n * Returns the strategy to use for a specific URL.\n *\n * If no route strategy matches (or the matching rule is `exclude: true`),\n * the global strategy is returned.\n *\n * @param {string | URL} url\n * @returns {typeof strategy}\n */\nexport function getStrategyForUrl(url) {\n\tconst routeStrategy = findMatchingRouteStrategy(url);\n\tif (\n\t\trouteStrategy &&\n\t\trouteStrategy.exclude !== true &&\n\t\tArray.isArray(routeStrategy.strategy)\n\t) {\n\t\treturn routeStrategy.strategy;\n\t}\n\treturn strategy;\n}\n\n/**\n * Returns whether the given URL is excluded from middleware i18n processing.\n *\n * @param {string | URL} url\n * @returns {boolean}\n */\nexport function isExcludedByRouteStrategy(url) {\n\treturn findMatchingRouteStrategy(url)?.exclude === true;\n}\n"]}
@@ -49,6 +49,15 @@ test("cookie cache clearer remains internal in the generated runtime", () => {
49
49
  expect(jsdocRuntime).toContain("function clearLocaleCookieCache");
50
50
  expect(jsdocRuntime).not.toContain("export function clearLocaleCookieCache");
51
51
  });
52
+ test("import statements in JSDoc examples survive in the generated runtime", () => {
53
+ const runtime = createRuntimeFile({
54
+ baseLocale: "en",
55
+ locales: ["en", "de"],
56
+ compilerOptions: defaultCompilerOptions,
57
+ });
58
+ expect(runtime).toContain(` * import { m } from './messages.js'\n * m.hello({ name: 'world' }, { locale: "en" })`);
59
+ expect(runtime).not.toMatch(/^\s*import\s/m);
60
+ });
52
61
  test("runtime type", async () => {
53
62
  const project = await typescriptProject({
54
63
  useInMemoryFileSystem: true,
@@ -1 +1 @@
1
- {"version":3,"file":"type.test.js","sourceRoot":"","sources":["../../../src/compiler/runtime/type.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACN,aAAa,IAAI,iBAAiB,EAClC,EAAE,GAEF,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,oCAAoC,GACzC;IACC,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI;IACb,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,IAAI;IACpB,kBAAkB,EAAE,IAAI;IACxB,iBAAiB,EAAE,IAAI;IACvB,cAAc,EAAE,IAAI;IACpB,wBAAwB,EAAE,IAAI;IAC9B,kCAAkC,EAAE,IAAI;IACxC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM;IAC5B,MAAM,EAAE,IAAI;CACZ,CAAC;AAEH,IAAI,CAAC,oEAAoE,EAAE,GAAG,EAAE;IAC/E,MAAM,CAAC,GAAG,EAAE,CACX,iBAAiB,CAAC;QACjB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,eAAe,EAAE;YAChB,GAAG,sBAAsB;YACzB,WAAW,EAAE;gBACZ;oBACC,OAAO,EAAE,4BAA4B;oBACrC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC;iBACpD;aACD;SACD;KACD,CAAC,CACF,CAAC,OAAO,CACR,mGAAmG,CACnG,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,GAAG,EAAE;IAC3E,MAAM,YAAY,GAAG,iBAAiB,CAAC;QACtC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,eAAe,EAAE;YAChB,GAAG,sBAAsB;YACzB,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC;SAClC;KACD,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;IAClE,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE;IAC/B,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC;QACvC,qBAAqB,EAAE,IAAI;QAC3B,eAAe,EAAE,oCAAoC;KACrD,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,iBAAiB,CAAC;QACtC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,CAAC;QACf,eAAe,EAAE,sBAAsB;KACvC,CAAC,CAAC,OAAO,CACT,sEAAsE,EACtE,EAAE,CACF,CAAC;IAEF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE;QAC7B,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,CAAE,CAAU,CAAC;IAC7E,CAAC,CAAC;IAEF,OAAO,CAAC,gBAAgB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACvD,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEpD,oDAAoD;IACpD,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9C,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,CAAC;IACF,CAAC;IAED,OAAO,CAAC,gBAAgB,CACvB,WAAW,EACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuCG,CACH,CAAC;IAEF,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IACxC,MAAM,WAAW,GAAG,EAAE;SACpB,qBAAqB,CAAC,OAAO,CAAC;QAC/B,sIAAsI;SACrI,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;SAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACrE,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC","sourcesContent":["import { expect, test } from \"vitest\";\nimport {\n\tcreateProject as typescriptProject,\n\tts,\n\ttype ProjectOptions,\n} from \"@ts-morph/bootstrap\";\nimport { createRuntimeFile } from \"./create-runtime.js\";\nimport fs from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"url\";\nimport { defaultCompilerOptions } from \"../compiler-options.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst superStrictRuleOutAnyErrorTsSettings: ProjectOptions[\"compilerOptions\"] =\n\t{\n\t\toutDir: \"dist\",\n\t\tdeclaration: true,\n\t\tallowJs: true,\n\t\tcheckJs: true,\n\t\tnoImplicitAny: true,\n\t\tnoUnusedLocals: true,\n\t\tnoUnusedParameters: true,\n\t\tnoImplicitReturns: true,\n\t\tnoImplicitThis: true,\n\t\tnoUncheckedIndexedAccess: true,\n\t\tnoPropertyAccessFromIndexSignature: true,\n\t\tmodule: ts.ModuleKind.Node16,\n\t\tstrict: true,\n\t};\n\ntest(\"createRuntimeFile throws if urlPatterns contains an unknown locale\", () => {\n\texpect(() =>\n\t\tcreateRuntimeFile({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tcompilerOptions: {\n\t\t\t\t...defaultCompilerOptions,\n\t\t\t\turlPatterns: [\n\t\t\t\t\t{\n\t\t\t\t\t\tpattern: \"https://example.com/:path*\",\n\t\t\t\t\t\tlocalized: [[\"fr\", \"https://example.com/fr/:path*\"]],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t})\n\t).toThrow(\n\t\t'Invalid locale \"fr\" in urlPatterns. It must be one of the locales defined in the \"locales\" array.'\n\t);\n});\n\ntest(\"cookie cache clearer remains internal in the generated runtime\", () => {\n\tconst jsdocRuntime = createRuntimeFile({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tcompilerOptions: {\n\t\t\t...defaultCompilerOptions,\n\t\t\tstrategy: [\"cookie\", \"baseLocale\"],\n\t\t},\n\t});\n\n\texpect(jsdocRuntime).toContain(\"function clearLocaleCookieCache\");\n\texpect(jsdocRuntime).not.toContain(\"export function clearLocaleCookieCache\");\n});\n\ntest(\"runtime type\", async () => {\n\tconst project = await typescriptProject({\n\t\tuseInMemoryFileSystem: true,\n\t\tcompilerOptions: superStrictRuleOutAnyErrorTsSettings,\n\t});\n\n\tconst jsdocRuntime = createRuntimeFile({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\"],\n\t\tcompilerOptions: defaultCompilerOptions,\n\t}).replace(\n\t\t'import * as pathToRegexp from \"@inlang/paraglide-js/path-to-regexp\";',\n\t\t\"\"\n\t);\n\n\tconst file = (path: string) => {\n\t\treturn [path, fs.readFileSync(resolve(__dirname, path), \"utf-8\")!] as const;\n\t};\n\n\tproject.createSourceFile(\"./runtime.js\", jsdocRuntime);\n\tproject.createSourceFile(...file(\"./type.ts\"));\n\tproject.createSourceFile(...file(\"./ambient.d.ts\"));\n\n\t// add the imports for the types in the runtime type\n\tfor (const name of fs.readdirSync(__dirname)) {\n\t\tif (name.endsWith(\".js\")) {\n\t\t\tproject.createSourceFile(...file(name));\n\t\t}\n\t}\n\n\tproject.createSourceFile(\n\t\t\"./test.ts\",\n\t\t`\n import * as runtime from \"./runtime.js\"\n import type { Runtime } from \"./type.js\"\n\n runtime satisfies Runtime\n\n\t\t// getLocale() should return type should be a union of language tags, not a generic string\n runtime.getLocale() satisfies \"de\" | \"en\" | \"en-US\"\n\n // locales should have a narrow type, not a generic string\n runtime.locales satisfies Readonly<Array<\"de\" | \"en\" | \"en-US\">>\n\n // setLocale() should fail if the given language tag is not included in locales\n // @ts-expect-error - invalid locale\n runtime.setLocale(\"fr\")\n\n // setLocale() should not fail if the given language tag is included in locales\n runtime.setLocale(\"de\")\n\n\t\t// getTextDirection() should return a strict direction union\n\t\truntime.getTextDirection() satisfies \"ltr\" | \"rtl\"\n\n\t\t// isLocale should narrow the type of it's argument\n\t\tconst thing = 5;\n\n\t\tlet a: \"de\" | \"en\" | \"en-US\";\n\n\t\tif(runtime.isLocale(thing)) {\n\t\t\ta = thing\n\t\t} else {\n\t\t\t// @ts-expect-error - thing is not a language tag\n\t\t\ta = thing\n\t\t}\n\n\t\t// to make ts not complain about unused variables\n\t\truntime.toLocale(\"EN\") satisfies \"de\" | \"en\" | \"en-US\" | undefined\n\t\truntime.toLocale(123) satisfies \"de\" | \"en\" | \"en-US\" | undefined\n\n\t\tconsole.log(a)\n `\n\t);\n\n\tconst program = project.createProgram();\n\tconst diagnostics = ts\n\t\t.getPreEmitDiagnostics(program)\n\t\t// ignore 'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible. /ambient.d.ts\n\t\t.filter((d) => d.code !== 2668)\n\t\t.filter((d) => d.messageText.toString().includes(\"path-to-regexp\"));\n\tfor (const diagnostic of diagnostics) {\n\t\tconsole.error(diagnostic.messageText, diagnostic.file?.fileName);\n\t}\n\texpect(diagnostics.length).toEqual(0);\n});\n"]}
1
+ {"version":3,"file":"type.test.js","sourceRoot":"","sources":["../../../src/compiler/runtime/type.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, test } from \"vitest\";\nimport {\n\tcreateProject as typescriptProject,\n\tts,\n\ttype ProjectOptions,\n} from \"@ts-morph/bootstrap\";\nimport { createRuntimeFile } from \"./create-runtime.js\";\nimport fs from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"url\";\nimport { defaultCompilerOptions } from \"../compiler-options.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst superStrictRuleOutAnyErrorTsSettings: ProjectOptions[\"compilerOptions\"] =\n\t{\n\t\toutDir: \"dist\",\n\t\tdeclaration: true,\n\t\tallowJs: true,\n\t\tcheckJs: true,\n\t\tnoImplicitAny: true,\n\t\tnoUnusedLocals: true,\n\t\tnoUnusedParameters: true,\n\t\tnoImplicitReturns: true,\n\t\tnoImplicitThis: true,\n\t\tnoUncheckedIndexedAccess: true,\n\t\tnoPropertyAccessFromIndexSignature: true,\n\t\tmodule: ts.ModuleKind.Node16,\n\t\tstrict: true,\n\t};\n\ntest(\"createRuntimeFile throws if urlPatterns contains an unknown locale\", () => {\n\texpect(() =>\n\t\tcreateRuntimeFile({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tcompilerOptions: {\n\t\t\t\t...defaultCompilerOptions,\n\t\t\t\turlPatterns: [\n\t\t\t\t\t{\n\t\t\t\t\t\tpattern: \"https://example.com/:path*\",\n\t\t\t\t\t\tlocalized: [[\"fr\", \"https://example.com/fr/:path*\"]],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t})\n\t).toThrow(\n\t\t'Invalid locale \"fr\" in urlPatterns. It must be one of the locales defined in the \"locales\" array.'\n\t);\n});\n\ntest(\"cookie cache clearer remains internal in the generated runtime\", () => {\n\tconst jsdocRuntime = createRuntimeFile({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tcompilerOptions: {\n\t\t\t...defaultCompilerOptions,\n\t\t\tstrategy: [\"cookie\", \"baseLocale\"],\n\t\t},\n\t});\n\n\texpect(jsdocRuntime).toContain(\"function clearLocaleCookieCache\");\n\texpect(jsdocRuntime).not.toContain(\"export function clearLocaleCookieCache\");\n});\n\ntest(\"import statements in JSDoc examples survive in the generated runtime\", () => {\n\tconst runtime = createRuntimeFile({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tcompilerOptions: defaultCompilerOptions,\n\t});\n\n\texpect(runtime).toContain(\n\t\t` * import { m } from './messages.js'\\n * m.hello({ name: 'world' }, { locale: \"en\" })`\n\t);\n\texpect(runtime).not.toMatch(/^\\s*import\\s/m);\n});\n\ntest(\"runtime type\", async () => {\n\tconst project = await typescriptProject({\n\t\tuseInMemoryFileSystem: true,\n\t\tcompilerOptions: superStrictRuleOutAnyErrorTsSettings,\n\t});\n\n\tconst jsdocRuntime = createRuntimeFile({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\"],\n\t\tcompilerOptions: defaultCompilerOptions,\n\t}).replace(\n\t\t'import * as pathToRegexp from \"@inlang/paraglide-js/path-to-regexp\";',\n\t\t\"\"\n\t);\n\n\tconst file = (path: string) => {\n\t\treturn [path, fs.readFileSync(resolve(__dirname, path), \"utf-8\")!] as const;\n\t};\n\n\tproject.createSourceFile(\"./runtime.js\", jsdocRuntime);\n\tproject.createSourceFile(...file(\"./type.ts\"));\n\tproject.createSourceFile(...file(\"./ambient.d.ts\"));\n\n\t// add the imports for the types in the runtime type\n\tfor (const name of fs.readdirSync(__dirname)) {\n\t\tif (name.endsWith(\".js\")) {\n\t\t\tproject.createSourceFile(...file(name));\n\t\t}\n\t}\n\n\tproject.createSourceFile(\n\t\t\"./test.ts\",\n\t\t`\n import * as runtime from \"./runtime.js\"\n import type { Runtime } from \"./type.js\"\n\n runtime satisfies Runtime\n\n\t\t// getLocale() should return type should be a union of language tags, not a generic string\n runtime.getLocale() satisfies \"de\" | \"en\" | \"en-US\"\n\n // locales should have a narrow type, not a generic string\n runtime.locales satisfies Readonly<Array<\"de\" | \"en\" | \"en-US\">>\n\n // setLocale() should fail if the given language tag is not included in locales\n // @ts-expect-error - invalid locale\n runtime.setLocale(\"fr\")\n\n // setLocale() should not fail if the given language tag is included in locales\n runtime.setLocale(\"de\")\n\n\t\t// getTextDirection() should return a strict direction union\n\t\truntime.getTextDirection() satisfies \"ltr\" | \"rtl\"\n\n\t\t// isLocale should narrow the type of it's argument\n\t\tconst thing = 5;\n\n\t\tlet a: \"de\" | \"en\" | \"en-US\";\n\n\t\tif(runtime.isLocale(thing)) {\n\t\t\ta = thing\n\t\t} else {\n\t\t\t// @ts-expect-error - thing is not a language tag\n\t\t\ta = thing\n\t\t}\n\n\t\t// to make ts not complain about unused variables\n\t\truntime.toLocale(\"EN\") satisfies \"de\" | \"en\" | \"en-US\" | undefined\n\t\truntime.toLocale(123) satisfies \"de\" | \"en\" | \"en-US\" | undefined\n\n\t\tconsole.log(a)\n `\n\t);\n\n\tconst program = project.createProgram();\n\tconst diagnostics = ts\n\t\t.getPreEmitDiagnostics(program)\n\t\t// ignore 'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible. /ambient.d.ts\n\t\t.filter((d) => d.code !== 2668)\n\t\t.filter((d) => d.messageText.toString().includes(\"path-to-regexp\"));\n\tfor (const diagnostic of diagnostics) {\n\t\tconsole.error(diagnostic.messageText, diagnostic.file?.fileName);\n\t}\n\texpect(diagnostics.length).toEqual(0);\n});\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * URLPattern's base URL affects relative patterns. Absolute patterns only
3
+ * depend on the pattern itself, while root-relative patterns also depend on
4
+ * the URL origin. Other relative patterns are deliberately not cached because
5
+ * their semantics depend on the complete base URL.
6
+ *
7
+ * @param {string} pattern
8
+ * @param {URL} url
9
+ * @returns {URLPattern}
10
+ */
11
+ export declare function getUrlPattern(pattern: string, url: URL): URLPattern;
@@ -0,0 +1,42 @@
1
+ /** @type {Map<string, URLPattern>} */
2
+ const urlPatternCache = new Map();
3
+ const URL_PATTERN_CACHE_LIMIT = 1024;
4
+ const ABSOLUTE_URL_PATTERN = /^(?:[A-Za-z][A-Za-z\d+.-]*|:[A-Za-z][A-Za-z\d_-]*):\/\//;
5
+ /**
6
+ * URLPattern's base URL affects relative patterns. Absolute patterns only
7
+ * depend on the pattern itself, while root-relative patterns also depend on
8
+ * the URL origin. Other relative patterns are deliberately not cached because
9
+ * their semantics depend on the complete base URL.
10
+ *
11
+ * @param {string} pattern
12
+ * @param {URL} url
13
+ * @returns {URLPattern}
14
+ */
15
+ export function getUrlPattern(pattern, url) {
16
+ const isAbsolutePattern = ABSOLUTE_URL_PATTERN.test(pattern);
17
+ // Opaque/file origins are not a unique base key (different file hosts all
18
+ // have origin "null"). Keep their constructor semantics uncached.
19
+ const isRootRelativePattern = pattern.startsWith("/") && /^https?:$/.test(url.protocol);
20
+ if (!isAbsolutePattern && !isRootRelativePattern) {
21
+ return new URLPattern(pattern, url.href);
22
+ }
23
+ const key = isAbsolutePattern
24
+ ? pattern
25
+ : JSON.stringify([url.origin, pattern]);
26
+ const cached = urlPatternCache.get(key);
27
+ if (cached !== undefined) {
28
+ // Refresh the entry so frequently used patterns stay in the bounded cache.
29
+ urlPatternCache.delete(key);
30
+ urlPatternCache.set(key, cached);
31
+ return cached;
32
+ }
33
+ const compiled = new URLPattern(pattern, url.href);
34
+ if (urlPatternCache.size >= URL_PATTERN_CACHE_LIMIT) {
35
+ const oldestKey = urlPatternCache.keys().next().value;
36
+ if (oldestKey !== undefined)
37
+ urlPatternCache.delete(oldestKey);
38
+ }
39
+ urlPatternCache.set(key, compiled);
40
+ return compiled;
41
+ }
42
+ //# sourceMappingURL=url-pattern-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-pattern-cache.js","sourceRoot":"","sources":["../../../src/compiler/runtime/url-pattern-cache.js"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAE,CAAC;AAElC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AACrC,MAAM,oBAAoB,GACzB,yDAAyD,CAAC;AAE3D;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,OAAO,EAAE,GAAG;IACzC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7D,0EAA0E;IAC1E,kEAAkE;IAClE,MAAM,qBAAqB,GAC1B,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3D,IAAI,CAAC,iBAAiB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAClD,OAAO,IAAI,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,GAAG,GAAG,iBAAiB;QAC5B,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,2EAA2E;QAC3E,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjC,OAAO,MAAM,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,eAAe,CAAC,IAAI,IAAI,uBAAuB,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QACtD,IAAI,SAAS,KAAK,SAAS;YAAE,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IACD,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC;AACjB,CAAC","sourcesContent":["/** @type {Map<string, URLPattern>} */\nconst urlPatternCache = new Map();\n\nconst URL_PATTERN_CACHE_LIMIT = 1024;\nconst ABSOLUTE_URL_PATTERN =\n\t/^(?:[A-Za-z][A-Za-z\\d+.-]*|:[A-Za-z][A-Za-z\\d_-]*):\\/\\//;\n\n/**\n * URLPattern's base URL affects relative patterns. Absolute patterns only\n * depend on the pattern itself, while root-relative patterns also depend on\n * the URL origin. Other relative patterns are deliberately not cached because\n * their semantics depend on the complete base URL.\n *\n * @param {string} pattern\n * @param {URL} url\n * @returns {URLPattern}\n */\nexport function getUrlPattern(pattern, url) {\n\tconst isAbsolutePattern = ABSOLUTE_URL_PATTERN.test(pattern);\n\t// Opaque/file origins are not a unique base key (different file hosts all\n\t// have origin \"null\"). Keep their constructor semantics uncached.\n\tconst isRootRelativePattern =\n\t\tpattern.startsWith(\"/\") && /^https?:$/.test(url.protocol);\n\tif (!isAbsolutePattern && !isRootRelativePattern) {\n\t\treturn new URLPattern(pattern, url.href);\n\t}\n\n\tconst key = isAbsolutePattern\n\t\t? pattern\n\t\t: JSON.stringify([url.origin, pattern]);\n\tconst cached = urlPatternCache.get(key);\n\tif (cached !== undefined) {\n\t\t// Refresh the entry so frequently used patterns stay in the bounded cache.\n\t\turlPatternCache.delete(key);\n\t\turlPatternCache.set(key, cached);\n\t\treturn cached;\n\t}\n\n\tconst compiled = new URLPattern(pattern, url.href);\n\tif (urlPatternCache.size >= URL_PATTERN_CACHE_LIMIT) {\n\t\tconst oldestKey = urlPatternCache.keys().next().value;\n\t\tif (oldestKey !== undefined) urlPatternCache.delete(oldestKey);\n\t}\n\turlPatternCache.set(key, compiled);\n\treturn compiled;\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { urlPatterns, routeStrategies } from "./variables.js";
2
+ export type PrefixNode = {
3
+ children: Map<string, PrefixNode>;
4
+ ranks: Set<number>;
5
+ };
6
+ export type PatternIndex = {
7
+ items: any[];
8
+ snapshots: any[];
9
+ root: PrefixNode;
10
+ };
11
+ /**
12
+ * Validate the public mutable configuration before reusing derived routing data.
13
+ * String/reference comparisons intentionally remain O(n): they preserve edits
14
+ * through retained array/object references without changing the public objects.
15
+ * Native matching of unrelated routes is the expensive work this index avoids.
16
+ * @returns {number}
17
+ */
18
+ export declare function getRoutingConfigVersion(): number;
19
+ /** @returns {number} */
20
+ export declare function currentRoutingConfigVersion(): number;
21
+ /** @param {URL} url @returns {typeof urlPatterns} */
22
+ export declare function getUrlPatternCandidates(url: URL): typeof urlPatterns;
23
+ /** @param {URL} url @returns {typeof routeStrategies} */
24
+ export declare function getRouteStrategyCandidates(url: URL): typeof routeStrategies;
@@ -0,0 +1,152 @@
1
+ import { expect, test } from "vitest";
2
+ import { URLPattern as PolyfillURLPattern } from "urlpattern-polyfill";
3
+ import { createRuntimeFile } from "./create-runtime.js";
4
+ import { defaultCompilerOptions } from "../compiler-options.js";
5
+ const engines = [PolyfillURLPattern];
6
+ const nativeURLPattern = Reflect.get(globalThis, "URLPattern");
7
+ if (nativeURLPattern && nativeURLPattern !== PolyfillURLPattern) {
8
+ engines.push(nativeURLPattern);
9
+ }
10
+ let moduleId = 0;
11
+ const patterns = [
12
+ "/section/:slug",
13
+ "/section/:slug?",
14
+ "/section/:slug*",
15
+ "/section/:slug+",
16
+ "/section/:slug(.*)?",
17
+ "/section/:slug(.*)",
18
+ "/section/literal",
19
+ "/section/:slug/details",
20
+ "/section/:a/:b?",
21
+ "/section/:slug(\\d+)",
22
+ "/section/{literal}?",
23
+ "/section%2Fliteral/:slug",
24
+ "/section//:slug",
25
+ "/section/../other/:slug",
26
+ "https://example.com/section/:slug",
27
+ "section/:slug",
28
+ "/section/:slug/:slug",
29
+ "/section/:slug([)",
30
+ ];
31
+ const paths = [
32
+ "/",
33
+ "/section",
34
+ "/section/",
35
+ "/section/literal",
36
+ "/section/story",
37
+ "/section/123",
38
+ "/section/story/details",
39
+ "/section/story/other",
40
+ "/section//story",
41
+ "/section%2Fliteral/story",
42
+ "/other/story",
43
+ "/unknown",
44
+ ];
45
+ function outcome(fn) {
46
+ try {
47
+ const result = fn();
48
+ return {
49
+ value: result instanceof URL
50
+ ? result.href
51
+ : Array.isArray(result)
52
+ ? result.map((url) => url.href)
53
+ : result,
54
+ };
55
+ }
56
+ catch (error) {
57
+ return {
58
+ error: error instanceof Error ? [error.name, error.message] : String(error),
59
+ };
60
+ }
61
+ }
62
+ for (const ctor of engines) {
63
+ test(`${ctor === PolyfillURLPattern ? "polyfill" : "native"} candidate index agrees with native ordered scans`, async () => {
64
+ const previous = Reflect.get(globalThis, "URLPattern");
65
+ Object.defineProperty(globalThis, "URLPattern", {
66
+ configurable: true,
67
+ writable: true,
68
+ value: ctor,
69
+ });
70
+ let comparisons = 0;
71
+ try {
72
+ for (const pattern of patterns) {
73
+ for (const trailingSlash of [undefined, "always", "never"]) {
74
+ for (const catchAllFirst of [false, true]) {
75
+ const specific = {
76
+ pattern,
77
+ localized: [
78
+ ["en", pattern],
79
+ ["de", `/de${pattern}`],
80
+ ],
81
+ };
82
+ const catchAll = {
83
+ pattern: "/:path(.*)?",
84
+ localized: [
85
+ ["de", "/de/:path(.*)?"],
86
+ ["en", "/:path(.*)?"],
87
+ ],
88
+ };
89
+ const code = createRuntimeFile({
90
+ baseLocale: "en",
91
+ locales: ["en", "de", "fr"],
92
+ compilerOptions: {
93
+ ...defaultCompilerOptions,
94
+ strategy: ["url", "baseLocale"],
95
+ trailingSlash,
96
+ urlPatterns: catchAllFirst
97
+ ? [catchAll, specific]
98
+ : [specific, catchAll],
99
+ routeStrategies: [
100
+ { match: pattern, exclude: true },
101
+ { match: "/:path(.*)?", strategy: ["url"] },
102
+ ],
103
+ },
104
+ }).replace('import "@inlang/paraglide-js/urlpattern-polyfill";', "");
105
+ // The reference keeps native construction/matching and all filling
106
+ // logic, but enumerates the original arrays without pruning.
107
+ const scan = code
108
+ .replace("return patternCandidates(urlPatternIndex, url, urlPatterns);", "return urlPatterns;")
109
+ .replace("return patternCandidates(routeStrategyIndex, url, routeStrategies);", "return routeStrategies;");
110
+ expect(scan).not.toBe(code);
111
+ expect(scan).not.toContain("return patternCandidates(");
112
+ const load = (source) => import(
113
+ /* @vite-ignore */ "data:text/javascript;base64," +
114
+ Buffer.from(source + `\n// isolated fixture ${moduleId++}`).toString("base64"));
115
+ const indexed = await load(code);
116
+ const original = await load(scan);
117
+ for (const pathname of paths.flatMap((path) => [
118
+ path,
119
+ `/de${path}`,
120
+ ])) {
121
+ for (const asObject of [false, true]) {
122
+ const href = `https://user:pass@example.com${pathname}?redirect=%2Faccount#section`;
123
+ const input = asObject ? new URL(href) : href;
124
+ const operations = [
125
+ (runtime) => runtime.localizeUrl(input, { locale: "de" }),
126
+ (runtime) => runtime.localizeUrl(input, { locale: "fr" }),
127
+ (runtime) => runtime.deLocalizeUrl(input),
128
+ (runtime) => runtime.extractLocaleFromUrl(input),
129
+ (runtime) => runtime.findMatchingRouteStrategy(input),
130
+ (runtime) => runtime.generateStaticLocalizedUrls([input]),
131
+ ];
132
+ for (const operation of operations) {
133
+ expect(outcome(() => operation(indexed)), `${pattern}, slash=${trailingSlash}, catchAllFirst=${catchAllFirst}, ${href}`).toEqual(outcome(() => operation(original)));
134
+ comparisons++;
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ }
141
+ expect(comparisons).toBe(31104);
142
+ }
143
+ finally {
144
+ Object.defineProperty(globalThis, "URLPattern", {
145
+ configurable: true,
146
+ writable: true,
147
+ value: previous,
148
+ });
149
+ }
150
+ }, 30000);
151
+ }
152
+ //# sourceMappingURL=url-pattern-index.differential.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-pattern-index.differential.test.js","sourceRoot":"","sources":["../../../src/compiler/runtime/url-pattern-index.differential.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, test } from \"vitest\";\nimport { URLPattern as PolyfillURLPattern } from \"urlpattern-polyfill\";\nimport { createRuntimeFile } from \"./create-runtime.js\";\nimport { defaultCompilerOptions } from \"../compiler-options.js\";\n\nconst engines = [PolyfillURLPattern as unknown as typeof URLPattern];\nconst nativeURLPattern = Reflect.get(globalThis, \"URLPattern\") as\n\t| typeof URLPattern\n\t| undefined;\nif (nativeURLPattern && nativeURLPattern !== PolyfillURLPattern) {\n\tengines.push(nativeURLPattern);\n}\nlet moduleId = 0;\n\nconst patterns = [\n\t\"/section/:slug\",\n\t\"/section/:slug?\",\n\t\"/section/:slug*\",\n\t\"/section/:slug+\",\n\t\"/section/:slug(.*)?\",\n\t\"/section/:slug(.*)\",\n\t\"/section/literal\",\n\t\"/section/:slug/details\",\n\t\"/section/:a/:b?\",\n\t\"/section/:slug(\\\\d+)\",\n\t\"/section/{literal}?\",\n\t\"/section%2Fliteral/:slug\",\n\t\"/section//:slug\",\n\t\"/section/../other/:slug\",\n\t\"https://example.com/section/:slug\",\n\t\"section/:slug\",\n\t\"/section/:slug/:slug\",\n\t\"/section/:slug([)\",\n];\nconst paths = [\n\t\"/\",\n\t\"/section\",\n\t\"/section/\",\n\t\"/section/literal\",\n\t\"/section/story\",\n\t\"/section/123\",\n\t\"/section/story/details\",\n\t\"/section/story/other\",\n\t\"/section//story\",\n\t\"/section%2Fliteral/story\",\n\t\"/other/story\",\n\t\"/unknown\",\n];\n\nfunction outcome(fn: () => unknown) {\n\ttry {\n\t\tconst result = fn();\n\t\treturn {\n\t\t\tvalue:\n\t\t\t\tresult instanceof URL\n\t\t\t\t\t? result.href\n\t\t\t\t\t: Array.isArray(result)\n\t\t\t\t\t\t? result.map((url) => url.href)\n\t\t\t\t\t\t: result,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\terror:\n\t\t\t\terror instanceof Error ? [error.name, error.message] : String(error),\n\t\t};\n\t}\n}\n\nfor (const ctor of engines) {\n\ttest(`${ctor === PolyfillURLPattern ? \"polyfill\" : \"native\"} candidate index agrees with native ordered scans`, async () => {\n\t\tconst previous = Reflect.get(globalThis, \"URLPattern\");\n\t\tObject.defineProperty(globalThis, \"URLPattern\", {\n\t\t\tconfigurable: true,\n\t\t\twritable: true,\n\t\t\tvalue: ctor,\n\t\t});\n\t\tlet comparisons = 0;\n\t\ttry {\n\t\t\tfor (const pattern of patterns) {\n\t\t\t\tfor (const trailingSlash of [undefined, \"always\", \"never\"] as const) {\n\t\t\t\t\tfor (const catchAllFirst of [false, true]) {\n\t\t\t\t\t\tconst specific = {\n\t\t\t\t\t\t\tpattern,\n\t\t\t\t\t\t\tlocalized: [\n\t\t\t\t\t\t\t\t[\"en\", pattern],\n\t\t\t\t\t\t\t\t[\"de\", `/de${pattern}`],\n\t\t\t\t\t\t\t] as Array<[string, string]>,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst catchAll = {\n\t\t\t\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\t\t\t\tlocalized: [\n\t\t\t\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"],\n\t\t\t\t\t\t\t\t[\"en\", \"/:path(.*)?\"],\n\t\t\t\t\t\t\t] as Array<[string, string]>,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst code = createRuntimeFile({\n\t\t\t\t\t\t\tbaseLocale: \"en\",\n\t\t\t\t\t\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\t\t\t\t\t\tcompilerOptions: {\n\t\t\t\t\t\t\t\t...defaultCompilerOptions,\n\t\t\t\t\t\t\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\t\t\t\t\t\t\ttrailingSlash,\n\t\t\t\t\t\t\t\turlPatterns: catchAllFirst\n\t\t\t\t\t\t\t\t\t? [catchAll, specific]\n\t\t\t\t\t\t\t\t\t: [specific, catchAll],\n\t\t\t\t\t\t\t\trouteStrategies: [\n\t\t\t\t\t\t\t\t\t{ match: pattern, exclude: true },\n\t\t\t\t\t\t\t\t\t{ match: \"/:path(.*)?\", strategy: [\"url\"] },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}).replace(\n\t\t\t\t\t\t\t'import \"@inlang/paraglide-js/urlpattern-polyfill\";',\n\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// The reference keeps native construction/matching and all filling\n\t\t\t\t\t\t// logic, but enumerates the original arrays without pruning.\n\t\t\t\t\t\tconst scan = code\n\t\t\t\t\t\t\t.replace(\n\t\t\t\t\t\t\t\t\"return patternCandidates(urlPatternIndex, url, urlPatterns);\",\n\t\t\t\t\t\t\t\t\"return urlPatterns;\"\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.replace(\n\t\t\t\t\t\t\t\t\"return patternCandidates(routeStrategyIndex, url, routeStrategies);\",\n\t\t\t\t\t\t\t\t\"return routeStrategies;\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\texpect(scan).not.toBe(code);\n\t\t\t\t\t\texpect(scan).not.toContain(\"return patternCandidates(\");\n\t\t\t\t\t\tconst load = (source: string) =>\n\t\t\t\t\t\t\timport(\n\t\t\t\t\t\t\t\t/* @vite-ignore */ \"data:text/javascript;base64,\" +\n\t\t\t\t\t\t\t\t\tBuffer.from(\n\t\t\t\t\t\t\t\t\t\tsource + `\\n// isolated fixture ${moduleId++}`\n\t\t\t\t\t\t\t\t\t).toString(\"base64\")\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tconst indexed = await load(code);\n\t\t\t\t\t\tconst original = await load(scan);\n\t\t\t\t\t\tfor (const pathname of paths.flatMap((path) => [\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t`/de${path}`,\n\t\t\t\t\t\t])) {\n\t\t\t\t\t\t\tfor (const asObject of [false, true]) {\n\t\t\t\t\t\t\t\tconst href = `https://user:pass@example.com${pathname}?redirect=%2Faccount#section`;\n\t\t\t\t\t\t\t\tconst input = asObject ? new URL(href) : href;\n\t\t\t\t\t\t\t\tconst operations = [\n\t\t\t\t\t\t\t\t\t(runtime: typeof indexed) =>\n\t\t\t\t\t\t\t\t\t\truntime.localizeUrl(input, { locale: \"de\" }),\n\t\t\t\t\t\t\t\t\t(runtime: typeof indexed) =>\n\t\t\t\t\t\t\t\t\t\truntime.localizeUrl(input, { locale: \"fr\" }),\n\t\t\t\t\t\t\t\t\t(runtime: typeof indexed) => runtime.deLocalizeUrl(input),\n\t\t\t\t\t\t\t\t\t(runtime: typeof indexed) =>\n\t\t\t\t\t\t\t\t\t\truntime.extractLocaleFromUrl(input),\n\t\t\t\t\t\t\t\t\t(runtime: typeof indexed) =>\n\t\t\t\t\t\t\t\t\t\truntime.findMatchingRouteStrategy(input),\n\t\t\t\t\t\t\t\t\t(runtime: typeof indexed) =>\n\t\t\t\t\t\t\t\t\t\truntime.generateStaticLocalizedUrls([input]),\n\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\tfor (const operation of operations) {\n\t\t\t\t\t\t\t\t\texpect(\n\t\t\t\t\t\t\t\t\t\toutcome(() => operation(indexed)),\n\t\t\t\t\t\t\t\t\t\t`${pattern}, slash=${trailingSlash}, catchAllFirst=${catchAllFirst}, ${href}`\n\t\t\t\t\t\t\t\t\t).toEqual(outcome(() => operation(original)));\n\t\t\t\t\t\t\t\t\tcomparisons++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\texpect(comparisons).toBe(31104);\n\t\t} finally {\n\t\t\tObject.defineProperty(globalThis, \"URLPattern\", {\n\t\t\t\tconfigurable: true,\n\t\t\t\twritable: true,\n\t\t\t\tvalue: previous,\n\t\t\t});\n\t\t}\n\t}, 30000);\n}\n"]}