@sebbro/paraglide-lite 0.1.1 → 0.1.2

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 (109) hide show
  1. package/dist/bundler-plugins/per-locale-build/index.js +5 -3
  2. package/dist/bundler-plugins/per-locale-build/index.js.map +1 -1
  3. package/dist/bundler-plugins/per-locale-build/vite-environments.js +12 -7
  4. package/dist/bundler-plugins/per-locale-build/vite-environments.js.map +1 -1
  5. package/dist/bundler-plugins/plugin-core.d.ts +38 -2
  6. package/dist/bundler-plugins/plugin-core.js +198 -11
  7. package/dist/bundler-plugins/plugin-core.js.map +1 -1
  8. package/dist/bundler-plugins/rolldown.test.js +15 -6
  9. package/dist/bundler-plugins/rolldown.test.js.map +1 -1
  10. package/dist/bundler-plugins/unplugin.js +5 -0
  11. package/dist/bundler-plugins/unplugin.js.map +1 -1
  12. package/dist/bundler-plugins/unplugin.test.js +67 -0
  13. package/dist/bundler-plugins/unplugin.test.js.map +1 -1
  14. package/dist/bundler-plugins/virtual-modules.test.js +64 -1
  15. package/dist/bundler-plugins/virtual-modules.test.js.map +1 -1
  16. package/dist/cli/commands/compile/command.js +8 -1
  17. package/dist/cli/commands/compile/command.js.map +1 -1
  18. package/dist/cli/commands/compile/command.test.js +51 -0
  19. package/dist/cli/commands/compile/command.test.js.map +1 -1
  20. package/dist/compiler/compile-annotation.d.ts +2 -2
  21. package/dist/compiler/compile-annotation.js +9 -9
  22. package/dist/compiler/compile-annotation.js.map +1 -1
  23. package/dist/compiler/compile-local-variable.d.ts +2 -1
  24. package/dist/compiler/compile-local-variable.js +4 -4
  25. package/dist/compiler/compile-local-variable.js.map +1 -1
  26. package/dist/compiler/compile-local-variable.test.js +82 -0
  27. package/dist/compiler/compile-local-variable.test.js.map +1 -1
  28. package/dist/compiler/compile-message.js +10 -2
  29. package/dist/compiler/compile-message.js.map +1 -1
  30. package/dist/compiler/compile-message.test.js +132 -2
  31. package/dist/compiler/compile-message.test.js.map +1 -1
  32. package/dist/compiler/compile-pattern.js +4 -2
  33. package/dist/compiler/compile-pattern.js.map +1 -1
  34. package/dist/compiler/compile-pattern.test.js +31 -0
  35. package/dist/compiler/compile-pattern.test.js.map +1 -1
  36. package/dist/compiler/compile.bench.js +1 -1
  37. package/dist/compiler/compile.bench.js.map +1 -1
  38. package/dist/compiler/compile.test.js +14 -0
  39. package/dist/compiler/compile.test.js.map +1 -1
  40. package/dist/compiler/compiler-options.d.ts +9 -1
  41. package/dist/compiler/compiler-options.js.map +1 -1
  42. package/dist/compiler/runtime/create-runtime.d.ts +1 -0
  43. package/dist/compiler/runtime/create-runtime.js +11 -0
  44. package/dist/compiler/runtime/create-runtime.js.map +1 -1
  45. package/dist/compiler/runtime/exec-url-pattern.d.ts +9 -0
  46. package/dist/compiler/runtime/exec-url-pattern.js +31 -0
  47. package/dist/compiler/runtime/exec-url-pattern.js.map +1 -0
  48. package/dist/compiler/runtime/extract-locale-from-url.js +9 -4
  49. package/dist/compiler/runtime/extract-locale-from-url.js.map +1 -1
  50. package/dist/compiler/runtime/generate-static-localized-urls.js +13 -6
  51. package/dist/compiler/runtime/generate-static-localized-urls.js.map +1 -1
  52. package/dist/compiler/runtime/generate-static-localized-urls.test.js +38 -0
  53. package/dist/compiler/runtime/generate-static-localized-urls.test.js.map +1 -1
  54. package/dist/compiler/runtime/localize-href.bench.d.ts +1 -0
  55. package/dist/compiler/runtime/localize-href.bench.js +68 -0
  56. package/dist/compiler/runtime/localize-href.bench.js.map +1 -0
  57. package/dist/compiler/runtime/localize-href.test.js +35 -0
  58. package/dist/compiler/runtime/localize-href.test.js.map +1 -1
  59. package/dist/compiler/runtime/localize-url.d.ts +14 -0
  60. package/dist/compiler/runtime/localize-url.js +338 -19
  61. package/dist/compiler/runtime/localize-url.js.map +1 -1
  62. package/dist/compiler/runtime/localize-url.test.js +139 -0
  63. package/dist/compiler/runtime/localize-url.test.js.map +1 -1
  64. package/dist/compiler/runtime/normalize-trailing-slash.d.ts +10 -0
  65. package/dist/compiler/runtime/normalize-trailing-slash.js +23 -0
  66. package/dist/compiler/runtime/normalize-trailing-slash.js.map +1 -0
  67. package/dist/compiler/runtime/route-strategy.js +4 -2
  68. package/dist/compiler/runtime/route-strategy.js.map +1 -1
  69. package/dist/compiler/runtime/should-redirect.js +4 -1
  70. package/dist/compiler/runtime/should-redirect.js.map +1 -1
  71. package/dist/compiler/runtime/should-redirect.test.js +26 -2
  72. package/dist/compiler/runtime/should-redirect.test.js.map +1 -1
  73. package/dist/compiler/runtime/type.d.ts +1 -0
  74. package/dist/compiler/runtime/type.js.map +1 -1
  75. package/dist/compiler/runtime/url-pattern.d.ts +11 -0
  76. package/dist/compiler/runtime/url-pattern.js +39 -1
  77. package/dist/compiler/runtime/url-pattern.js.map +1 -1
  78. package/dist/compiler/runtime/variables.d.ts +6 -0
  79. package/dist/compiler/runtime/variables.js +6 -0
  80. package/dist/compiler/runtime/variables.js.map +1 -1
  81. package/dist/compiler/server/create-server-file.js +18 -4
  82. package/dist/compiler/server/create-server-file.js.map +1 -1
  83. package/dist/compiler/server/create-server-file.test.js +76 -0
  84. package/dist/compiler/server/create-server-file.test.js.map +1 -1
  85. package/dist/compiler/server/middleware.js +6 -2
  86. package/dist/compiler/server/middleware.js.map +1 -1
  87. package/dist/compiler/server/middleware.test.js +30 -0
  88. package/dist/compiler/server/middleware.test.js.map +1 -1
  89. package/dist/compiler/variable-access.d.ts +2 -0
  90. package/dist/compiler/variable-access.js +6 -0
  91. package/dist/compiler/variable-access.js.map +1 -1
  92. package/dist/index.test.d.ts +1 -0
  93. package/dist/index.test.js +9 -0
  94. package/dist/index.test.js.map +1 -0
  95. package/dist/messages/load-messages.js +4 -5
  96. package/dist/messages/load-messages.js.map +1 -1
  97. package/dist/services/env-variables/index.js +1 -1
  98. package/dist/services/env-variables/index.js.map +1 -1
  99. package/dist/services/file-handling/write-output.bench.d.ts +1 -0
  100. package/dist/services/file-handling/write-output.bench.js +24 -0
  101. package/dist/services/file-handling/write-output.bench.js.map +1 -0
  102. package/dist/services/file-handling/write-output.d.ts +5 -0
  103. package/dist/services/file-handling/write-output.js +54 -9
  104. package/dist/services/file-handling/write-output.js.map +1 -1
  105. package/dist/services/file-handling/write-output.test.js +27 -0
  106. package/dist/services/file-handling/write-output.test.js.map +1 -1
  107. package/dist/services/logger/index.js +2 -0
  108. package/dist/services/logger/index.js.map +1 -1
  109. package/package.json +86 -86
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/compiler/server/middleware.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AAExC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO;IAClE,IAAI,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAC/D,uBAAuB;IACvB,MAAM,GAAG,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAE1B,IAAI,OAAO,CAAC,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;QAClC,MAAM,UAAU,GAAG,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1D,0BAA0B;QAC1B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QAC/B,OAAO,uBAAuB,CAAC,CAC9B,MAAM,wBAAwB,EAAE,GAAG,CAClC,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,EAChC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAC9C,CACD,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAE/B,4DAA4D;IAC5D,6DAA6D;IAC7D,IACC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,UAAU;QACpD,QAAQ,CAAC,cAAc;QACvB,QAAQ,CAAC,WAAW,EACnB,CAAC;QACF,+EAA+E;QAC/E,qCAAqC;QACrC,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,IAAI,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,MAAM,CAAC,GAAG,iBAAiB,CAAC;QACrC,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE;YACnC,MAAM,EAAE,GAAG;YACX,OAAO,EAAE;gBACR,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI;gBACnC,GAAG,OAAO;aACV;SACD,CAAC,CAAC;QAEH,OAAO,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,CAAC;QAChC,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,iEAAiE;IACjE,8CAA8C;IAC9C,EAAE;IACF,mEAAmE;IACnE,4DAA4D;IAC5D,4CAA4C;IAC5C,IAAI,UAAU,CAAC;IACf,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,UAAU,GAAG,wBAAwB,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACP,UAAU,GAAG,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,8DAA8D;IAC9D,0BAA0B;IAC1B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;IAE/B,MAAM,QAAQ,GAAG,MAAM,wBAAwB,EAAE,GAAG,CACnD,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,EAChC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAC9C,CAAC;IAEF,6BAA6B;IAC7B,IACC,OAAO,CAAC,qCAAqC;QAC7C,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,EACrD,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,MAAM,QAAQ,GAAG,EAAE,CAAC;QAEpB,6FAA6F;QAC7F,yIAAyI;QACzI,KAAK,MAAM,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YACpD,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC;YACjB,sDAAsD,CAAC,CACtD,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CACtB,CAAC;YACH,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,qEAAqE;QACrE,MAAM,eAAe,GAAG,QAAQ;aAC9B,IAAI,CAAC,GAAG,CAAC;aACT,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QACrC,8FAA8F;QAC9F,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO;aAC5B,GAAG,CAAC,yBAAyB,CAAC;YAC/B,EAAE,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,WAAW,SAAS,0FAA0F,eAAe,aAAa,CAAC;QAE1J,gDAAgD;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,MAAM,SAAS,CAAC,CAAC;QAE5D,+CAA+C;QAC/C,0EAA0E;QAC1E,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjD,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,+CAA+C;QAEpF,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE;YAC5B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO,EAAE,UAAU;SACnB,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,OAAO,EAAE,mBAAmB;IACzD,IAAI,OAAO,mBAAmB,KAAK,UAAU,EAAE,CAAC;QAC/C,OAAO,IAAI,GAAG,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,OAAO,mBAAmB,KAAK,QAAQ,IAAI,mBAAmB,YAAY,GAAG,EAAE,CAAC;QACnF,OAAO,IAAI,GAAG,CAAC,mBAAmB,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,wBAAwB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG;IAC3D,MAAM,SAAS,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC3D,IAAI,SAAS,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC;YACJ,mFAAmF;YACnF,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACR,IAAI,CAAC;gBACJ,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,OAAO,CAAC;YAChB,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,CAAC;QACJ,mFAAmF;QACnF,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACR,IAAI,CAAC;YACJ,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,OAAO,CAAC;QAChB,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,2BAA2B;IACnC,kBAAkB;IAClB,IAAI,YAAY,GAAG,SAAS,CAAC;IAC7B,OAAO;QACN,QAAQ;YACP,OAAO,YAAY,CAAC;QACrB,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ;YACxB,YAAY,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC;gBACJ,OAAO,MAAM,QAAQ,EAAE,CAAC;YACzB,CAAC;oBAAS,CAAC;gBACV,YAAY,GAAG,SAAS,CAAC;YAC1B,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,KAAK,2BAA2B,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,eAAe,GAAG,EAAE,CAAC","sourcesContent":["import * as runtime from \"./runtime.js\";\n\n/**\n * Server middleware that handles locale-based routing and request processing.\n *\n * Configure `disableAsyncLocalStorage` when generating Paraglide with\n * `paraglideVitePlugin()` or `compile()`, not when calling\n * `paraglideMiddleware()`. Keep AsyncLocalStorage enabled by default and\n * only disable it for runtimes that lack `AsyncLocalStorage` support and\n * guarantee request isolation.\n *\n * This middleware performs several key functions:\n *\n * 1. Determines the locale for the incoming request using configured strategies\n * 2. Handles URL localization and redirects (only for document requests)\n * 3. Maintains locale state using AsyncLocalStorage to prevent request interference\n *\n * When URL strategy is used:\n *\n * - The locale is extracted from the URL for all request types\n * - If URL doesn't match the determined locale, redirects to localized URL (only for document requests)\n * - De-localizes URLs before passing to server (e.g., `/fr/about` → `/about`)\n *\n * @see https://paraglidejs.com/middleware\n *\n * @template T - The return type of the resolve function\n *\n * @param {Request} request - The incoming request object\n * @param {(args: { request: Request, locale: import(\"./runtime.js\").Locale }) => T | Promise<T>} resolve - Function to handle the request. The callback receives:\n * - `request`: A modified request with a delocalized URL when the URL strategy is used (e.g., `/fr/about` → `/about`).\n * If your framework handles URL localization itself (e.g., TanStack Router's `rewrite` option), use the original\n * request instead to avoid redirect loops.\n * - `locale`: The determined locale for this request.\n * @param {{\n * effectiveRequestUrl?: string | URL | ((request: Request) => string | URL),\n * onRedirect?: (response: Response) => void\n * }} [options] - Options to control middleware behavior. `effectiveRequestUrl` sets the effective request URL used for route matching, URL-based locale detection, redirects, and `getUrlOrigin()`.\n * @returns {Promise<Response>}\n *\n * @example\n * ```typescript\n * // Basic usage in metaframeworks like NextJS, SvelteKit, Astro, Nuxt, etc.\n * export const handle = async ({ event, resolve }) => {\n * return paraglideMiddleware(event.request, ({ request, locale }) => {\n * // let the framework further resolve the request\n * return resolve(request);\n * });\n * };\n * ```\n *\n * @example\n * ```typescript\n * // Usage in a framework like Express JS or Hono\n * app.use(async (req, res, next) => {\n * const result = await paraglideMiddleware(req, ({ request, locale }) => {\n * // If a redirect happens this won't be called\n * return next(request);\n * });\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Usage with frameworks that handle URL localization/delocalization themselves\n * //\n * // Some frameworks like TanStack Router handle URL localization and delocalization\n * // themselves via their own rewrite APIs (e.g., `rewrite.input`/`rewrite.output`).\n * //\n * // When the framework handles this, the middleware's URL delocalization is not needed.\n * // Using the modified `request` from the callback would cause a redirect loop because\n * // both the middleware and the framework would attempt to delocalize the URL.\n * //\n * // Solution: Pass the original request to the handler instead of the modified one.\n * // The middleware still handles locale detection, cookies, and AsyncLocalStorage context.\n * //\n * // ❌ WRONG - causes redirect loop when framework handles URL rewriting:\n * // paraglideMiddleware(req, ({ request }) => handler.fetch(request))\n * //\n * // ✅ CORRECT - use original request when framework handles URL localization:\n * // paraglideMiddleware(req, () => handler.fetch(req))\n *\n * import { paraglideMiddleware } from './paraglide/server.js'\n * import handler from '@tanstack/react-start/server-entry'\n *\n * export default {\n * fetch(req: Request): Promise<Response> {\n * // TanStack Router handles URL rewriting via deLocalizeUrl/localizeUrl\n * // so we pass the original `req` instead of the modified `request`\n * return paraglideMiddleware(req, () => handler.fetch(req))\n * },\n * }\n * ```\n */\nexport async function paraglideMiddleware(request, resolve, options) {\n\tlet requestAsyncLocalStorage = runtime.serverAsyncLocalStorage;\n\t// %async-local-storage\n\tconst url = resolveMiddlewareUrl(request, options?.effectiveRequestUrl);\n\tconst origin = url.origin;\n\n\tif (runtime.isExcludedByRouteStrategy(url.href)) {\n\t\tconst locale = runtime.baseLocale;\n\t\tconst newRequest = cloneRequestWithFallback(request, url);\n\t\t/** @type {Set<string>} */\n\t\tconst messageCalls = new Set();\n\t\treturn /** @type {Response} */ (\n\t\t\tawait requestAsyncLocalStorage?.run(\n\t\t\t\t{ locale, origin, messageCalls },\n\t\t\t\t() => resolve({ locale, request: newRequest })\n\t\t\t)\n\t\t);\n\t}\n\n\tconst strategy = runtime.getStrategyForUrl(url.href);\n\tconst decision = await runtime.shouldRedirect({ request, effectiveRequestUrl: url });\n\tconst locale = decision.locale;\n\n\t// if the client makes a request to a URL that doesn't match\n\t// the localizedUrl, redirect the client to the localized URL\n\tif (\n\t\trequest.headers.get(\"Sec-Fetch-Dest\") === \"document\" &&\n\t\tdecision.shouldRedirect &&\n\t\tdecision.redirectUrl\n\t) {\n\t\t// Create headers object with Vary header if preferredLanguage strategy is used\n\t\t/** @type {Record<string, string>} */\n\t\tconst headers = {};\n\t\tif (strategy.includes(\"preferredLanguage\")) {\n\t\t\theaders[\"Vary\"] = \"Accept-Language\";\n\t\t}\n\n\t\tconst response = new Response(null, {\n\t\t\tstatus: 307,\n\t\t\theaders: {\n\t\t\t\tLocation: decision.redirectUrl.href,\n\t\t\t\t...headers,\n\t\t\t},\n\t\t});\n\n\t\toptions?.onRedirect?.(response);\n\t\treturn response;\n\t}\n\n\t// If the strategy includes \"url\", we need to de-localize the URL\n\t// before passing it to the server middleware.\n\t//\n\t// The middleware is responsible for mapping a localized URL to the\n\t// de-localized URL e.g. `/en/about` to `/about`. Otherwise,\n\t// the server can't render the correct page.\n\tlet newRequest;\n\tif (strategy.includes(\"url\")) {\n\t\tnewRequest = cloneRequestWithFallback(request, runtime.deLocalizeUrl(url));\n\t} else {\n\t\tnewRequest = cloneRequestWithFallback(request, url);\n\t}\n\n\t// the message functions that have been called in this request\n\t/** @type {Set<string>} */\n\tconst messageCalls = new Set();\n\n\tconst response = await requestAsyncLocalStorage?.run(\n\t\t{ locale, origin, messageCalls },\n\t\t() => resolve({ locale, request: newRequest })\n\t);\n\n\t// Only modify HTML responses\n\tif (\n\t\truntime.experimentalMiddlewareLocaleSplitting &&\n\t\tresponse.headers.get(\"Content-Type\")?.includes(\"html\")\n\t) {\n\t\tconst body = await response.text();\n\n\t\tconst messages = [];\n\n\t\t// using .values() to avoid polyfilling in older projects. else the following error is thrown\n\t\t// Type 'Set<string>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.\n\t\tfor (const messageCall of Array.from(messageCalls)) {\n\t\t\tconst [id, locale] =\n\t\t\t\t/** @type {[string, import(\"./runtime.js\").Locale]} */ (\n\t\t\t\t\tmessageCall.split(\":\")\n\t\t\t\t);\n\t\t\tmessages.push(`${id}: ${compiledBundles[id]?.[locale]}`);\n\t\t}\n\n\t\t// Prevent translated content from terminating the inline script tag.\n\t\tconst escapedMessages = messages\n\t\t\t.join(\",\")\n\t\t\t.replace(/<\\/(script)/gi, \"<\\\\/$1\");\n\t\t// Reuse the request's CSP nonce (if any) so the injected script is allowed under a strict CSP\n\t\tconst nonce = response.headers\n\t\t\t.get(\"Content-Security-Policy\")\n\t\t\t?.match(/'nonce-([\\w+/=-]+)'/)?.[1];\n\t\tconst nonceAttr = nonce ? `nonce=\"${nonce}\"` : \"\";\n\t\tconst script = `<script ${nonceAttr}>globalThis.__paraglide = globalThis.__paraglide ?? {}; globalThis.__paraglide.ssr = { ${escapedMessages} }</script>`;\n\n\t\t// Insert the script before the closing head tag\n\t\tconst newBody = body.replace(\"</head>\", `${script}</head>`);\n\n\t\t// Create a new response with the modified body\n\t\t// Clone all headers except Content-Length which will be set automatically\n\t\tconst newHeaders = new Headers(response.headers);\n\t\tnewHeaders.delete(\"Content-Length\"); // Let the browser calculate the correct length\n\n\t\treturn new Response(newBody, {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: newHeaders,\n\t\t});\n\t}\n\n\treturn response;\n}\n\n/**\n * @param {Request} request\n * @param {string | URL | ((request: Request) => string | URL) | undefined} effectiveRequestUrl\n * @returns {URL}\n */\nfunction resolveMiddlewareUrl(request, effectiveRequestUrl) {\n\tif (typeof effectiveRequestUrl === \"function\") {\n\t\treturn new URL(effectiveRequestUrl(request), request.url);\n\t}\n\n\tif (typeof effectiveRequestUrl === \"string\" || effectiveRequestUrl instanceof URL) {\n\t\treturn new URL(effectiveRequestUrl, request.url);\n\t}\n\n\treturn new URL(request.url);\n}\n\n/**\n * Some metaframeworks (NextJS) require a new Request object.\n * https://github.com/opral/inlang-paraglide-js/issues/411\n *\n * However, some frameworks (TanStack Start 1.143+) use custom Request\n * implementations that cannot be cloned with `new Request(request)`.\n * https://github.com/opral/paraglide-js/issues/573\n *\n * Effective request URL overrides behind proxies:\n * https://github.com/opral/paraglide-js/issues/652\n *\n * @param {Request} request\n * @param {string | URL} [url]\n * @returns {Request}\n */\nfunction cloneRequestWithFallback(request, url = request.url) {\n\tconst targetUrl = typeof url === \"string\" ? url : url.href;\n\tif (targetUrl === request.url) {\n\t\ttry {\n\t\t\t// Clone first so building a new Request does not consume the original body stream.\n\t\t\treturn new Request(request.clone());\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\treturn new Request(request);\n\t\t\t} catch {\n\t\t\t\treturn request;\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\t// Clone first so building a new Request does not consume the original body stream.\n\t\treturn new Request(targetUrl, request.clone());\n\t} catch {\n\t\ttry {\n\t\t\treturn new Request(targetUrl, request);\n\t\t} catch {\n\t\t\treturn request;\n\t\t}\n\t}\n}\n\n/**\n * Creates a mock AsyncLocalStorage implementation for environments where\n * native AsyncLocalStorage is not available or disabled.\n *\n * This mock implementation mimics the behavior of the native AsyncLocalStorage\n * but doesn't require the async_hooks module. It's used as a fallback when\n * the runtime does not expose AsyncLocalStorage or when it has been disabled.\n *\n * @returns {import(\"./runtime.js\").ParaglideAsyncLocalStorage}\n */\nfunction createMockAsyncLocalStorage() {\n\t/** @type {any} */\n\tlet currentStore = undefined;\n\treturn {\n\t\tgetStore() {\n\t\t\treturn currentStore;\n\t\t},\n\t\tasync run(store, callback) {\n\t\t\tcurrentStore = store;\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tcurrentStore = undefined;\n\t\t\t}\n\t\t},\n\t};\n}\n\n// Used in generated server.js when async local storage is disabled.\nvoid createMockAsyncLocalStorage;\n\n/**\n * The compiled messages for the server middleware.\n *\n * Only populated if `enableMiddlewareOptimizations` is set to `true`.\n *\n * @type {Record<string, Record<import(\"./runtime.js\").Locale, string>>}\n */\nconst compiledBundles = {};\n"]}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/compiler/server/middleware.js"],"names":[],"mappings":"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","sourcesContent":["import * as runtime from \"./runtime.js\";\n\n/**\n * Server middleware that handles locale-based routing and request processing.\n *\n * Configure `disableAsyncLocalStorage` when generating Paraglide with\n * `paraglideVitePlugin()` or `compile()`, not when calling\n * `paraglideMiddleware()`. Keep AsyncLocalStorage enabled by default and\n * only disable it for runtimes that lack `AsyncLocalStorage` support and\n * guarantee request isolation.\n *\n * This middleware performs several key functions:\n *\n * 1. Determines the locale for the incoming request using configured strategies\n * 2. Handles URL localization and redirects (only for document requests)\n * 3. Maintains locale state using AsyncLocalStorage to prevent request interference\n *\n * When URL strategy is used:\n *\n * - The locale is extracted from the URL for all request types\n * - If URL doesn't match the determined locale, redirects to localized URL (only for document requests)\n * - De-localizes URLs before passing to server (e.g., `/fr/about` → `/about`)\n *\n * @see https://paraglidejs.com/middleware\n *\n * @template T - The return type of the resolve function\n *\n * @param {Request} request - The incoming request object\n * @param {(args: { request: Request, locale: import(\"./runtime.js\").Locale }) => T | Promise<T>} resolve - Function to handle the request. The callback receives:\n * - `request`: A modified request with a delocalized URL when the URL strategy is used (e.g., `/fr/about` → `/about`).\n * If your framework handles URL localization itself (e.g., TanStack Router's `rewrite` option), use the original\n * request instead to avoid redirect loops.\n * - `locale`: The determined locale for this request.\n * @param {{\n * effectiveRequestUrl?: string | URL | ((request: Request) => string | URL),\n * onRedirect?: (response: Response) => void\n * }} [options] - Options to control middleware behavior. `effectiveRequestUrl` sets the effective request URL used for route matching, URL-based locale detection, redirects, and `getUrlOrigin()`.\n * @returns {Promise<Response>}\n *\n * @example\n * ```typescript\n * // Basic usage in metaframeworks like NextJS, SvelteKit, Astro, Nuxt, etc.\n * export const handle = async ({ event, resolve }) => {\n * return paraglideMiddleware(event.request, ({ request, locale }) => {\n * // let the framework further resolve the request\n * return resolve(request);\n * });\n * };\n * ```\n *\n * @example\n * ```typescript\n * // Usage in a framework like Express JS or Hono\n * app.use(async (req, res, next) => {\n * const result = await paraglideMiddleware(req, ({ request, locale }) => {\n * // If a redirect happens this won't be called\n * return next(request);\n * });\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Usage with frameworks that handle URL localization/delocalization themselves\n * //\n * // Some frameworks like TanStack Router handle URL localization and delocalization\n * // themselves via their own rewrite APIs (e.g., `rewrite.input`/`rewrite.output`).\n * //\n * // When the framework handles this, the middleware's URL delocalization is not needed.\n * // Using the modified `request` from the callback would cause a redirect loop because\n * // both the middleware and the framework would attempt to delocalize the URL.\n * //\n * // Solution: Pass the original request to the handler instead of the modified one.\n * // The middleware still handles locale detection, cookies, and AsyncLocalStorage context.\n * //\n * // ❌ WRONG - causes redirect loop when framework handles URL rewriting:\n * // paraglideMiddleware(req, ({ request }) => handler.fetch(request))\n * //\n * // ✅ CORRECT - use original request when framework handles URL localization:\n * // paraglideMiddleware(req, () => handler.fetch(req))\n *\n * import { paraglideMiddleware } from './paraglide/server.js'\n * import handler from '@tanstack/react-start/server-entry'\n *\n * export default {\n * fetch(req: Request): Promise<Response> {\n * // TanStack Router handles URL rewriting via deLocalizeUrl/localizeUrl\n * // so we pass the original `req` instead of the modified `request`\n * return paraglideMiddleware(req, () => handler.fetch(req))\n * },\n * }\n * ```\n */\nexport async function paraglideMiddleware(request, resolve, options) {\n\tlet requestAsyncLocalStorage = runtime.serverAsyncLocalStorage;\n\t// %async-local-storage\n\tconst url = resolveMiddlewareUrl(request, options?.effectiveRequestUrl);\n\tconst origin = url.origin;\n\n\tif (runtime.isExcludedByRouteStrategy(url.href)) {\n\t\tconst locale = runtime.baseLocale;\n\t\tconst newRequest = cloneRequestWithFallback(request, url);\n\t\t/** @type {Set<string>} */\n\t\tconst messageCalls = new Set();\n\t\treturn /** @type {Response} */ (\n\t\t\tawait requestAsyncLocalStorage?.run(\n\t\t\t\t{ locale, origin, messageCalls },\n\t\t\t\t() => resolve({ locale, request: newRequest })\n\t\t\t)\n\t\t);\n\t}\n\n\tconst strategy = runtime.getStrategyForUrl(url.href);\n\tconst decision = await runtime.shouldRedirect({\n\t\trequest,\n\t\teffectiveRequestUrl: url,\n\t});\n\tconst locale = decision.locale;\n\n\t// if the client makes a request to a URL that doesn't match\n\t// the localizedUrl, redirect the client to the localized URL\n\tif (\n\t\trequest.headers.get(\"Sec-Fetch-Dest\") === \"document\" &&\n\t\tdecision.shouldRedirect &&\n\t\tdecision.redirectUrl\n\t) {\n\t\t// Create headers object with Vary header if preferredLanguage strategy is used\n\t\t/** @type {Record<string, string>} */\n\t\tconst headers = {};\n\t\tif (strategy.includes(\"preferredLanguage\")) {\n\t\t\theaders[\"Vary\"] = \"Accept-Language\";\n\t\t}\n\n\t\tconst response = new Response(null, {\n\t\t\tstatus: 307,\n\t\t\theaders: {\n\t\t\t\tLocation: decision.redirectUrl.href,\n\t\t\t\t...headers,\n\t\t\t},\n\t\t});\n\n\t\toptions?.onRedirect?.(response);\n\t\treturn response;\n\t}\n\n\t// If the strategy includes \"url\", we need to de-localize the URL\n\t// before passing it to the server middleware.\n\t//\n\t// The middleware is responsible for mapping a localized URL to the\n\t// de-localized URL e.g. `/en/about` to `/about`. Otherwise,\n\t// the server can't render the correct page.\n\tlet newRequest;\n\tif (strategy.includes(\"url\")) {\n\t\tnewRequest = cloneRequestWithFallback(request, runtime.deLocalizeUrl(url));\n\t} else {\n\t\tnewRequest = cloneRequestWithFallback(request, url);\n\t}\n\n\t// the message functions that have been called in this request\n\t/** @type {Set<string>} */\n\tconst messageCalls = new Set();\n\n\tconst response = await requestAsyncLocalStorage?.run(\n\t\t{ locale, origin, messageCalls },\n\t\t() => resolve({ locale, request: newRequest })\n\t);\n\n\t// Only modify HTML responses\n\tif (\n\t\truntime.experimentalMiddlewareLocaleSplitting &&\n\t\tresponse.headers.get(\"Content-Type\")?.includes(\"html\")\n\t) {\n\t\tconst body = await response.text();\n\n\t\tconst messages = [];\n\n\t\t// using .values() to avoid polyfilling in older projects. else the following error is thrown\n\t\t// Type 'Set<string>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.\n\t\tfor (const messageCall of Array.from(messageCalls)) {\n\t\t\tconst [id, locale] =\n\t\t\t\t/** @type {[string, import(\"./runtime.js\").Locale]} */ (\n\t\t\t\t\tmessageCall.split(\":\")\n\t\t\t\t);\n\t\t\tmessages.push(`${id}: ${compiledBundles[id]?.[locale]}`);\n\t\t}\n\n\t\t// Prevent translated content from terminating the inline script tag.\n\t\tconst escapedMessages = messages\n\t\t\t.join(\",\")\n\t\t\t.replace(/<\\/(script)/gi, \"<\\\\/$1\");\n\t\t// Reuse the request's CSP nonce (if any) so the injected script is allowed under a strict CSP\n\t\tconst nonce = response.headers\n\t\t\t.get(\"Content-Security-Policy\")\n\t\t\t?.match(/'nonce-([\\w+/=-]+)'/)?.[1];\n\t\tconst nonceAttr = nonce ? `nonce=\"${nonce}\"` : \"\";\n\t\tconst script = `<script ${nonceAttr}>globalThis.__paraglide = globalThis.__paraglide ?? {}; globalThis.__paraglide.ssr = { ${escapedMessages} }</script>`;\n\n\t\t// Insert the script before the closing head tag\n\t\tconst newBody = body.replace(\"</head>\", `${script}</head>`);\n\n\t\t// Create a new response with the modified body\n\t\t// Clone all headers except Content-Length which will be set automatically\n\t\tconst newHeaders = new Headers(response.headers);\n\t\tnewHeaders.delete(\"Content-Length\"); // Let the browser calculate the correct length\n\n\t\treturn new Response(newBody, {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: newHeaders,\n\t\t});\n\t}\n\n\treturn response;\n}\n\n/**\n * @param {Request} request\n * @param {string | URL | ((request: Request) => string | URL) | undefined} effectiveRequestUrl\n * @returns {URL}\n */\nfunction resolveMiddlewareUrl(request, effectiveRequestUrl) {\n\tif (typeof effectiveRequestUrl === \"function\") {\n\t\treturn new URL(effectiveRequestUrl(request), request.url);\n\t}\n\n\tif (\n\t\ttypeof effectiveRequestUrl === \"string\" ||\n\t\teffectiveRequestUrl instanceof URL\n\t) {\n\t\treturn new URL(effectiveRequestUrl, request.url);\n\t}\n\n\treturn new URL(request.url);\n}\n\n/**\n * Some metaframeworks (NextJS) require a new Request object.\n * https://github.com/opral/inlang-paraglide-js/issues/411\n *\n * However, some frameworks (TanStack Start 1.143+) use custom Request\n * implementations that cannot be cloned with `new Request(request)`.\n * https://github.com/opral/paraglide-js/issues/573\n *\n * Effective request URL overrides behind proxies:\n * https://github.com/opral/paraglide-js/issues/652\n *\n * @param {Request} request\n * @param {string | URL} [url]\n * @returns {Request}\n */\nfunction cloneRequestWithFallback(request, url = request.url) {\n\tconst targetUrl = typeof url === \"string\" ? url : url.href;\n\tif (targetUrl === request.url) {\n\t\ttry {\n\t\t\t// Clone first so building a new Request does not consume the original body stream.\n\t\t\treturn new Request(request.clone());\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\treturn new Request(request);\n\t\t\t} catch {\n\t\t\t\treturn request;\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\t// Clone first so building a new Request does not consume the original body stream.\n\t\treturn new Request(targetUrl, request.clone());\n\t} catch {\n\t\ttry {\n\t\t\treturn new Request(targetUrl, request);\n\t\t} catch {\n\t\t\treturn request;\n\t\t}\n\t}\n}\n\n/**\n * Creates a mock AsyncLocalStorage implementation for environments where\n * native AsyncLocalStorage is not available or disabled.\n *\n * This mock implementation mimics the behavior of the native AsyncLocalStorage\n * but doesn't require the async_hooks module. It's used as a fallback when\n * the runtime does not expose AsyncLocalStorage or when it has been disabled.\n *\n * @returns {import(\"./runtime.js\").ParaglideAsyncLocalStorage}\n */\nfunction createMockAsyncLocalStorage() {\n\t/** @type {any} */\n\tlet currentStore = undefined;\n\treturn {\n\t\tgetStore() {\n\t\t\treturn currentStore;\n\t\t},\n\t\tasync run(store, callback) {\n\t\t\tcurrentStore = store;\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tcurrentStore = undefined;\n\t\t\t}\n\t\t},\n\t};\n}\n\n// Used in generated server.js when async local storage is disabled.\nvoid createMockAsyncLocalStorage;\n\n/**\n * The compiled messages for the server middleware.\n *\n * Only populated if `enableMiddlewareOptimizations` is set to `true`.\n *\n * @type {Record<string, Record<import(\"./runtime.js\").Locale, string>>}\n */\nconst compiledBundles = {};\n"]}
@@ -620,6 +620,36 @@ test("prevents redirect loops by normalizing URLs with trailing slashes in diffe
620
620
  expect(response.status).toBe(307);
621
621
  expect(response.headers.get("Location")).toBe("https://example.com/fr/different-page");
622
622
  });
623
+ // https://github.com/opral/paraglide-js/issues/473
624
+ test("canonicalizes translated pathnames with the configured trailing slash policy", async () => {
625
+ const runtime = await createParaglide({
626
+ baseLocale: "en",
627
+ locales: ["en", "de"],
628
+ strategy: ["url", "baseLocale"],
629
+ trailingSlash: "never",
630
+ urlPatterns: [
631
+ {
632
+ pattern: "/about",
633
+ localized: [
634
+ ["en", "/about"],
635
+ ["de", "/de/ueber"],
636
+ ],
637
+ },
638
+ ],
639
+ });
640
+ const response = await runtime.paraglideMiddleware(new Request("https://example.com/de/ueber/", {
641
+ headers: { "Sec-Fetch-Dest": "document" },
642
+ }), () => {
643
+ throw new Error("canonical document requests should redirect first");
644
+ });
645
+ expect(response.status).toBe(307);
646
+ expect(response.headers.get("Location")).toBe("https://example.com/de/ueber");
647
+ await runtime.paraglideMiddleware(new Request("https://example.com/de/ueber/"), ({ locale, request }) => {
648
+ expect(locale).toBe("de");
649
+ expect(request.url).toBe("https://example.com/about");
650
+ return new Response();
651
+ });
652
+ });
623
653
  // not implemented because users should disable redirects by
624
654
  // making another strategy preceed the url strategy
625
655
  //
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.test.js","sourceRoot":"","sources":["../../../src/compiler/server/middleware.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"vitest\";\nimport { createParaglide } from \"../create-paraglide.js\";\n\ntest(\"sets the locale and origin\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tstrategy: [\"url\", \"globalVariable\"],\n\t});\n\n\t// setting the global variable to fr to assure that\n\truntime.setLocale(\"fr\");\n\n\t// simulating multiple requests that could interfere with each other\n\tawait Promise.all([\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://example.com/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\texpect(runtime.getLocale()).toBe(\"en\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\t\treturn new Response();\n\t\t\t}\n\t\t),\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://peter.com/de/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\texpect(runtime.getLocale()).toBe(\"de\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://peter.com\");\n\t\t\t\treturn new Response();\n\t\t\t}\n\t\t),\n\t]);\n\n\t// global variable is not impacted by middleware\n\texpect(runtime.getLocale()).toBe(\"fr\");\n});\n\ntest(\"delocalizes the url if the url strategy is used and returns the locale\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t});\n\n\tconst request = new Request(new URL(\"https://example.com/de/page\"), {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\tconst result = await runtime.paraglideMiddleware(request, (args) => {\n\t\texpect(args.locale).toBe(\"de\");\n\t\texpect(args.request.url).toBe(\"https://example.com/page\");\n\t\treturn new Response(\"Hello World\");\n\t});\n\n\texpect(await result.text()).toBe(\"Hello World\");\n});\n\ntest(\"does not delocalize the url if the url strategy is not used\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t});\n\n\tconst request = new Request(new URL(\"https://example.com/de/page\"), {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\tconst result = await runtime.paraglideMiddleware(request, (args) => {\n\t\texpect(args.locale).toBe(\"en\");\n\t\texpect(args.request.url).toBe(\"https://example.com/de/page\");\n\t\treturn new Response(\"Hello World\");\n\t});\n\n\texpect(await result.text()).toBe(\"Hello World\");\n});\n\ntest(\"skips i18n middleware behavior for excluded routeStrategies\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\trouteStrategies: [{ match: \"/api/:path(.*)?\", exclude: true }],\n\t});\n\n\tconst request = new Request(\"https://example.com/api/data\", {\n\t\theaders: {\n\t\t\tcookie: \"PARAGLIDE_LOCALE=fr\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t({ locale, request }) => new Response(`${locale}|${request.url}`)\n\t);\n\n\texpect(response.status).toBe(200);\n\texpect(await response.text()).toBe(\"en|https://example.com/api/data\");\n});\n\ntest(\"localized URLs still match routeStrategies after delocalization\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"url\", \"cookie\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\trouteStrategies: [\n\t\t\t{\n\t\t\t\tmatch: \"/dashboard/:path(.*)?\",\n\t\t\t\tstrategy: [\"cookie\", \"baseLocale\"],\n\t\t\t},\n\t\t\t{ match: \"/api/:path(.*)?\", exclude: true },\n\t\t],\n\t});\n\n\tconst dashboard = await runtime.paraglideMiddleware(\n\t\tnew Request(\"https://example.com/fr/dashboard\", {\n\t\t\theaders: { cookie: \"PARAGLIDE_LOCALE=en\" },\n\t\t}),\n\t\t({ locale }) => new Response(locale)\n\t);\n\texpect(await dashboard.text()).toBe(\"en\");\n\n\tconst api = await runtime.paraglideMiddleware(\n\t\tnew Request(\"https://example.com/fr/api/data\", {\n\t\t\theaders: { cookie: \"PARAGLIDE_LOCALE=fr\" },\n\t\t}),\n\t\t({ locale, request }) => new Response(`${locale}|${request.url}`)\n\t);\n\texpect(await api.text()).toBe(\"en|https://example.com/fr/api/data\");\n});\n\ntest(\"excluded routeStrategies keep request-scoped locale context and clone request when possible\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t\trouteStrategies: [{ match: \"/api/:path(.*)?\", exclude: true }],\n\t});\n\n\truntime.setLocale(\"fr\");\n\tconst originalRequest = new Request(\"https://example.com/api/data\", {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\toriginalRequest,\n\t\t({ locale, request }) => {\n\t\t\texpect(locale).toBe(\"en\");\n\t\t\texpect(runtime.getLocale()).toBe(\"en\");\n\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\texpect(request).not.toBe(originalRequest);\n\t\t\texpect(request.url).toBe(\"https://example.com/api/data\");\n\t\t\treturn new Response(\"ok\");\n\t\t}\n\t);\n\n\texpect(await response.text()).toBe(\"ok\");\n\texpect(runtime.getLocale()).toBe(\"fr\");\n});\n\ntest(\"excluded routeStrategies fall back to original request when cloning fails\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t\trouteStrategies: [{ match: \"/api/:path(.*)?\", exclude: true }],\n\t});\n\n\tconst customRequest = {\n\t\turl: \"https://example.com/api/data\",\n\t\theaders: new Headers({ \"Sec-Fetch-Dest\": \"document\" }),\n\t\tmethod: \"GET\",\n\t} as unknown as Request;\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\tcustomRequest,\n\t\t({ locale, request }) => {\n\t\t\texpect(locale).toBe(\"en\");\n\t\t\texpect(request).toBe(customRequest);\n\t\t\treturn new Response(\"ok\");\n\t\t}\n\t);\n\n\texpect(await response.text()).toBe(\"ok\");\n});\n\ntest(\"excluded routeStrategies preserve original request body readability\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t\trouteStrategies: [{ match: \"/api/:path(.*)?\", exclude: true }],\n\t});\n\n\tconst originalRequest = new Request(\"https://example.com/api/data\", {\n\t\tmethod: \"POST\",\n\t\tbody: \"hello=world\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\toriginalRequest,\n\t\tasync ({ request }) => {\n\t\t\texpect(await request.text()).toBe(\"hello=world\");\n\t\t\treturn new Response(\"ok\");\n\t\t}\n\t);\n\n\texpect(await response.text()).toBe(\"ok\");\n\texpect(await originalRequest.text()).toBe(\"hello=world\");\n});\n\ntest(\"routeStrategies layering is first-match-wins when exclude comes first\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\trouteStrategies: [\n\t\t\t{ match: \"/api/:path(.*)?\", exclude: true },\n\t\t\t{ match: \"/api/:path(.*)?\", strategy: [\"cookie\", \"baseLocale\"] },\n\t\t],\n\t});\n\n\tconst request = new Request(\"https://example.com/api/data\", {\n\t\theaders: {\n\t\t\tcookie: \"PARAGLIDE_LOCALE=fr\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t({ locale, request }) => new Response(`${locale}|${request.url}`)\n\t);\n\n\texpect(response.status).toBe(200);\n\texpect(await response.text()).toBe(\"en|https://example.com/api/data\");\n});\n\ntest(\"routeStrategies layering is first-match-wins when strategy comes first\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\trouteStrategies: [\n\t\t\t{ match: \"/api/:path(.*)?\", strategy: [\"cookie\", \"baseLocale\"] },\n\t\t\t{ match: \"/api/:path(.*)?\", exclude: true },\n\t\t],\n\t});\n\n\tconst request = new Request(\"https://example.com/api/data\", {\n\t\theaders: {\n\t\t\tcookie: \"PARAGLIDE_LOCALE=fr\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t({ locale, request }) => new Response(`${locale}|${request.url}`)\n\t);\n\n\texpect(response.status).toBe(200);\n\texpect(await response.text()).toBe(\"fr|https://example.com/api/data\");\n});\n\ntest(\"redirects to localized URL when non-URL strategy determines locale\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request to URL in en with cookie specifying French\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(request, () => {\n\t\t// This shouldn't be called since we should redirect\n\t\tthrow new Error(\"Should not reach here\");\n\t});\n\n\texpect(response instanceof Response).toBe(true);\n\t// needs to be 307 status code https://github.com/opral/inlang-paraglide-js/issues/416\n\texpect(response.status).toBe(307); // Redirect status code\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n});\n\ntest(\"call onRedirect callback when redirecting to new url\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request to URL in en with cookie specifying French\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tlet response: any;\n\n\tawait runtime.paraglideMiddleware(\n\t\trequest,\n\t\t() => {\n\t\t\t// This shouldn't be called since we should redirect\n\t\t\tthrow new Error(\"Should not reach here\");\n\t\t},\n\t\t{\n\t\t\tonRedirect: (res: Response) => {\n\t\t\t\tresponse = res;\n\t\t\t},\n\t\t}\n\t);\n\n\texpect(response instanceof Response).toBe(true);\n\t// needs to be 307 status code https://github.com/opral/inlang-paraglide-js/issues/416\n\texpect(response.status).toBe(307); // Redirect status code\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n});\n\ntest(\"uses the provided public url for redirects behind a proxy\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst request = new Request(\"http://internal.example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t() => {\n\t\t\tthrow new Error(\"Should not reach here\");\n\t\t},\n\t\t{\n\t\t\teffectiveRequestUrl: \"https://example.com/en/some-path\",\n\t\t}\n\t);\n\n\texpect(response.status).toBe(307);\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n});\n\ntest(\"uses the provided public url for callback request and origin\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst request = new Request(\"http://internal.example.com/fr/some-path\", {\n\t\theaders: {\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t({ request }) => {\n\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\treturn new Response(request.url);\n\t\t},\n\t\t{\n\t\t\teffectiveRequestUrl: \"https://example.com/fr/some-path\",\n\t\t}\n\t);\n\n\texpect(await response.text()).toBe(\"https://example.com/some-path\");\n});\n\ntest(\"sets Vary: Accept-Language header when preferredLanguage strategy is used and redirect occurs\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"preferredLanguage\", \"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request with Accept-Language header preferring French\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\t\"Accept-Language\": \"fr,en;q=0.8\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(request, () => {\n\t\t// This shouldn't be called since we should redirect\n\t\tthrow new Error(\"Should not reach here\");\n\t});\n\n\texpect(response instanceof Response).toBe(true);\n\texpect(response.status).toBe(307); // Redirect status code\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n\t// Should have Vary header when preferredLanguage strategy is used\n\texpect(response.headers.get(\"Vary\")).toBe(\"Accept-Language\");\n});\n\ntest(\"does not set Vary header when preferredLanguage strategy is not used\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request with cookie specifying French\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(request, () => {\n\t\t// This shouldn't be called since we should redirect\n\t\tthrow new Error(\"Should not reach here\");\n\t});\n\n\texpect(response instanceof Response).toBe(true);\n\texpect(response.status).toBe(307); // Redirect status code\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n\t// Should NOT have Vary header when preferredLanguage strategy is not used\n\texpect(response.headers.get(\"Vary\")).toBe(null);\n});\n\ntest(\"does not call onRedirect callback when there is no redirecting\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request to URL in en with cookie specifying French\n\tconst request = new Request(\"https://example.com/fr/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tlet response: any = null;\n\n\tawait runtime.paraglideMiddleware(\n\t\trequest,\n\t\t() => {\n\t\t\treturn new Response(\"Hello World\");\n\t\t},\n\t\t{\n\t\t\tonRedirect: (res: Response) => {\n\t\t\t\tresponse = res;\n\t\t\t},\n\t\t}\n\t);\n\n\texpect(response).toBe(null);\n});\n\ntest(\"does not redirect if URL already matches determined locale\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request to already localized URL matching cookie locale\n\tconst request = new Request(\"https://example.com/fr/some-path\", {\n\t\theaders: {\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t},\n\t});\n\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(request, () => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\treturn new Response();\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true); // Middleware should be called since no redirect needed\n});\n\ntest(\"works with disableAsyncLocalStorage option\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tstrategy: [\"url\", \"globalVariable\"],\n\t\tdisableAsyncLocalStorage: true,\n\t});\n\n\t// Set a global locale to verify it doesn't interfere with request processing\n\truntime.setLocale(\"fr\");\n\n\t// Create a request with a \"de\" locale in the URL\n\tconst request = new Request(new URL(\"https://example.com/de/page\"), {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\t// Process the request with AsyncLocalStorage disabled\n\tconst response = await runtime.paraglideMiddleware(request, (args) => {\n\t\t// Verify we still get the correct locale\n\t\texpect(args.locale).toBe(\"de\");\n\t\texpect(runtime.getLocale()).toBe(\"de\");\n\t\t// Verify URL is still properly delocalized\n\t\texpect(args.request.url).toBe(\"https://example.com/page\");\n\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\treturn new Response(\"hello\");\n\t});\n\n\t// Verify the result contains the correct data\n\texpect(await response.text()).toBe(\"hello\");\n\n\t// Verify that global variable wasn't affected by this request\n\texpect(runtime.getLocale()).toBe(\"fr\");\n});\n\ntest(\"works with sequential parallel requests using disableAsyncLocalStorage\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tstrategy: [\"url\", \"globalVariable\"],\n\t});\n\n\t// setting the global variable to fr to assure that\n\truntime.setLocale(\"fr\");\n\n\t// simulating multiple requests that could interference with each other\n\tawait Promise.all([\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://example.com/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\texpect(runtime.getLocale()).toBe(\"en\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\t\treturn new Response();\n\t\t\t}\n\t\t),\n\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://peter.com/de/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\texpect(runtime.getLocale()).toBe(\"de\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://peter.com\");\n\t\t\t\treturn new Response();\n\t\t\t}\n\t\t),\n\t]);\n\n\t// global variable is not impacted by middleware\n\texpect(runtime.getLocale()).toBe(\"fr\");\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/442\ntest(\"falls back to next strategy when cookie contains invalid locale\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request with an invalid locale in cookie\n\tconst request = new Request(\"https://example.com/fr/some-path\", {\n\t\theaders: {\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\tcookie: `PARAGLIDE_LOCALE=invalid_locale`,\n\t\t},\n\t});\n\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(request, (args) => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\t// Should fall back to URL strategy, which will detect 'fr' from the URL\n\t\texpect(args.locale).toBe(\"fr\");\n\t\treturn new Response();\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true);\n\n\t// Try with a request that would fall back to baseLocale\n\tconst baseRequest = new Request(\"https://example.com/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=invalid_locale`,\n\t\t},\n\t});\n\n\tawait runtime.paraglideMiddleware(baseRequest, (args) => {\n\t\t// Should fall back all the way to baseLocale since URL has no locale\n\t\texpect(args.locale).toBe(\"en\");\n\t\treturn new Response();\n\t});\n});\n\n// can likely be removed once the default url pattern polyfill workaround is removed\n// because URLPattern seems to be handling this correctly\ntest(\"prevents redirect loops by normalizing URLs with trailing slashes in different scenarios\", async () => {\n\t// Create two different runtimes to test different strategy configurations\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// SCENARIO 1: Basic trailing slash normalization with cookie strategy\n\n\t// Case 1A: Request URL has trailing slash, but localized URL might not\n\tconst requestWithTrailingSlash = new Request(\"https://example.com/fr/page/\", {\n\t\theaders: {\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t},\n\t});\n\n\tlet response = await runtime.paraglideMiddleware(\n\t\trequestWithTrailingSlash,\n\t\t() => {\n\t\t\treturn new Response(\"No redirect needed\");\n\t\t}\n\t);\n\n\t// Middleware should be called (no redirect) because normalized URLs match\n\texpect(response.status).toBe(200);\n\texpect(await response.text()).toBe(\"No redirect needed\");\n\n\t// Case 1B: Request URL has no trailing slash, but localized URL might\n\tconst requestWithoutTrailingSlash = new Request(\n\t\t\"https://example.com/fr/page\",\n\t\t{\n\t\t\theaders: {\n\t\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t},\n\t\t}\n\t);\n\n\tresponse = await runtime.paraglideMiddleware(\n\t\trequestWithoutTrailingSlash,\n\t\t() => {\n\t\t\treturn new Response(\"No redirect needed\");\n\t\t}\n\t);\n\n\texpect(response.status).toBe(200);\n\n\t// Case 1C: redirect wanted because cookie is set to fr but url is en\n\tconst requestDifferentPath = new Request(\n\t\t\"https://example.com/en/different-page\",\n\t\t{\n\t\t\theaders: {\n\t\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t},\n\t\t}\n\t);\n\n\tresponse = await runtime.paraglideMiddleware(requestDifferentPath, () => {\n\t\t// This shouldn't be called since we should redirect\n\t\tthrow new Error(\"Should not reach here\");\n\t});\n\n\t// Should redirect to fr version\n\texpect(response.status).toBe(307);\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/different-page\"\n\t);\n});\n\n// not implemented because users should disable redirects by\n// making another strategy preceed the url strategy\n//\n// strategy: [\"cookie\", \"url\"]\ntest.skip(\"doesn't redirect if disableUrlRedirect is true\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Create a request that would normally be redirected\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\t// Test with disableUrlRedirect = true\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(\n\t\trequest,\n\t\t() => {\n\t\t\tmiddlewareResolveWasCalled = true;\n\t\t\treturn new Response(\"No redirect\");\n\t\t}\n\t\t// { disableUrlRedirect: true }\n\t);\n\n\t// Middleware should be called since redirect is disabled\n\texpect(middlewareResolveWasCalled).toBe(true);\n});\n\ntest(\"only redirects if the request.headers.get('Sec-Fetch-Dest') === 'document'\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Test with Sec-Fetch-Dest = document (should redirect)\n\tconst documentRequest = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst documentResponse = await runtime.paraglideMiddleware(\n\t\tdocumentRequest,\n\t\t() => {\n\t\t\t// This shouldn't be called since we should redirect\n\t\t\tthrow new Error(\"Should not reach here\");\n\t\t}\n\t);\n\n\t// Should redirect to fr version\n\texpect(documentResponse instanceof Response).toBe(true);\n\texpect(documentResponse.status).toBe(307);\n\texpect(documentResponse.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n\n\t// Test with Sec-Fetch-Dest = empty (should not redirect)\n\tconst apiRequest = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t// No Sec-Fetch-Dest header or set to something other than \"document\"\n\t\t\t\"Sec-Fetch-Dest\": \"empty\",\n\t\t},\n\t});\n\n\tlet apiMiddlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(apiRequest, () => {\n\t\tapiMiddlewareResolveWasCalled = true;\n\t\treturn new Response(\"API response\");\n\t});\n\n\t// Middleware should be called since no redirect for API requests\n\texpect(apiMiddlewareResolveWasCalled).toBe(true);\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/477\ntest(\"does not catch errors thrown by downstream resolve call\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\"],\n\t\tstrategy: [\"url\"],\n\t});\n\n\tawait expect(() =>\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://example.com/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\tthrow new Error(\"Downstream error\");\n\t\t\t}\n\t\t)\n\t).rejects.toThrow();\n});\n\ntest(\"middleware supports async custom server strategies\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\", \"de\"],\n\t\tstrategy: [\"custom-database\", \"baseLocale\"],\n\t});\n\n\t// Mock an async custom strategy that simulates a database call\n\tlet databaseCallCount = 0;\n\truntime.defineCustomServerStrategy(\"custom-database\", {\n\t\tgetLocale: async (request) => {\n\t\t\tdatabaseCallCount++;\n\t\t\t// Simulate async database call delay\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\n\t\t\t// Extract user ID from a custom header (simulating authentication)\n\t\t\tif (!request) return undefined;\n\t\t\tconst userId = request.headers.get(\"X-User-ID\");\n\t\t\tif (userId === \"user123\") {\n\t\t\t\treturn \"fr\";\n\t\t\t}\n\t\t\tif (userId === \"user456\") {\n\t\t\t\treturn \"de\";\n\t\t\t}\n\t\t\treturn undefined; // No user preference found\n\t\t},\n\t});\n\n\t// Test 1: Request with user preference\n\tconst requestWithUserPref = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"user123\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(requestWithUserPref, (args) => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\texpect(args.locale).toBe(\"fr\"); // Should get locale from async custom strategy\n\t\treturn new Response(\"User preference locale\");\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true);\n\texpect(databaseCallCount).toBe(1);\n\n\t// Test 2: Request with different user preference\n\tconst requestWithOtherUser = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"user456\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tawait runtime.paraglideMiddleware(requestWithOtherUser, (args) => {\n\t\texpect(args.locale).toBe(\"de\"); // Should get different locale\n\t\treturn new Response(\"Other user preference\");\n\t});\n\n\texpect(databaseCallCount).toBe(2);\n});\n\ntest(\"middleware falls back to other strategies when async custom strategy returns undefined\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\", \"de\"],\n\t\tstrategy: [\"custom-database\", \"cookie\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t});\n\n\t// Mock async custom strategy that returns undefined for unknown users\n\truntime.defineCustomServerStrategy(\"custom-database\", {\n\t\tgetLocale: async (request) => {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5));\n\t\t\tif (!request) return undefined;\n\t\t\tconst userId = request.headers.get(\"X-User-ID\");\n\t\t\t// Only return locale for known users\n\t\t\tif (userId === \"known-user\") {\n\t\t\t\treturn \"fr\";\n\t\t\t}\n\t\t\treturn undefined; // Unknown user, fallback to other strategies\n\t\t},\n\t});\n\n\t// Request from unknown user with cookie fallback\n\tconst request = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"unknown-user\",\n\t\t\tcookie: \"PARAGLIDE_LOCALE=de\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(request, (args) => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\texpect(args.locale).toBe(\"de\"); // Should fallback to cookie strategy\n\t\treturn new Response(\"Fallback locale\");\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true);\n});\n\ntest(\"middleware handles async custom strategy errors gracefully\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"custom-database\", \"baseLocale\"],\n\t});\n\n\t// Mock async custom strategy that throws an error\n\truntime.defineCustomServerStrategy(\"custom-database\", {\n\t\tgetLocale: async () => {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5));\n\t\t\tthrow new Error(\"Database connection failed\");\n\t\t},\n\t});\n\n\tconst request = new Request(\"https://example.com/page\", {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\t// The middleware should handle the error and not crash\n\tawait expect(\n\t\truntime.paraglideMiddleware(request, (args) => {\n\t\t\t// If we reach here, the error was handled and fallback worked\n\t\t\texpect(args.locale).toBe(\"en\"); // Should fallback to baseLocale\n\t\t\treturn new Response(\"Error handled\");\n\t\t})\n\t).rejects.toThrow(\"Database connection failed\");\n});\n\n// https://github.com/opral/paraglide-js/issues/573\ntest(\"falls back to original request when cloning fails (e.g., TanStack Start custom Request)\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\t// Using a strategy that doesn't include \"url\" to trigger the clone path\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t});\n\n\t// Create a custom request-like object that cannot be cloned\n\t// This simulates TanStack Start's custom Request implementation\n\tconst customRequest = {\n\t\turl: \"https://example.com/page\",\n\t\theaders: new Headers({ \"Sec-Fetch-Dest\": \"document\" }),\n\t\tmethod: \"GET\",\n\t\t// Missing other required properties that would cause `new Request(request)` to fail\n\t} as unknown as Request;\n\n\tlet middlewareResolveWasCalled = false;\n\tconst response = await runtime.paraglideMiddleware(customRequest, (args) => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\texpect(args.locale).toBe(\"en\");\n\t\t// The request should be the original custom request since cloning failed\n\t\texpect(args.request).toBe(customRequest);\n\t\treturn new Response(\"Success\");\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true);\n\texpect(await response.text()).toBe(\"Success\");\n});\n\n// https://github.com/opral/paraglide-js/issues/652\ntest(\"falls back to original request when cloning a rewritten request fails\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t});\n\n\tconst customRequest = {\n\t\turl: \"http://internal.example.com/page\",\n\t\theaders: new Headers({ \"Sec-Fetch-Dest\": \"document\" }),\n\t\tmethod: \"GET\",\n\t} as unknown as Request;\n\n\tconst NativeRequest = globalThis.Request;\n\tObject.defineProperty(globalThis, \"Request\", {\n\t\tvalue: class extends NativeRequest {\n\t\t\tconstructor(input: RequestInfo | URL, init?: RequestInit) {\n\t\t\t\tif (\n\t\t\t\t\t(typeof input === \"string\" && input === \"https://example.com/page\") ||\n\t\t\t\t\t(input instanceof URL && input.href === \"https://example.com/page\")\n\t\t\t\t) {\n\t\t\t\t\tthrow new TypeError(\"Simulated rewritten request clone failure\");\n\t\t\t\t}\n\t\t\t\tsuper(input, init);\n\t\t\t}\n\t\t},\n\t\tconfigurable: true,\n\t\twritable: true,\n\t});\n\n\ttry {\n\t\tlet middlewareResolveWasCalled = false;\n\t\tconst response = await runtime.paraglideMiddleware(\n\t\t\tcustomRequest,\n\t\t\t(args) => {\n\t\t\t\tmiddlewareResolveWasCalled = true;\n\t\t\t\texpect(args.locale).toBe(\"en\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\t\texpect(args.request).toBe(customRequest);\n\t\t\t\texpect(args.request.url).toBe(\"http://internal.example.com/page\");\n\t\t\t\treturn new Response(\"Success\");\n\t\t\t},\n\t\t\t{\n\t\t\t\teffectiveRequestUrl: \"https://example.com/page\",\n\t\t\t}\n\t\t);\n\n\t\texpect(middlewareResolveWasCalled).toBe(true);\n\t\texpect(await response.text()).toBe(\"Success\");\n\t} finally {\n\t\tObject.defineProperty(globalThis, \"Request\", {\n\t\t\tvalue: NativeRequest,\n\t\t\tconfigurable: true,\n\t\t\twritable: true,\n\t\t});\n\t}\n});\n\ntest(\"middleware works with multiple async custom strategies\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\", \"de\", \"es\"],\n\t\tstrategy: [\"custom-userPref\", \"custom-region\", \"baseLocale\"],\n\t});\n\n\tlet userPrefCallCount = 0;\n\tlet regionCallCount = 0;\n\n\t// First strategy: user preference\n\truntime.defineCustomServerStrategy(\"custom-userPref\", {\n\t\tgetLocale: async (request) => {\n\t\t\tuserPrefCallCount++;\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5));\n\t\t\tif (!request) return undefined;\n\t\t\tconst userId = request.headers.get(\"X-User-ID\");\n\t\t\treturn userId === \"premium-user\" ? \"fr\" : undefined;\n\t\t},\n\t});\n\n\t// Second strategy: region detection\n\truntime.defineCustomServerStrategy(\"custom-region\", {\n\t\tgetLocale: async (request) => {\n\t\t\tregionCallCount++;\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5));\n\t\t\tif (!request) return undefined;\n\t\t\tconst region = request.headers.get(\"X-Region\");\n\t\t\treturn region === \"europe\" ? \"de\" : undefined;\n\t\t},\n\t});\n\n\t// Test 1: First strategy succeeds\n\tconst premiumUserRequest = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"premium-user\",\n\t\t\t\"X-Region\": \"europe\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tawait runtime.paraglideMiddleware(premiumUserRequest, (args) => {\n\t\texpect(args.locale).toBe(\"fr\"); // Should use first strategy result\n\t\treturn new Response(\"Premium user\");\n\t});\n\n\texpect(userPrefCallCount).toBe(1);\n\t// Second strategy should not be called since first one succeeded\n\texpect(regionCallCount).toBe(0);\n\n\t// Test 2: First strategy fails, second succeeds\n\tconst regionalUserRequest = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"regular-user\",\n\t\t\t\"X-Region\": \"europe\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tawait runtime.paraglideMiddleware(regionalUserRequest, (args) => {\n\t\texpect(args.locale).toBe(\"de\"); // Should use second strategy result\n\t\treturn new Response(\"Regional user\");\n\t});\n\n\texpect(userPrefCallCount).toBe(2);\n\texpect(regionCallCount).toBe(1);\n});\n\ntest(\"injected script reuses the Content-Security-Policy nonce when present and omits it otherwise\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t\texperimentalMiddlewareLocaleSplitting: true,\n\t});\n\n\tconst request = new Request(new URL(\"https://example.com/page\"), {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\t// With a CSP nonce -> the injected script reuses it.\n\tconst responseWithCsp = await runtime.paraglideMiddleware(request, () => {\n\t\treturn new Response(\"<html><head></head><body></body></html>\", {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/html\",\n\t\t\t\t\"Content-Security-Policy\":\n\t\t\t\t\t\"default-src 'self'; script-src 'nonce-abc123' 'strict-dynamic'\",\n\t\t\t},\n\t\t});\n\t});\n\texpect(await responseWithCsp.text()).toContain('<script nonce=\"abc123\">');\n\n\t// Without a CSP header -> the script is still injected, without a nonce.\n\tconst responseWithoutCsp = await runtime.paraglideMiddleware(request, () => {\n\t\treturn new Response(\"<html><head></head><body></body></html>\", {\n\t\t\theaders: { \"Content-Type\": \"text/html\" },\n\t\t});\n\t});\n\tconst html = await responseWithoutCsp.text();\n\texpect(html).toContain(\"globalThis.__paraglide.ssr\");\n\texpect(html).not.toContain(\"nonce=\");\n});\n"]}
1
+ {"version":3,"file":"middleware.test.js","sourceRoot":"","sources":["../../../src/compiler/server/middleware.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"vitest\";\nimport { createParaglide } from \"../create-paraglide.js\";\n\ntest(\"sets the locale and origin\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tstrategy: [\"url\", \"globalVariable\"],\n\t});\n\n\t// setting the global variable to fr to assure that\n\truntime.setLocale(\"fr\");\n\n\t// simulating multiple requests that could interfere with each other\n\tawait Promise.all([\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://example.com/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\texpect(runtime.getLocale()).toBe(\"en\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\t\treturn new Response();\n\t\t\t}\n\t\t),\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://peter.com/de/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\texpect(runtime.getLocale()).toBe(\"de\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://peter.com\");\n\t\t\t\treturn new Response();\n\t\t\t}\n\t\t),\n\t]);\n\n\t// global variable is not impacted by middleware\n\texpect(runtime.getLocale()).toBe(\"fr\");\n});\n\ntest(\"delocalizes the url if the url strategy is used and returns the locale\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t});\n\n\tconst request = new Request(new URL(\"https://example.com/de/page\"), {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\tconst result = await runtime.paraglideMiddleware(request, (args) => {\n\t\texpect(args.locale).toBe(\"de\");\n\t\texpect(args.request.url).toBe(\"https://example.com/page\");\n\t\treturn new Response(\"Hello World\");\n\t});\n\n\texpect(await result.text()).toBe(\"Hello World\");\n});\n\ntest(\"does not delocalize the url if the url strategy is not used\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t});\n\n\tconst request = new Request(new URL(\"https://example.com/de/page\"), {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\tconst result = await runtime.paraglideMiddleware(request, (args) => {\n\t\texpect(args.locale).toBe(\"en\");\n\t\texpect(args.request.url).toBe(\"https://example.com/de/page\");\n\t\treturn new Response(\"Hello World\");\n\t});\n\n\texpect(await result.text()).toBe(\"Hello World\");\n});\n\ntest(\"skips i18n middleware behavior for excluded routeStrategies\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\trouteStrategies: [{ match: \"/api/:path(.*)?\", exclude: true }],\n\t});\n\n\tconst request = new Request(\"https://example.com/api/data\", {\n\t\theaders: {\n\t\t\tcookie: \"PARAGLIDE_LOCALE=fr\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t({ locale, request }) => new Response(`${locale}|${request.url}`)\n\t);\n\n\texpect(response.status).toBe(200);\n\texpect(await response.text()).toBe(\"en|https://example.com/api/data\");\n});\n\ntest(\"localized URLs still match routeStrategies after delocalization\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"url\", \"cookie\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\trouteStrategies: [\n\t\t\t{\n\t\t\t\tmatch: \"/dashboard/:path(.*)?\",\n\t\t\t\tstrategy: [\"cookie\", \"baseLocale\"],\n\t\t\t},\n\t\t\t{ match: \"/api/:path(.*)?\", exclude: true },\n\t\t],\n\t});\n\n\tconst dashboard = await runtime.paraglideMiddleware(\n\t\tnew Request(\"https://example.com/fr/dashboard\", {\n\t\t\theaders: { cookie: \"PARAGLIDE_LOCALE=en\" },\n\t\t}),\n\t\t({ locale }) => new Response(locale)\n\t);\n\texpect(await dashboard.text()).toBe(\"en\");\n\n\tconst api = await runtime.paraglideMiddleware(\n\t\tnew Request(\"https://example.com/fr/api/data\", {\n\t\t\theaders: { cookie: \"PARAGLIDE_LOCALE=fr\" },\n\t\t}),\n\t\t({ locale, request }) => new Response(`${locale}|${request.url}`)\n\t);\n\texpect(await api.text()).toBe(\"en|https://example.com/fr/api/data\");\n});\n\ntest(\"excluded routeStrategies keep request-scoped locale context and clone request when possible\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t\trouteStrategies: [{ match: \"/api/:path(.*)?\", exclude: true }],\n\t});\n\n\truntime.setLocale(\"fr\");\n\tconst originalRequest = new Request(\"https://example.com/api/data\", {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\toriginalRequest,\n\t\t({ locale, request }) => {\n\t\t\texpect(locale).toBe(\"en\");\n\t\t\texpect(runtime.getLocale()).toBe(\"en\");\n\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\texpect(request).not.toBe(originalRequest);\n\t\t\texpect(request.url).toBe(\"https://example.com/api/data\");\n\t\t\treturn new Response(\"ok\");\n\t\t}\n\t);\n\n\texpect(await response.text()).toBe(\"ok\");\n\texpect(runtime.getLocale()).toBe(\"fr\");\n});\n\ntest(\"excluded routeStrategies fall back to original request when cloning fails\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t\trouteStrategies: [{ match: \"/api/:path(.*)?\", exclude: true }],\n\t});\n\n\tconst customRequest = {\n\t\turl: \"https://example.com/api/data\",\n\t\theaders: new Headers({ \"Sec-Fetch-Dest\": \"document\" }),\n\t\tmethod: \"GET\",\n\t} as unknown as Request;\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\tcustomRequest,\n\t\t({ locale, request }) => {\n\t\t\texpect(locale).toBe(\"en\");\n\t\t\texpect(request).toBe(customRequest);\n\t\t\treturn new Response(\"ok\");\n\t\t}\n\t);\n\n\texpect(await response.text()).toBe(\"ok\");\n});\n\ntest(\"excluded routeStrategies preserve original request body readability\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t\trouteStrategies: [{ match: \"/api/:path(.*)?\", exclude: true }],\n\t});\n\n\tconst originalRequest = new Request(\"https://example.com/api/data\", {\n\t\tmethod: \"POST\",\n\t\tbody: \"hello=world\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\toriginalRequest,\n\t\tasync ({ request }) => {\n\t\t\texpect(await request.text()).toBe(\"hello=world\");\n\t\t\treturn new Response(\"ok\");\n\t\t}\n\t);\n\n\texpect(await response.text()).toBe(\"ok\");\n\texpect(await originalRequest.text()).toBe(\"hello=world\");\n});\n\ntest(\"routeStrategies layering is first-match-wins when exclude comes first\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\trouteStrategies: [\n\t\t\t{ match: \"/api/:path(.*)?\", exclude: true },\n\t\t\t{ match: \"/api/:path(.*)?\", strategy: [\"cookie\", \"baseLocale\"] },\n\t\t],\n\t});\n\n\tconst request = new Request(\"https://example.com/api/data\", {\n\t\theaders: {\n\t\t\tcookie: \"PARAGLIDE_LOCALE=fr\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t({ locale, request }) => new Response(`${locale}|${request.url}`)\n\t);\n\n\texpect(response.status).toBe(200);\n\texpect(await response.text()).toBe(\"en|https://example.com/api/data\");\n});\n\ntest(\"routeStrategies layering is first-match-wins when strategy comes first\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\trouteStrategies: [\n\t\t\t{ match: \"/api/:path(.*)?\", strategy: [\"cookie\", \"baseLocale\"] },\n\t\t\t{ match: \"/api/:path(.*)?\", exclude: true },\n\t\t],\n\t});\n\n\tconst request = new Request(\"https://example.com/api/data\", {\n\t\theaders: {\n\t\t\tcookie: \"PARAGLIDE_LOCALE=fr\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t({ locale, request }) => new Response(`${locale}|${request.url}`)\n\t);\n\n\texpect(response.status).toBe(200);\n\texpect(await response.text()).toBe(\"fr|https://example.com/api/data\");\n});\n\ntest(\"redirects to localized URL when non-URL strategy determines locale\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request to URL in en with cookie specifying French\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(request, () => {\n\t\t// This shouldn't be called since we should redirect\n\t\tthrow new Error(\"Should not reach here\");\n\t});\n\n\texpect(response instanceof Response).toBe(true);\n\t// needs to be 307 status code https://github.com/opral/inlang-paraglide-js/issues/416\n\texpect(response.status).toBe(307); // Redirect status code\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n});\n\ntest(\"call onRedirect callback when redirecting to new url\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request to URL in en with cookie specifying French\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tlet response: any;\n\n\tawait runtime.paraglideMiddleware(\n\t\trequest,\n\t\t() => {\n\t\t\t// This shouldn't be called since we should redirect\n\t\t\tthrow new Error(\"Should not reach here\");\n\t\t},\n\t\t{\n\t\t\tonRedirect: (res: Response) => {\n\t\t\t\tresponse = res;\n\t\t\t},\n\t\t}\n\t);\n\n\texpect(response instanceof Response).toBe(true);\n\t// needs to be 307 status code https://github.com/opral/inlang-paraglide-js/issues/416\n\texpect(response.status).toBe(307); // Redirect status code\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n});\n\ntest(\"uses the provided public url for redirects behind a proxy\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst request = new Request(\"http://internal.example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t() => {\n\t\t\tthrow new Error(\"Should not reach here\");\n\t\t},\n\t\t{\n\t\t\teffectiveRequestUrl: \"https://example.com/en/some-path\",\n\t\t}\n\t);\n\n\texpect(response.status).toBe(307);\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n});\n\ntest(\"uses the provided public url for callback request and origin\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst request = new Request(\"http://internal.example.com/fr/some-path\", {\n\t\theaders: {\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\trequest,\n\t\t({ request }) => {\n\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\treturn new Response(request.url);\n\t\t},\n\t\t{\n\t\t\teffectiveRequestUrl: \"https://example.com/fr/some-path\",\n\t\t}\n\t);\n\n\texpect(await response.text()).toBe(\"https://example.com/some-path\");\n});\n\ntest(\"sets Vary: Accept-Language header when preferredLanguage strategy is used and redirect occurs\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"preferredLanguage\", \"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request with Accept-Language header preferring French\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\t\"Accept-Language\": \"fr,en;q=0.8\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(request, () => {\n\t\t// This shouldn't be called since we should redirect\n\t\tthrow new Error(\"Should not reach here\");\n\t});\n\n\texpect(response instanceof Response).toBe(true);\n\texpect(response.status).toBe(307); // Redirect status code\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n\t// Should have Vary header when preferredLanguage strategy is used\n\texpect(response.headers.get(\"Vary\")).toBe(\"Accept-Language\");\n});\n\ntest(\"does not set Vary header when preferredLanguage strategy is not used\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request with cookie specifying French\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(request, () => {\n\t\t// This shouldn't be called since we should redirect\n\t\tthrow new Error(\"Should not reach here\");\n\t});\n\n\texpect(response instanceof Response).toBe(true);\n\texpect(response.status).toBe(307); // Redirect status code\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n\t// Should NOT have Vary header when preferredLanguage strategy is not used\n\texpect(response.headers.get(\"Vary\")).toBe(null);\n});\n\ntest(\"does not call onRedirect callback when there is no redirecting\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request to URL in en with cookie specifying French\n\tconst request = new Request(\"https://example.com/fr/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tlet response: any = null;\n\n\tawait runtime.paraglideMiddleware(\n\t\trequest,\n\t\t() => {\n\t\t\treturn new Response(\"Hello World\");\n\t\t},\n\t\t{\n\t\t\tonRedirect: (res: Response) => {\n\t\t\t\tresponse = res;\n\t\t\t},\n\t\t}\n\t);\n\n\texpect(response).toBe(null);\n});\n\ntest(\"does not redirect if URL already matches determined locale\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request to already localized URL matching cookie locale\n\tconst request = new Request(\"https://example.com/fr/some-path\", {\n\t\theaders: {\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t},\n\t});\n\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(request, () => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\treturn new Response();\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true); // Middleware should be called since no redirect needed\n});\n\ntest(\"works with disableAsyncLocalStorage option\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tstrategy: [\"url\", \"globalVariable\"],\n\t\tdisableAsyncLocalStorage: true,\n\t});\n\n\t// Set a global locale to verify it doesn't interfere with request processing\n\truntime.setLocale(\"fr\");\n\n\t// Create a request with a \"de\" locale in the URL\n\tconst request = new Request(new URL(\"https://example.com/de/page\"), {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\t// Process the request with AsyncLocalStorage disabled\n\tconst response = await runtime.paraglideMiddleware(request, (args) => {\n\t\t// Verify we still get the correct locale\n\t\texpect(args.locale).toBe(\"de\");\n\t\texpect(runtime.getLocale()).toBe(\"de\");\n\t\t// Verify URL is still properly delocalized\n\t\texpect(args.request.url).toBe(\"https://example.com/page\");\n\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\treturn new Response(\"hello\");\n\t});\n\n\t// Verify the result contains the correct data\n\texpect(await response.text()).toBe(\"hello\");\n\n\t// Verify that global variable wasn't affected by this request\n\texpect(runtime.getLocale()).toBe(\"fr\");\n});\n\ntest(\"works with sequential parallel requests using disableAsyncLocalStorage\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tstrategy: [\"url\", \"globalVariable\"],\n\t});\n\n\t// setting the global variable to fr to assure that\n\truntime.setLocale(\"fr\");\n\n\t// simulating multiple requests that could interference with each other\n\tawait Promise.all([\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://example.com/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\texpect(runtime.getLocale()).toBe(\"en\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\t\treturn new Response();\n\t\t\t}\n\t\t),\n\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://peter.com/de/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\texpect(runtime.getLocale()).toBe(\"de\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://peter.com\");\n\t\t\t\treturn new Response();\n\t\t\t}\n\t\t),\n\t]);\n\n\t// global variable is not impacted by middleware\n\texpect(runtime.getLocale()).toBe(\"fr\");\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/442\ntest(\"falls back to next strategy when cookie contains invalid locale\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Request with an invalid locale in cookie\n\tconst request = new Request(\"https://example.com/fr/some-path\", {\n\t\theaders: {\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\tcookie: `PARAGLIDE_LOCALE=invalid_locale`,\n\t\t},\n\t});\n\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(request, (args) => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\t// Should fall back to URL strategy, which will detect 'fr' from the URL\n\t\texpect(args.locale).toBe(\"fr\");\n\t\treturn new Response();\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true);\n\n\t// Try with a request that would fall back to baseLocale\n\tconst baseRequest = new Request(\"https://example.com/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=invalid_locale`,\n\t\t},\n\t});\n\n\tawait runtime.paraglideMiddleware(baseRequest, (args) => {\n\t\t// Should fall back all the way to baseLocale since URL has no locale\n\t\texpect(args.locale).toBe(\"en\");\n\t\treturn new Response();\n\t});\n});\n\n// can likely be removed once the default url pattern polyfill workaround is removed\n// because URLPattern seems to be handling this correctly\ntest(\"prevents redirect loops by normalizing URLs with trailing slashes in different scenarios\", async () => {\n\t// Create two different runtimes to test different strategy configurations\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// SCENARIO 1: Basic trailing slash normalization with cookie strategy\n\n\t// Case 1A: Request URL has trailing slash, but localized URL might not\n\tconst requestWithTrailingSlash = new Request(\"https://example.com/fr/page/\", {\n\t\theaders: {\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t},\n\t});\n\n\tlet response = await runtime.paraglideMiddleware(\n\t\trequestWithTrailingSlash,\n\t\t() => {\n\t\t\treturn new Response(\"No redirect needed\");\n\t\t}\n\t);\n\n\t// Middleware should be called (no redirect) because normalized URLs match\n\texpect(response.status).toBe(200);\n\texpect(await response.text()).toBe(\"No redirect needed\");\n\n\t// Case 1B: Request URL has no trailing slash, but localized URL might\n\tconst requestWithoutTrailingSlash = new Request(\n\t\t\"https://example.com/fr/page\",\n\t\t{\n\t\t\theaders: {\n\t\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t},\n\t\t}\n\t);\n\n\tresponse = await runtime.paraglideMiddleware(\n\t\trequestWithoutTrailingSlash,\n\t\t() => {\n\t\t\treturn new Response(\"No redirect needed\");\n\t\t}\n\t);\n\n\texpect(response.status).toBe(200);\n\n\t// Case 1C: redirect wanted because cookie is set to fr but url is en\n\tconst requestDifferentPath = new Request(\n\t\t\"https://example.com/en/different-page\",\n\t\t{\n\t\t\theaders: {\n\t\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t},\n\t\t}\n\t);\n\n\tresponse = await runtime.paraglideMiddleware(requestDifferentPath, () => {\n\t\t// This shouldn't be called since we should redirect\n\t\tthrow new Error(\"Should not reach here\");\n\t});\n\n\t// Should redirect to fr version\n\texpect(response.status).toBe(307);\n\texpect(response.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/different-page\"\n\t);\n});\n\n// https://github.com/opral/paraglide-js/issues/473\ntest(\"canonicalizes translated pathnames with the configured trailing slash policy\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\ttrailingSlash: \"never\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/about\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/about\"],\n\t\t\t\t\t[\"de\", \"/de/ueber\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst response = await runtime.paraglideMiddleware(\n\t\tnew Request(\"https://example.com/de/ueber/\", {\n\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t}),\n\t\t() => {\n\t\t\tthrow new Error(\"canonical document requests should redirect first\");\n\t\t}\n\t);\n\n\texpect(response.status).toBe(307);\n\texpect(response.headers.get(\"Location\")).toBe(\"https://example.com/de/ueber\");\n\n\tawait runtime.paraglideMiddleware(\n\t\tnew Request(\"https://example.com/de/ueber/\"),\n\t\t({ locale, request }) => {\n\t\t\texpect(locale).toBe(\"de\");\n\t\t\texpect(request.url).toBe(\"https://example.com/about\");\n\t\t\treturn new Response();\n\t\t}\n\t);\n});\n\n// not implemented because users should disable redirects by\n// making another strategy preceed the url strategy\n//\n// strategy: [\"cookie\", \"url\"]\ntest.skip(\"doesn't redirect if disableUrlRedirect is true\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Create a request that would normally be redirected\n\tconst request = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\t// Test with disableUrlRedirect = true\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(\n\t\trequest,\n\t\t() => {\n\t\t\tmiddlewareResolveWasCalled = true;\n\t\t\treturn new Response(\"No redirect\");\n\t\t}\n\t\t// { disableUrlRedirect: true }\n\t);\n\n\t// Middleware should be called since redirect is disabled\n\texpect(middlewareResolveWasCalled).toBe(true);\n});\n\ntest(\"only redirects if the request.headers.get('Sec-Fetch-Dest') === 'document'\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"cookie\", \"url\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://example.com/en/:path(.*)?\"],\n\t\t\t\t\t[\"fr\", \"https://example.com/fr/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Test with Sec-Fetch-Dest = document (should redirect)\n\tconst documentRequest = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tconst documentResponse = await runtime.paraglideMiddleware(\n\t\tdocumentRequest,\n\t\t() => {\n\t\t\t// This shouldn't be called since we should redirect\n\t\t\tthrow new Error(\"Should not reach here\");\n\t\t}\n\t);\n\n\t// Should redirect to fr version\n\texpect(documentResponse instanceof Response).toBe(true);\n\texpect(documentResponse.status).toBe(307);\n\texpect(documentResponse.headers.get(\"Location\")).toBe(\n\t\t\"https://example.com/fr/some-path\"\n\t);\n\n\t// Test with Sec-Fetch-Dest = empty (should not redirect)\n\tconst apiRequest = new Request(\"https://example.com/en/some-path\", {\n\t\theaders: {\n\t\t\tcookie: `PARAGLIDE_LOCALE=fr`,\n\t\t\t// No Sec-Fetch-Dest header or set to something other than \"document\"\n\t\t\t\"Sec-Fetch-Dest\": \"empty\",\n\t\t},\n\t});\n\n\tlet apiMiddlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(apiRequest, () => {\n\t\tapiMiddlewareResolveWasCalled = true;\n\t\treturn new Response(\"API response\");\n\t});\n\n\t// Middleware should be called since no redirect for API requests\n\texpect(apiMiddlewareResolveWasCalled).toBe(true);\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/477\ntest(\"does not catch errors thrown by downstream resolve call\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\"],\n\t\tstrategy: [\"url\"],\n\t});\n\n\tawait expect(() =>\n\t\truntime.paraglideMiddleware(\n\t\t\tnew Request(new URL(\"https://example.com/page\"), {\n\t\t\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t\t\t}),\n\t\t\t() => {\n\t\t\t\tthrow new Error(\"Downstream error\");\n\t\t\t}\n\t\t)\n\t).rejects.toThrow();\n});\n\ntest(\"middleware supports async custom server strategies\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\", \"de\"],\n\t\tstrategy: [\"custom-database\", \"baseLocale\"],\n\t});\n\n\t// Mock an async custom strategy that simulates a database call\n\tlet databaseCallCount = 0;\n\truntime.defineCustomServerStrategy(\"custom-database\", {\n\t\tgetLocale: async (request) => {\n\t\t\tdatabaseCallCount++;\n\t\t\t// Simulate async database call delay\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\n\t\t\t// Extract user ID from a custom header (simulating authentication)\n\t\t\tif (!request) return undefined;\n\t\t\tconst userId = request.headers.get(\"X-User-ID\");\n\t\t\tif (userId === \"user123\") {\n\t\t\t\treturn \"fr\";\n\t\t\t}\n\t\t\tif (userId === \"user456\") {\n\t\t\t\treturn \"de\";\n\t\t\t}\n\t\t\treturn undefined; // No user preference found\n\t\t},\n\t});\n\n\t// Test 1: Request with user preference\n\tconst requestWithUserPref = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"user123\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(requestWithUserPref, (args) => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\texpect(args.locale).toBe(\"fr\"); // Should get locale from async custom strategy\n\t\treturn new Response(\"User preference locale\");\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true);\n\texpect(databaseCallCount).toBe(1);\n\n\t// Test 2: Request with different user preference\n\tconst requestWithOtherUser = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"user456\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tawait runtime.paraglideMiddleware(requestWithOtherUser, (args) => {\n\t\texpect(args.locale).toBe(\"de\"); // Should get different locale\n\t\treturn new Response(\"Other user preference\");\n\t});\n\n\texpect(databaseCallCount).toBe(2);\n});\n\ntest(\"middleware falls back to other strategies when async custom strategy returns undefined\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\", \"de\"],\n\t\tstrategy: [\"custom-database\", \"cookie\", \"baseLocale\"],\n\t\tcookieName: \"PARAGLIDE_LOCALE\",\n\t});\n\n\t// Mock async custom strategy that returns undefined for unknown users\n\truntime.defineCustomServerStrategy(\"custom-database\", {\n\t\tgetLocale: async (request) => {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5));\n\t\t\tif (!request) return undefined;\n\t\t\tconst userId = request.headers.get(\"X-User-ID\");\n\t\t\t// Only return locale for known users\n\t\t\tif (userId === \"known-user\") {\n\t\t\t\treturn \"fr\";\n\t\t\t}\n\t\t\treturn undefined; // Unknown user, fallback to other strategies\n\t\t},\n\t});\n\n\t// Request from unknown user with cookie fallback\n\tconst request = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"unknown-user\",\n\t\t\tcookie: \"PARAGLIDE_LOCALE=de\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tlet middlewareResolveWasCalled = false;\n\tawait runtime.paraglideMiddleware(request, (args) => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\texpect(args.locale).toBe(\"de\"); // Should fallback to cookie strategy\n\t\treturn new Response(\"Fallback locale\");\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true);\n});\n\ntest(\"middleware handles async custom strategy errors gracefully\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\"],\n\t\tstrategy: [\"custom-database\", \"baseLocale\"],\n\t});\n\n\t// Mock async custom strategy that throws an error\n\truntime.defineCustomServerStrategy(\"custom-database\", {\n\t\tgetLocale: async () => {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5));\n\t\t\tthrow new Error(\"Database connection failed\");\n\t\t},\n\t});\n\n\tconst request = new Request(\"https://example.com/page\", {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\t// The middleware should handle the error and not crash\n\tawait expect(\n\t\truntime.paraglideMiddleware(request, (args) => {\n\t\t\t// If we reach here, the error was handled and fallback worked\n\t\t\texpect(args.locale).toBe(\"en\"); // Should fallback to baseLocale\n\t\t\treturn new Response(\"Error handled\");\n\t\t})\n\t).rejects.toThrow(\"Database connection failed\");\n});\n\n// https://github.com/opral/paraglide-js/issues/573\ntest(\"falls back to original request when cloning fails (e.g., TanStack Start custom Request)\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\t// Using a strategy that doesn't include \"url\" to trigger the clone path\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t});\n\n\t// Create a custom request-like object that cannot be cloned\n\t// This simulates TanStack Start's custom Request implementation\n\tconst customRequest = {\n\t\turl: \"https://example.com/page\",\n\t\theaders: new Headers({ \"Sec-Fetch-Dest\": \"document\" }),\n\t\tmethod: \"GET\",\n\t\t// Missing other required properties that would cause `new Request(request)` to fail\n\t} as unknown as Request;\n\n\tlet middlewareResolveWasCalled = false;\n\tconst response = await runtime.paraglideMiddleware(customRequest, (args) => {\n\t\tmiddlewareResolveWasCalled = true;\n\t\texpect(args.locale).toBe(\"en\");\n\t\t// The request should be the original custom request since cloning failed\n\t\texpect(args.request).toBe(customRequest);\n\t\treturn new Response(\"Success\");\n\t});\n\n\texpect(middlewareResolveWasCalled).toBe(true);\n\texpect(await response.text()).toBe(\"Success\");\n});\n\n// https://github.com/opral/paraglide-js/issues/652\ntest(\"falls back to original request when cloning a rewritten request fails\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t});\n\n\tconst customRequest = {\n\t\turl: \"http://internal.example.com/page\",\n\t\theaders: new Headers({ \"Sec-Fetch-Dest\": \"document\" }),\n\t\tmethod: \"GET\",\n\t} as unknown as Request;\n\n\tconst NativeRequest = globalThis.Request;\n\tObject.defineProperty(globalThis, \"Request\", {\n\t\tvalue: class extends NativeRequest {\n\t\t\tconstructor(input: RequestInfo | URL, init?: RequestInit) {\n\t\t\t\tif (\n\t\t\t\t\t(typeof input === \"string\" && input === \"https://example.com/page\") ||\n\t\t\t\t\t(input instanceof URL && input.href === \"https://example.com/page\")\n\t\t\t\t) {\n\t\t\t\t\tthrow new TypeError(\"Simulated rewritten request clone failure\");\n\t\t\t\t}\n\t\t\t\tsuper(input, init);\n\t\t\t}\n\t\t},\n\t\tconfigurable: true,\n\t\twritable: true,\n\t});\n\n\ttry {\n\t\tlet middlewareResolveWasCalled = false;\n\t\tconst response = await runtime.paraglideMiddleware(\n\t\t\tcustomRequest,\n\t\t\t(args) => {\n\t\t\t\tmiddlewareResolveWasCalled = true;\n\t\t\t\texpect(args.locale).toBe(\"en\");\n\t\t\t\texpect(runtime.getUrlOrigin()).toBe(\"https://example.com\");\n\t\t\t\texpect(args.request).toBe(customRequest);\n\t\t\t\texpect(args.request.url).toBe(\"http://internal.example.com/page\");\n\t\t\t\treturn new Response(\"Success\");\n\t\t\t},\n\t\t\t{\n\t\t\t\teffectiveRequestUrl: \"https://example.com/page\",\n\t\t\t}\n\t\t);\n\n\t\texpect(middlewareResolveWasCalled).toBe(true);\n\t\texpect(await response.text()).toBe(\"Success\");\n\t} finally {\n\t\tObject.defineProperty(globalThis, \"Request\", {\n\t\t\tvalue: NativeRequest,\n\t\t\tconfigurable: true,\n\t\t\twritable: true,\n\t\t});\n\t}\n});\n\ntest(\"middleware works with multiple async custom strategies\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"fr\", \"de\", \"es\"],\n\t\tstrategy: [\"custom-userPref\", \"custom-region\", \"baseLocale\"],\n\t});\n\n\tlet userPrefCallCount = 0;\n\tlet regionCallCount = 0;\n\n\t// First strategy: user preference\n\truntime.defineCustomServerStrategy(\"custom-userPref\", {\n\t\tgetLocale: async (request) => {\n\t\t\tuserPrefCallCount++;\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5));\n\t\t\tif (!request) return undefined;\n\t\t\tconst userId = request.headers.get(\"X-User-ID\");\n\t\t\treturn userId === \"premium-user\" ? \"fr\" : undefined;\n\t\t},\n\t});\n\n\t// Second strategy: region detection\n\truntime.defineCustomServerStrategy(\"custom-region\", {\n\t\tgetLocale: async (request) => {\n\t\t\tregionCallCount++;\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5));\n\t\t\tif (!request) return undefined;\n\t\t\tconst region = request.headers.get(\"X-Region\");\n\t\t\treturn region === \"europe\" ? \"de\" : undefined;\n\t\t},\n\t});\n\n\t// Test 1: First strategy succeeds\n\tconst premiumUserRequest = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"premium-user\",\n\t\t\t\"X-Region\": \"europe\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tawait runtime.paraglideMiddleware(premiumUserRequest, (args) => {\n\t\texpect(args.locale).toBe(\"fr\"); // Should use first strategy result\n\t\treturn new Response(\"Premium user\");\n\t});\n\n\texpect(userPrefCallCount).toBe(1);\n\t// Second strategy should not be called since first one succeeded\n\texpect(regionCallCount).toBe(0);\n\n\t// Test 2: First strategy fails, second succeeds\n\tconst regionalUserRequest = new Request(\"https://example.com/page\", {\n\t\theaders: {\n\t\t\t\"X-User-ID\": \"regular-user\",\n\t\t\t\"X-Region\": \"europe\",\n\t\t\t\"Sec-Fetch-Dest\": \"document\",\n\t\t},\n\t});\n\n\tawait runtime.paraglideMiddleware(regionalUserRequest, (args) => {\n\t\texpect(args.locale).toBe(\"de\"); // Should use second strategy result\n\t\treturn new Response(\"Regional user\");\n\t});\n\n\texpect(userPrefCallCount).toBe(2);\n\texpect(regionCallCount).toBe(1);\n});\n\ntest(\"injected script reuses the Content-Security-Policy nonce when present and omits it otherwise\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"globalVariable\", \"baseLocale\"],\n\t\texperimentalMiddlewareLocaleSplitting: true,\n\t});\n\n\tconst request = new Request(new URL(\"https://example.com/page\"), {\n\t\theaders: { \"Sec-Fetch-Dest\": \"document\" },\n\t});\n\n\t// With a CSP nonce -> the injected script reuses it.\n\tconst responseWithCsp = await runtime.paraglideMiddleware(request, () => {\n\t\treturn new Response(\"<html><head></head><body></body></html>\", {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/html\",\n\t\t\t\t\"Content-Security-Policy\":\n\t\t\t\t\t\"default-src 'self'; script-src 'nonce-abc123' 'strict-dynamic'\",\n\t\t\t},\n\t\t});\n\t});\n\texpect(await responseWithCsp.text()).toContain('<script nonce=\"abc123\">');\n\n\t// Without a CSP header -> the script is still injected, without a nonce.\n\tconst responseWithoutCsp = await runtime.paraglideMiddleware(request, () => {\n\t\treturn new Response(\"<html><head></head><body></body></html>\", {\n\t\t\theaders: { \"Content-Type\": \"text/html\" },\n\t\t});\n\t});\n\tconst html = await responseWithoutCsp.text();\n\texpect(html).toContain(\"globalThis.__paraglide.ssr\");\n\texpect(html).not.toContain(\"nonce=\");\n});\n"]}
@@ -1,3 +1,5 @@
1
+ import type { Declaration } from "../messages/ast.js";
1
2
  export declare function isValidIdentifier(name: string): boolean;
2
3
  export declare function quotePropertyKey(name: string): string;
3
4
  export declare function compileInputAccess(name: string): string;
5
+ export declare function compileVariableAccess(name: string, declarations?: Declaration[]): string;
@@ -12,4 +12,10 @@ export function compileInputAccess(name) {
12
12
  }
13
13
  return `i?.[${quotePropertyKey(name)}]`;
14
14
  }
15
+ export function compileVariableAccess(name, declarations) {
16
+ const declaration = declarations?.find((candidate) => candidate.name === name);
17
+ return declaration?.type === "local-variable"
18
+ ? name
19
+ : compileInputAccess(name);
20
+ }
15
21
  //# sourceMappingURL=variable-access.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"variable-access.js","sourceRoot":"","sources":["../../src/compiler/variable-access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE3E,MAAM,iBAAiB,GAAG,4BAA4B,CAAC;AAEvD,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC7C,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,OAAO,IAAI,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC9C,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,MAAM,IAAI,EAAE,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;AACzC,CAAC","sourcesContent":["import { escapeForDoubleQuoteString } from \"../services/codegen/escape.js\";\n\nconst identifierPattern = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\nexport function isValidIdentifier(name: string): boolean {\n\treturn identifierPattern.test(name);\n}\n\nexport function quotePropertyKey(name: string): string {\n\treturn `\"${escapeForDoubleQuoteString(name)}\"`;\n}\n\nexport function compileInputAccess(name: string): string {\n\tif (isValidIdentifier(name)) {\n\t\treturn `i?.${name}`;\n\t}\n\treturn `i?.[${quotePropertyKey(name)}]`;\n}\n"]}
1
+ {"version":3,"file":"variable-access.js","sourceRoot":"","sources":["../../src/compiler/variable-access.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE3E,MAAM,iBAAiB,GAAG,4BAA4B,CAAC;AAEvD,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC7C,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,OAAO,IAAI,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC9C,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,MAAM,IAAI,EAAE,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,qBAAqB,CACpC,IAAY,EACZ,YAA4B;IAE5B,MAAM,WAAW,GAAG,YAAY,EAAE,IAAI,CACrC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CACtC,CAAC;IACF,OAAO,WAAW,EAAE,IAAI,KAAK,gBAAgB;QAC5C,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import type { Declaration } from \"../messages/ast.js\";\nimport { escapeForDoubleQuoteString } from \"../services/codegen/escape.js\";\n\nconst identifierPattern = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\nexport function isValidIdentifier(name: string): boolean {\n\treturn identifierPattern.test(name);\n}\n\nexport function quotePropertyKey(name: string): string {\n\treturn `\"${escapeForDoubleQuoteString(name)}\"`;\n}\n\nexport function compileInputAccess(name: string): string {\n\tif (isValidIdentifier(name)) {\n\t\treturn `i?.${name}`;\n\t}\n\treturn `i?.[${quotePropertyKey(name)}]`;\n}\n\nexport function compileVariableAccess(\n\tname: string,\n\tdeclarations?: Declaration[]\n): string {\n\tconst declaration = declarations?.find(\n\t\t(candidate) => candidate.name === name\n\t);\n\treturn declaration?.type === \"local-variable\"\n\t\t? name\n\t\t: compileInputAccess(name);\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import { expect, test, vi } from "vitest";
2
+ vi.mock("vite", () => {
3
+ throw new Error("The package entry point eagerly imported Vite");
4
+ });
5
+ test("imports the compiler API without loading the optional Vite peer", async () => {
6
+ const { compile } = await import("./index.js");
7
+ expect(compile).toBeTypeOf("function");
8
+ });
9
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE1C,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;IAClF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAE/C,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC","sourcesContent":["import { expect, test, vi } from \"vitest\";\n\nvi.mock(\"vite\", () => {\n\tthrow new Error(\"The package entry point eagerly imported Vite\");\n});\n\ntest(\"imports the compiler API without loading the optional Vite peer\", async () => {\n\tconst { compile } = await import(\"./index.js\");\n\n\texpect(compile).toBeTypeOf(\"function\");\n});\n"]}
@@ -16,8 +16,7 @@ export async function loadMessages(options) {
16
16
  if (!settings.locales.includes(settings.baseLocale)) {
17
17
  throw new Error(`baseLocale "${settings.baseLocale}" must be one of locales: ${settings.locales.join(", ")}`);
18
18
  }
19
- const files = [];
20
- for (const locale of settings.locales) {
19
+ const files = await Promise.all(settings.locales.map(async (locale) => {
21
20
  const relativePath = options.messages.replace("{locale}", locale);
22
21
  const absolutePath = path.resolve(cwd, relativePath);
23
22
  let content;
@@ -30,12 +29,12 @@ export async function loadMessages(options) {
30
29
  }
31
30
  throw error;
32
31
  }
33
- files.push({
32
+ return {
34
33
  locale,
35
34
  content: new Uint8Array(content),
36
35
  name: relativePath,
37
- });
38
- }
36
+ };
37
+ }));
39
38
  const imported = importFiles({ files });
40
39
  const bundles = nestBundles(imported);
41
40
  return { bundles, settings };