@inlang/paraglide-js 2.26.0 → 2.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +11 -1
  2. package/dist/bundler-plugins/per-locale-build/index.js +14 -7
  3. package/dist/bundler-plugins/per-locale-build/index.js.map +1 -1
  4. package/dist/bundler-plugins/per-locale-build/vite-environments.test.js +237 -4
  5. package/dist/bundler-plugins/per-locale-build/vite-environments.test.js.map +1 -1
  6. package/dist/bundler-plugins/unplugin.d.ts +1 -1
  7. package/dist/bundler-plugins/unplugin.js +79 -10
  8. package/dist/bundler-plugins/unplugin.js.map +1 -1
  9. package/dist/bundler-plugins/unplugin.test.js +334 -1
  10. package/dist/bundler-plugins/unplugin.test.js.map +1 -1
  11. package/dist/bundler-plugins/vite.js +2 -1
  12. package/dist/bundler-plugins/vite.js.map +1 -1
  13. package/dist/bundler-plugins/vite.test.js +1 -1
  14. package/dist/bundler-plugins/vite.test.js.map +1 -1
  15. package/dist/cli/commands/compile/command.js +13 -0
  16. package/dist/cli/commands/compile/command.js.map +1 -1
  17. package/dist/cli/commands/compile/command.test.js +87 -3
  18. package/dist/cli/commands/compile/command.test.js.map +1 -1
  19. package/dist/cli/commands/init/command.d.ts +5 -0
  20. package/dist/cli/commands/init/command.js +216 -44
  21. package/dist/cli/commands/init/command.js.map +1 -1
  22. package/dist/cli/commands/init/command.test.d.ts +1 -0
  23. package/dist/cli/commands/init/command.test.js +123 -0
  24. package/dist/cli/commands/init/command.test.js.map +1 -0
  25. package/dist/cli/defaults.js +2 -2
  26. package/dist/cli/defaults.js.map +1 -1
  27. package/dist/cli/init-options.d.ts +11 -0
  28. package/dist/cli/init-options.js +2 -0
  29. package/dist/cli/init-options.js.map +1 -0
  30. package/dist/cli/steps/add-inlang-check.d.ts +19 -0
  31. package/dist/cli/steps/add-inlang-check.js +60 -0
  32. package/dist/cli/steps/add-inlang-check.js.map +1 -0
  33. package/dist/cli/steps/add-inlang-check.test.d.ts +1 -0
  34. package/dist/cli/steps/add-inlang-check.test.js +88 -0
  35. package/dist/cli/steps/add-inlang-check.test.js.map +1 -0
  36. package/dist/cli/steps/add-message-lint.d.ts +34 -0
  37. package/dist/cli/steps/add-message-lint.js +105 -0
  38. package/dist/cli/steps/add-message-lint.js.map +1 -0
  39. package/dist/cli/steps/add-message-lint.test.d.ts +1 -0
  40. package/dist/cli/steps/add-message-lint.test.js +74 -0
  41. package/dist/cli/steps/add-message-lint.test.js.map +1 -0
  42. package/dist/cli/steps/add-vite-plugin.d.ts +18 -0
  43. package/dist/cli/steps/add-vite-plugin.js +34 -6
  44. package/dist/cli/steps/add-vite-plugin.js.map +1 -1
  45. package/dist/cli/steps/add-vite-plugin.test.js +25 -9
  46. package/dist/cli/steps/add-vite-plugin.test.js.map +1 -1
  47. package/dist/cli/steps/agents-md-suggestion.d.ts +11 -0
  48. package/dist/cli/steps/agents-md-suggestion.js +19 -0
  49. package/dist/cli/steps/agents-md-suggestion.js.map +1 -0
  50. package/dist/cli/steps/agents-md-suggestion.test.d.ts +1 -0
  51. package/dist/cli/steps/agents-md-suggestion.test.js +36 -0
  52. package/dist/cli/steps/agents-md-suggestion.test.js.map +1 -0
  53. package/dist/cli/steps/check-for-uncomitted-changes.d.ts +3 -0
  54. package/dist/cli/steps/check-for-uncomitted-changes.js +15 -3
  55. package/dist/cli/steps/check-for-uncomitted-changes.js.map +1 -1
  56. package/dist/cli/steps/detect-bundler.d.ts +1 -0
  57. package/dist/cli/steps/detect-bundler.js +7 -1
  58. package/dist/cli/steps/detect-bundler.js.map +1 -1
  59. package/dist/cli/steps/initialize-inlang-project.d.ts +4 -3
  60. package/dist/cli/steps/initialize-inlang-project.js +60 -157
  61. package/dist/cli/steps/initialize-inlang-project.js.map +1 -1
  62. package/dist/cli/steps/maybe-add-machine-translation.d.ts +4 -0
  63. package/dist/cli/steps/maybe-add-machine-translation.js +14 -8
  64. package/dist/cli/steps/maybe-add-machine-translation.js.map +1 -1
  65. package/dist/cli/steps/maybe-add-sherlock.d.ts +2 -0
  66. package/dist/cli/steps/maybe-add-sherlock.js +13 -7
  67. package/dist/cli/steps/maybe-add-sherlock.js.map +1 -1
  68. package/dist/cli/steps/maybe-add-sherlock.test.d.ts +1 -0
  69. package/dist/cli/steps/maybe-add-sherlock.test.js +44 -0
  70. package/dist/cli/steps/maybe-add-sherlock.test.js.map +1 -0
  71. package/dist/cli/steps/prompt-for-outdir.d.ts +2 -0
  72. package/dist/cli/steps/prompt-for-outdir.js +4 -0
  73. package/dist/cli/steps/prompt-for-outdir.js.map +1 -1
  74. package/dist/cli/steps/update-package-json.js +8 -13
  75. package/dist/cli/steps/update-package-json.js.map +1 -1
  76. package/dist/cli/steps/update-ts-config.d.ts +6 -0
  77. package/dist/cli/steps/update-ts-config.js +27 -4
  78. package/dist/cli/steps/update-ts-config.js.map +1 -1
  79. package/dist/cli/utils.d.ts +11 -0
  80. package/dist/cli/utils.js +21 -0
  81. package/dist/cli/utils.js.map +1 -1
  82. package/dist/cli/utils.test.d.ts +1 -0
  83. package/dist/cli/utils.test.js +16 -0
  84. package/dist/cli/utils.test.js.map +1 -0
  85. package/dist/compiler/compile-annotation.d.ts +48 -1
  86. package/dist/compiler/compile-annotation.js +243 -10
  87. package/dist/compiler/compile-annotation.js.map +1 -1
  88. package/dist/compiler/compile-bundle.d.ts +7 -2
  89. package/dist/compiler/compile-bundle.js +97 -3
  90. package/dist/compiler/compile-bundle.js.map +1 -1
  91. package/dist/compiler/compile-bundle.test.js +232 -19
  92. package/dist/compiler/compile-bundle.test.js.map +1 -1
  93. package/dist/compiler/compile-lifecycle.test.d.ts +1 -0
  94. package/dist/compiler/compile-lifecycle.test.js +69 -0
  95. package/dist/compiler/compile-lifecycle.test.js.map +1 -0
  96. package/dist/compiler/compile-local-variable.d.ts +3 -0
  97. package/dist/compiler/compile-local-variable.js +5 -2
  98. package/dist/compiler/compile-local-variable.js.map +1 -1
  99. package/dist/compiler/compile-local-variable.test.js +55 -15
  100. package/dist/compiler/compile-local-variable.test.js.map +1 -1
  101. package/dist/compiler/compile-message.d.ts +29 -1
  102. package/dist/compiler/compile-message.exact-number.test.d.ts +1 -0
  103. package/dist/compiler/compile-message.exact-number.test.js +786 -0
  104. package/dist/compiler/compile-message.exact-number.test.js.map +1 -0
  105. package/dist/compiler/compile-message.js +162 -66
  106. package/dist/compiler/compile-message.js.map +1 -1
  107. package/dist/compiler/compile-message.locals.test.d.ts +1 -0
  108. package/dist/compiler/compile-message.locals.test.js +498 -0
  109. package/dist/compiler/compile-message.locals.test.js.map +1 -0
  110. package/dist/compiler/compile-message.test.js +113 -22
  111. package/dist/compiler/compile-message.test.js.map +1 -1
  112. package/dist/compiler/compile-pattern.d.ts +5 -0
  113. package/dist/compiler/compile-pattern.js +6 -18
  114. package/dist/compiler/compile-pattern.js.map +1 -1
  115. package/dist/compiler/compile-pattern.test.js +169 -5
  116. package/dist/compiler/compile-pattern.test.js.map +1 -1
  117. package/dist/compiler/compile-project.js +5 -1
  118. package/dist/compiler/compile-project.js.map +1 -1
  119. package/dist/compiler/compile-project.test.js +1260 -185
  120. package/dist/compiler/compile-project.test.js.map +1 -1
  121. package/dist/compiler/compile.js +36 -17
  122. package/dist/compiler/compile.js.map +1 -1
  123. package/dist/compiler/compile.test.js +71 -1
  124. package/dist/compiler/compile.test.js.map +1 -1
  125. package/dist/compiler/compiler-options.d.ts +41 -0
  126. package/dist/compiler/compiler-options.js.map +1 -1
  127. package/dist/compiler/create-readme.d.ts +4 -1
  128. package/dist/compiler/create-readme.js +33 -125
  129. package/dist/compiler/create-readme.js.map +1 -1
  130. package/dist/compiler/emit-ts-declarations.interop.test.js +2 -2
  131. package/dist/compiler/emit-ts-declarations.interop.test.js.map +1 -1
  132. package/dist/compiler/emit-ts-declarations.test.js +4 -4
  133. package/dist/compiler/emit-ts-declarations.test.js.map +1 -1
  134. package/dist/compiler/index.d.ts +1 -1
  135. package/dist/compiler/index.js +1 -1
  136. package/dist/compiler/index.js.map +1 -1
  137. package/dist/compiler/input-alias.d.ts +21 -0
  138. package/dist/compiler/input-alias.js +42 -0
  139. package/dist/compiler/input-alias.js.map +1 -0
  140. package/dist/compiler/input-alias.test.d.ts +1 -0
  141. package/dist/compiler/input-alias.test.js +58 -0
  142. package/dist/compiler/input-alias.test.js.map +1 -0
  143. package/dist/compiler/message-locals.d.ts +46 -0
  144. package/dist/compiler/message-locals.js +129 -0
  145. package/dist/compiler/message-locals.js.map +1 -0
  146. package/dist/compiler/output-structure/locale-modules.js +7 -1
  147. package/dist/compiler/output-structure/locale-modules.js.map +1 -1
  148. package/dist/compiler/output-structure/locale-modules.test.js +35 -0
  149. package/dist/compiler/output-structure/locale-modules.test.js.map +1 -1
  150. package/dist/compiler/output-structure/message-modules.js +6 -4
  151. package/dist/compiler/output-structure/message-modules.js.map +1 -1
  152. package/dist/compiler/output-structure/message-modules.test.js +35 -0
  153. package/dist/compiler/output-structure/message-modules.test.js.map +1 -1
  154. package/dist/compiler/registry.d.ts +12 -0
  155. package/dist/compiler/registry.js +158 -31
  156. package/dist/compiler/registry.js.map +1 -1
  157. package/dist/compiler/registry.test.d.ts +1 -0
  158. package/dist/compiler/registry.test.js +291 -0
  159. package/dist/compiler/registry.test.js.map +1 -0
  160. package/dist/compiler/runtime/create-runtime.d.ts +2 -0
  161. package/dist/compiler/runtime/create-runtime.js +9 -0
  162. package/dist/compiler/runtime/create-runtime.js.map +1 -1
  163. package/dist/compiler/runtime/extract-locale-from-cookie.js +8 -1
  164. package/dist/compiler/runtime/extract-locale-from-cookie.js.map +1 -1
  165. package/dist/compiler/runtime/extract-locale-from-cookie.test.js +26 -0
  166. package/dist/compiler/runtime/extract-locale-from-cookie.test.js.map +1 -1
  167. package/dist/compiler/runtime/extract-locale-from-header.js +47 -5
  168. package/dist/compiler/runtime/extract-locale-from-header.js.map +1 -1
  169. package/dist/compiler/runtime/extract-locale-from-header.test.js +58 -0
  170. package/dist/compiler/runtime/extract-locale-from-header.test.js.map +1 -1
  171. package/dist/compiler/runtime/get-locale.js +7 -1
  172. package/dist/compiler/runtime/get-locale.js.map +1 -1
  173. package/dist/compiler/runtime/get-locale.test.js +95 -0
  174. package/dist/compiler/runtime/get-locale.test.js.map +1 -1
  175. package/dist/compiler/runtime/localize-href.d.ts +8 -0
  176. package/dist/compiler/runtime/localize-href.js +60 -0
  177. package/dist/compiler/runtime/localize-href.js.map +1 -1
  178. package/dist/compiler/runtime/localize-href.test.js +227 -1
  179. package/dist/compiler/runtime/localize-href.test.js.map +1 -1
  180. package/dist/compiler/runtime/set-locale.js +24 -6
  181. package/dist/compiler/runtime/set-locale.js.map +1 -1
  182. package/dist/compiler/runtime/set-locale.test.js +182 -0
  183. package/dist/compiler/runtime/set-locale.test.js.map +1 -1
  184. package/dist/compiler/runtime/type.d.ts +2 -0
  185. package/dist/compiler/runtime/type.js.map +1 -1
  186. package/dist/compiler/runtime/type.test.js +34 -0
  187. package/dist/compiler/runtime/type.test.js.map +1 -1
  188. package/dist/compiler/runtime/variables.d.ts +2 -0
  189. package/dist/compiler/runtime/variables.js +7 -0
  190. package/dist/compiler/runtime/variables.js.map +1 -1
  191. package/dist/compiler/server/create-server-file.js +24 -0
  192. package/dist/compiler/server/create-server-file.js.map +1 -1
  193. package/dist/compiler/server/create-server-file.test.js +8 -2
  194. package/dist/compiler/server/create-server-file.test.js.map +1 -1
  195. package/dist/compiler/server/middleware.d.ts +8 -2
  196. package/dist/compiler/server/middleware.js +204 -11
  197. package/dist/compiler/server/middleware.js.map +1 -1
  198. package/dist/compiler/server/middleware.test.js +750 -3
  199. package/dist/compiler/server/middleware.test.js.map +1 -1
  200. package/dist/eslint/index.d.ts +4 -0
  201. package/dist/eslint/index.js +8 -0
  202. package/dist/eslint/index.js.map +1 -0
  203. package/dist/eslint/no-dynamic-message-access.d.ts +3 -0
  204. package/dist/eslint/no-dynamic-message-access.js +150 -0
  205. package/dist/eslint/no-dynamic-message-access.js.map +1 -0
  206. package/dist/eslint/no-dynamic-message-access.test.d.ts +1 -0
  207. package/dist/eslint/no-dynamic-message-access.test.js +126 -0
  208. package/dist/eslint/no-dynamic-message-access.test.js.map +1 -0
  209. package/dist/eslint/oxlint.test.d.ts +1 -0
  210. package/dist/eslint/oxlint.test.js +64 -0
  211. package/dist/eslint/oxlint.test.js.map +1 -0
  212. package/dist/services/config/config-schema.d.ts +2 -0
  213. package/dist/services/config/config-schema.js +2 -0
  214. package/dist/services/config/config-schema.js.map +1 -1
  215. package/dist/services/config/load-paraglide-config.test.js +12 -0
  216. package/dist/services/config/load-paraglide-config.test.js.map +1 -1
  217. package/dist/services/env-variables/index.js +1 -1
  218. package/dist/services/env-variables/index.js.map +1 -1
  219. package/dist/services/file-handling/write-output.bench.js +51 -11
  220. package/dist/services/file-handling/write-output.bench.js.map +1 -1
  221. package/dist/services/file-handling/write-output.js +60 -20
  222. package/dist/services/file-handling/write-output.js.map +1 -1
  223. package/dist/services/file-handling/write-output.test.js +175 -0
  224. package/dist/services/file-handling/write-output.test.js.map +1 -1
  225. package/package.json +15 -5
@@ -1 +1 @@
1
- {"version":3,"file":"localize-href.test.js","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-href.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"vitest\";\nimport { createParaglide } from \"../create-paraglide.js\";\nimport { newProject } from \"@inlang/sdk\";\n\ntest(\"uses the locale from getLocale() if no locale is provided\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\", \"globalVariable\", \"baseLocale\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"http://:domain(.*)/:locale(de|en)?/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\truntime.overwriteGetLocale(() => \"de\");\n\n\texpect(runtime.localizeHref(\"/hello\")).toBe(\"/de/hello\");\n\texpect(runtime.deLocalizeHref(\"/de/hello\")).toBe(\"/hello\");\n});\n\ntest(\"returns an absolute href if the provided href is absolute\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\", \"globalVariable\", \"baseLocale\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"http://:domain(.*)/:locale(de|en)?/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeHref(\"http://example.com/hello\", { locale: \"de\" })\n\t).toBe(\"http://example.com/de/hello\");\n\texpect(runtime.deLocalizeHref(\"http://example.com/de/hello\")).toBe(\n\t\t\"http://example.com/hello\"\n\t);\n});\n\n// useful if domain based localization is used for example\ntest(\"returns an absolute href if the provided href is relative but the origin of the localized href differs\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\", \"globalVariable\", \"baseLocale\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"http://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://de.example.com/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://example.com/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// simulating routing from current en page to de page\n\truntime.overwriteGetLocale(() => \"en\");\n\truntime.overwriteGetUrlOrigin(() => \"http://example.com\");\n\n\texpect(runtime.localizeHref(\"/hello\", { locale: \"de\" })).toBe(\n\t\t\"http://de.example.com/hello\"\n\t);\n\texpect(runtime.deLocalizeHref(\"http://de.example.com/hello\")).toBe(\n\t\t\"http://example.com/hello\"\n\t);\n\n\t// simulating routing from current de page to en page\n\truntime.overwriteGetLocale(() => \"de\");\n\n\texpect(runtime.localizeHref(\"/hello\", { locale: \"en\" })).toBe(\n\t\t\"http://example.com/hello\"\n\t);\n\texpect(runtime.deLocalizeHref(\"http://example.com/hello\")).toBe(\n\t\t\"http://example.com/hello\"\n\t);\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/362\ntest(\"adding a base path\", async () => {\n\tconst base = \"shop\";\n\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: `/{${base}/}?:path(.*)?`,\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", `/{${base}/}?de/:path(.*)?`],\n\t\t\t\t\t[\"en\", `/{${base}/}?:path(.*)?`],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// simulating the current locale to be en\n\truntime.overwriteGetLocale(() => \"en\");\n\n\texpect(runtime.localizeHref(\"/about\")).toBe(\"/shop/about\");\n\texpect(runtime.deLocalizeHref(\"/about\")).toBe(\"/shop/about\");\n\n\t// simulating current locale to be de\n\truntime.overwriteGetLocale(() => \"de\");\n\texpect(runtime.localizeHref(\"/about\")).toBe(\"/shop/de/about\");\n\texpect(runtime.deLocalizeHref(\"/de/about\")).toBe(\"/shop/about\");\n});\n\ntest(\"default url patterns to improve out of the box experience\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\t\t},\n\t\t}),\n\t\tisServer: \"false\",\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: undefined,\n\t});\n\n\t// polyfilling window\n\tglobalThis.window = { location: new URL(\"http://example.com\") } as any;\n\n\texpect(runtime.urlPatterns).toStrictEqual([\n\t\t{\n\t\t\tpattern: \":protocol://:domain(.*)::port?/:path(.*)?\",\n\t\t\tlocalized: [\n\t\t\t\t[\"de\", \":protocol://:domain(.*)::port?/de/:path(.*)?\"],\n\t\t\t\t[\"fr\", \":protocol://:domain(.*)::port?/fr/:path(.*)?\"],\n\t\t\t\t[\"en\", \":protocol://:domain(.*)::port?/:path(.*)?\"],\n\t\t\t],\n\t\t},\n\t]);\n\n\t// expecting the baseLocale to not be included in the url\n\texpect(runtime.localizeHref(\"/about\", { locale: \"en\" })).toBe(\"/about\");\n\texpect(runtime.localizeHref(\"/about\", { locale: \"de\" })).toBe(\"/de/about\");\n\n\t// expecting root path to work\n\texpect(runtime.localizeHref(\"/\", { locale: \"en\" })).toBe(\"/\");\n\texpect(runtime.localizeHref(\"/\", { locale: \"de\" })).toBe(\"/de/\");\n\n\t// expecting de-localization to work\n\texpect(runtime.deLocalizeHref(\"/de/\")).toBe(\"/\");\n\texpect(runtime.deLocalizeHref(\"/de/about\")).toBe(\"/about\");\n\texpect(runtime.deLocalizeHref(\"/about\")).toBe(\"/about\");\n\n\t// expecting localhost to work (for development)\n\texpect(runtime.localizeHref(\"http://localhost:5173/\", { locale: \"de\" })).toBe(\n\t\t\"http://localhost:5173/de/\"\n\t);\n\n\t// de-localizing localhost\n\texpect(runtime.deLocalizeHref(\"http://localhost:5173/de\")).toBe(\n\t\t\"http://localhost:5173/\"\n\t);\n\n\t// pathnames\n\texpect(\n\t\truntime.localizeHref(\"http://localhost:5173/about\", { locale: \"de\" })\n\t).toBe(\"http://localhost:5173/de/about\");\n\n\texpect(runtime.deLocalizeHref(\"http://localhost:5173/de/about\")).toBe(\n\t\t\"http://localhost:5173/about\"\n\t);\n});\n\ntest(\"normalizes localized root hrefs and anchors\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tisServer: \"false\",\n\t\tstrategy: [\"url\"],\n\t\ttrailingSlash: \"never\",\n\t});\n\n\tglobalThis.window = { location: new URL(\"http://example.com\") } as any;\n\n\texpect(runtime.localizeHref(\"/\", { locale: \"de\" })).toBe(\"/de\");\n\texpect(runtime.localizeHref(\"/#section\", { locale: \"de\" })).toBe(\n\t\t\"/de#section\"\n\t);\n\texpect(runtime.deLocalizeHref(\"/de/\")).toBe(\"/\");\n});\n\ntest(\"normalizes mixed-case explicit locales in localizeHref\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\"],\n\t});\n\n\texpect(runtime.localizeHref(\"/about\", { locale: \"DE\" })).toBe(\"/de/about\");\n\n\texpect(runtime.localizeHref(\"/de/about\", { locale: \"EN\" })).toBe(\"/about\");\n});\n\ntest(\"keeps custom URLPattern path expressions on the generic fallback\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:slug(.)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/:slug(.)?\"],\n\t\t\t\t\t[\"de\", \"/de/:slug(.)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\truntime.overwriteGetLocale(() => \"en\");\n\truntime.overwriteGetUrlOrigin(() => \"https://example.com\");\n\n\t// `(.)` matches exactly one character in URLPattern. A prefix-only\n\t// implementation must not broaden this route into a catch-all.\n\texpect(runtime.localizeHref(\"/a\", { locale: \"de\" })).toBe(\"/de/a\");\n\texpect(runtime.localizeHref(\"/about\", { locale: \"de\" })).toBe(\"/about\");\n});\n\ntest.each([undefined, \"always\", \"never\"] as const)(\n\t\"default hrefs preserve slashes unless trailingSlash is %s\",\n\tasync (trailingSlash) => {\n\t\tconst runtime = await createParaglide({\n\t\t\tblob: await newProject({\n\t\t\t\tsettings: { baseLocale: \"de\", locales: [\"de\", \"en\"] },\n\t\t\t}),\n\t\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\t\ttrailingSlash,\n\t\t});\n\t\tconst paths = [\"/\", \"/about/\", \"/contact/\"];\n\t\tconst suffix = trailingSlash === \"never\" ? \"\" : \"/\";\n\t\texpect(\n\t\t\tpaths.flatMap((path) =>\n\t\t\t\truntime.locales.map((locale) => runtime.localizeHref(path, { locale }))\n\t\t\t)\n\t\t).toEqual([\n\t\t\t\"/\",\n\t\t\t\"/en\" + suffix,\n\t\t\t\"/about\" + suffix,\n\t\t\t\"/en/about\" + suffix,\n\t\t\t\"/contact\" + suffix,\n\t\t\t\"/en/contact\" + suffix,\n\t\t]);\n\t\texpect(runtime.localizeHref(\"/about\", { locale: \"en\" })).toBe(\n\t\t\t\"/en/about\" + (trailingSlash === \"always\" ? \"/\" : \"\")\n\t\t);\n\t\texpect(runtime.deLocalizeHref(\"/en/about/?q=test#section\")).toBe(\n\t\t\t\"/about\" + suffix + \"?q=test#section\"\n\t\t);\n\t\texpect(\n\t\t\truntime.localizeHref(\"/en/about/?q=test#section\", { locale: \"de\" })\n\t\t).toBe(\"/about\" + suffix + \"?q=test#section\");\n\t}\n);\n\ntest(\"default routes remove detected locales after repeated leading separators\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\", \"fr\"] },\n\t\t}),\n\t\tstrategy: [\"url\", \"baseLocale\"],\n\t});\n\tfor (const suffix of [\"\", \"/\"]) {\n\t\tconst input = `https://example.com//de/about${suffix}?q=test#section`;\n\t\texpect(runtime.extractLocaleFromUrl(input)).toBe(\"de\");\n\t\texpect(runtime.localizeUrl(input, { locale: \"en\" }).href).toBe(\n\t\t\t`https://example.com/about${suffix}?q=test#section`\n\t\t);\n\t\texpect(runtime.localizeUrl(input, { locale: \"fr\" }).href).toBe(\n\t\t\t`https://example.com/fr/about${suffix}?q=test#section`\n\t\t);\n\t\texpect(runtime.deLocalizeUrl(input).href).toBe(\n\t\t\t`https://example.com/about${suffix}?q=test#section`\n\t\t);\n\t}\n});\n"]}
1
+ {"version":3,"file":"localize-href.test.js","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-href.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect, vi } from \"vitest\";\nimport { createParaglide } from \"../create-paraglide.js\";\nimport { newProject } from \"@inlang/sdk\";\n\ntest(\"uses the locale from getLocale() if no locale is provided\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\", \"globalVariable\", \"baseLocale\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"http://:domain(.*)/:locale(de|en)?/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\truntime.overwriteGetLocale(() => \"de\");\n\n\texpect(runtime.localizeHref(\"/hello\")).toBe(\"/de/hello\");\n\texpect(runtime.deLocalizeHref(\"/de/hello\")).toBe(\"/hello\");\n});\n\ntest(\"returns an absolute href if the provided href is absolute\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\", \"globalVariable\", \"baseLocale\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"http://:domain(.*)/:locale(de|en)?/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeHref(\"http://example.com/hello\", { locale: \"de\" })\n\t).toBe(\"http://example.com/de/hello\");\n\texpect(runtime.deLocalizeHref(\"http://example.com/de/hello\")).toBe(\n\t\t\"http://example.com/hello\"\n\t);\n});\n\ntest(\"localizeHref preserves protocol-relative authorities\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\"] },\n\t\t}),\n\t\tstrategy: [\"url\", \"baseLocale\"],\n\t});\n\truntime.overwriteGetLocale(() => \"en\");\n\n\tfor (const protocol of [\"http\", \"https\"]) {\n\t\truntime.overwriteGetUrlOrigin(() => `${protocol}://app.example.com`);\n\t\tfor (const prefix of [\"//\", \"/\\\\\", \"\\\\\\\\\", \"\\\\/\", \"///\", \"/\\\\/\"]) {\n\t\t\tfor (const authority of [\n\t\t\t\t\"cdn.example.com:8443\",\n\t\t\t\t\"cdn.example.com:80\",\n\t\t\t\t\"cdn.example.com:443\",\n\t\t\t\t\"app.example.com\",\n\t\t\t\t\"user:p%40ss@app.example.com\",\n\t\t\t]) {\n\t\t\t\texpect(\n\t\t\t\t\truntime.localizeHref(`${prefix}${authority}/hello?q=1#section`, {\n\t\t\t\t\t\tlocale: \"de\",\n\t\t\t\t\t})\n\t\t\t\t).toBe(`//${authority}/de/hello?q=1#section`);\n\t\t\t}\n\t\t}\n\t}\n\texpect(runtime.localizeHref(\"/hello?q=1#section\", { locale: \"de\" })).toBe(\n\t\t\"/de/hello?q=1#section\"\n\t);\n});\n\ntest(\"deLocalizeHref preserves protocol-relative authorities\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\"] },\n\t\t}),\n\t\tstrategy: [\"url\", \"baseLocale\"],\n\t});\n\n\tfor (const protocol of [\"http\", \"https\"]) {\n\t\truntime.overwriteGetUrlOrigin(() => `${protocol}://app.example.com`);\n\t\tfor (const prefix of [\"//\", \"/\\\\\", \"\\\\\\\\\", \"\\\\/\", \"///\", \"/\\\\/\"]) {\n\t\t\tfor (const authority of [\n\t\t\t\t\"cdn.example.com:8443\",\n\t\t\t\t\"cdn.example.com:80\",\n\t\t\t\t\"cdn.example.com:443\",\n\t\t\t\t\"app.example.com\",\n\t\t\t\t\"user:p%40ss@app.example.com\",\n\t\t\t]) {\n\t\t\t\texpect(\n\t\t\t\t\truntime.deLocalizeHref(`${prefix}${authority}/de/hello?q=1#section`)\n\t\t\t\t).toBe(`//${authority}/hello?q=1#section`);\n\t\t\t}\n\t\t}\n\t}\n\texpect(runtime.deLocalizeHref(\"/de/hello?q=1#section\")).toBe(\n\t\t\"/hello?q=1#section\"\n\t);\n});\n\ntest(\"classifies protocol-relative hrefs after URL whitespace normalization\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\"] },\n\t\t}),\n\t\tstrategy: [\"url\", \"baseLocale\"],\n\t});\n\truntime.overwriteGetLocale(() => \"en\");\n\truntime.overwriteGetUrlOrigin(() => \"https://app.example.com\");\n\n\tfor (const prefix of [\n\t\t\"/\\t/\",\n\t\t\"/\\n/\",\n\t\t\"/\\r\\\\\",\n\t\t\"/\\t\\\\\",\n\t\t\" \\t//\",\n\t\t\"\\u0000//\",\n\t]) {\n\t\texpect({\n\t\t\tlocalized: runtime.localizeHref(`${prefix}cdn.example.com/hello`, {\n\t\t\t\tlocale: \"de\",\n\t\t\t}),\n\t\t\tdeLocalized: runtime.deLocalizeHref(`${prefix}cdn.example.com/de/hello`),\n\t\t}).toEqual({\n\t\t\tlocalized: \"//cdn.example.com/de/hello\",\n\t\t\tdeLocalized: \"//cdn.example.com/hello\",\n\t\t});\n\t}\n\texpect(\n\t\truntime.localizeHref(\"/%2Fcdn.example.com/hello\", { locale: \"de\" })\n\t).toBe(\"/de/%2Fcdn.example.com/hello\");\n\texpect(runtime.deLocalizeHref(\"/de/%2Fcdn.example.com/hello\")).toBe(\n\t\t\"/%2Fcdn.example.com/hello\"\n\t);\n\truntime.overwriteGetUrlOrigin(() => \"custom://app.example.com\");\n\texpect(runtime.localizeHref(\"/\\\\hello\", { locale: \"de\" })).toBe(\n\t\t\"/de/\\\\hello\"\n\t);\n\texpect(runtime.deLocalizeHref(\"/de/\\\\hello\")).toBe(\"/\\\\hello\");\n});\n\ntest.each([\"localizeHref\", \"deLocalizeHref\"] as const)(\n\t\"%s does not interpret file path segments as ports\",\n\tasync (helper) => {\n\t\tconst runtime = await createParaglide({\n\t\t\tblob: await newProject({\n\t\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\"] },\n\t\t\t}),\n\t\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\t});\n\t\truntime.overwriteGetLocale(() => \"en\");\n\t\truntime.overwriteGetUrlOrigin(() => \"file:///app/\");\n\n\t\tfor (const [prefix, expectedPrefix] of [\n\t\t\t[\"///\", \"///\"],\n\t\t\t[\"/\\\\/\", \"///\"],\n\t\t\t[\"//localhost/\", \"///\"],\n\t\t\t[\"//server/\", \"//server/\"],\n\t\t]) {\n\t\t\tconst href = `${prefix}docs:80/page?q=1#part`;\n\t\t\tconst result =\n\t\t\t\thelper === \"localizeHref\"\n\t\t\t\t\t? runtime.localizeHref(href, { locale: \"de\" })\n\t\t\t\t\t: runtime.deLocalizeHref(href);\n\t\t\tconst expected = `${expectedPrefix}${helper === \"localizeHref\" ? \"de/\" : \"\"}docs:80/page?q=1#part`;\n\t\t\texpect(result).toBe(expected);\n\t\t\texpect(new URL(result, \"file:///app/\").href).toBe(`file:${expected}`);\n\t\t}\n\t}\n);\n\ntest(\"protocol-relative hrefs do not inherit the server fallback protocol\", async () => {\n\tvi.stubGlobal(\"window\", undefined);\n\ttry {\n\t\tconst runtime = await createParaglide({\n\t\t\tblob: await newProject({\n\t\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\"] },\n\t\t\t}),\n\t\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\t\t// A distinct option gives these fallback tests a runtime whose origin\n\t\t\t// was not overwritten.\n\t\t\tisServer: \"true\",\n\t\t});\n\t\truntime.overwriteGetLocale(() => \"en\");\n\t\texpect(runtime.getUrlOrigin()).toBe(\"http://fallback.com\");\n\n\t\tfor (const prefix of [\"//\", \"/\\\\\"]) {\n\t\t\tconst localized = runtime.localizeHref(`${prefix}cdn.example.com/hello`, {\n\t\t\t\tlocale: \"de\",\n\t\t\t});\n\t\t\tconst deLocalized = runtime.deLocalizeHref(\n\t\t\t\t`${prefix}cdn.example.com/de/hello`\n\t\t\t);\n\t\t\texpect({ localized, deLocalized }).toEqual({\n\t\t\t\tlocalized: \"//cdn.example.com/de/hello\",\n\t\t\t\tdeLocalized: \"//cdn.example.com/hello\",\n\t\t\t});\n\t\t\texpect(new URL(localized, \"https://app.example.com\").href).toBe(\n\t\t\t\t\"https://cdn.example.com/de/hello\"\n\t\t\t);\n\t\t\texpect(new URL(deLocalized, \"https://app.example.com\").href).toBe(\n\t\t\t\t\"https://cdn.example.com/hello\"\n\t\t\t);\n\t\t}\n\t} finally {\n\t\tvi.unstubAllGlobals();\n\t}\n});\n\ntest.each([\"localizeHref\", \"deLocalizeHref\"] as const)(\n\t\"%s preserves explicit default ports on the server\",\n\tasync (helper) => {\n\t\tconst runtime = await createParaglide({\n\t\t\tblob: await newProject({\n\t\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\"] },\n\t\t\t}),\n\t\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\t\tisServer: \"true\",\n\t\t});\n\t\truntime.overwriteGetLocale(() => \"en\");\n\t\texpect(runtime.getUrlOrigin()).toBe(\"http://fallback.com\");\n\n\t\tfor (const prefix of [\"//\", \"/\\\\\", \"/\\t/\"]) {\n\t\t\tfor (const authority of [\n\t\t\t\t\"cdn.example.com:80\",\n\t\t\t\t\"cdn.example.com:00080\",\n\t\t\t\t\"user:p%40ss@cdn.example.com:80\",\n\t\t\t\t\"[::1]:80\",\n\t\t\t\t\"user:p%40ss@[::1]:80\",\n\t\t\t]) {\n\t\t\t\tconst input = `${prefix}${authority}${helper === \"localizeHref\" ? \"/docs\" : \"/de/docs\"}?q=1#part`;\n\t\t\t\tconst output =\n\t\t\t\t\thelper === \"localizeHref\"\n\t\t\t\t\t\t? runtime.localizeHref(input, { locale: \"de\" })\n\t\t\t\t\t\t: runtime.deLocalizeHref(input);\n\t\t\t\tconst resolved = new URL(output, \"https://app.example.com\");\n\t\t\t\texpect(resolved.port).toBe(\"80\");\n\t\t\t\texpect(resolved.href).toBe(\n\t\t\t\t\tnew URL(\n\t\t\t\t\t\t`https://${authority}${helper === \"localizeHref\" ? \"/de/docs\" : \"/docs\"}?q=1#part`\n\t\t\t\t\t).href\n\t\t\t\t);\n\t\t\t\texpect(output.startsWith(\"//\")).toBe(true);\n\t\t\t}\n\t\t}\n\t}\n);\n\ntest.each([\n\t[\"80\", \"8080\"],\n\t[\"8080\", \"80\"],\n])(\n\t\"configured port changes from %s to %s take precedence\",\n\tasync (basePort, localizedPort) => {\n\t\tconst runtime = await createParaglide({\n\t\t\tblob: await newProject({\n\t\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\"] },\n\t\t\t}),\n\t\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\t\turlPatterns: [\n\t\t\t\t{\n\t\t\t\t\tpattern: `http://example.com:${basePort}/:path(.*)?`,\n\t\t\t\t\tlocalized: [\n\t\t\t\t\t\t[\"en\", `http://example.com:${basePort}/:path(.*)?`],\n\t\t\t\t\t\t[\"de\", `http://de.example.com:${localizedPort}/:path(.*)?`],\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\t\truntime.overwriteGetLocale(() => \"en\");\n\t\truntime.overwriteGetUrlOrigin(() => \"http://app.example.com\");\n\n\t\tfor (const prefix of [\"//\", \"/\\\\\", \"/\\n/\"]) {\n\t\t\texpect(\n\t\t\t\truntime.localizeHref(`${prefix}example.com:${basePort}/docs?q=1#part`, {\n\t\t\t\t\tlocale: \"de\",\n\t\t\t\t})\n\t\t\t).toBe(\n\t\t\t\tnew URL(`http://de.example.com:${localizedPort}/docs?q=1#part`).href\n\t\t\t);\n\t\t\texpect(\n\t\t\t\truntime.deLocalizeHref(\n\t\t\t\t\t`${prefix}de.example.com:${localizedPort}/docs?q=1#part`\n\t\t\t\t)\n\t\t\t).toBe(new URL(`http://example.com:${basePort}/docs?q=1#part`).href);\n\t\t}\n\t}\n);\n\ntest.each([\"http\", \"https\"])(\n\t\"protocol-relative hrefs respect domain localization between http and %s\",\n\tasync (protocol) => {\n\t\tconst runtime = await createParaglide({\n\t\t\tblob: await newProject({\n\t\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\"] },\n\t\t\t}),\n\t\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\t\turlPatterns: [\n\t\t\t\t{\n\t\t\t\t\tpattern: \"http://example.com/:path(.*)?\",\n\t\t\t\t\tlocalized: [\n\t\t\t\t\t\t[\"en\", \"http://example.com/:path(.*)?\"],\n\t\t\t\t\t\t[\"de\", `${protocol}://de.example.com/:path(.*)?`],\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\t\truntime.overwriteGetLocale(() => \"en\");\n\n\t\tfor (const prefix of [\"//\", \"/\\\\\", \"/\\t/\"]) {\n\t\t\truntime.overwriteGetUrlOrigin(() => \"http://app.example.com\");\n\t\t\texpect(\n\t\t\t\truntime.localizeHref(`${prefix}example.com/hello?q=1#section`, {\n\t\t\t\t\tlocale: \"de\",\n\t\t\t\t})\n\t\t\t).toBe(\n\t\t\t\t`${protocol === \"http\" ? \"\" : \"https:\"}//de.example.com/hello?q=1#section`\n\t\t\t);\n\t\t\texpect(\n\t\t\t\truntime.localizeHref(`${prefix}example.com:80/hello`, { locale: \"de\" })\n\t\t\t).toBe(\n\t\t\t\tprotocol === \"http\"\n\t\t\t\t\t? \"//de.example.com:80/hello\"\n\t\t\t\t\t: \"https://de.example.com/hello\"\n\t\t\t);\n\t\t\truntime.overwriteGetUrlOrigin(() => `${protocol}://app.example.com`);\n\t\t\texpect(\n\t\t\t\truntime.deLocalizeHref(`${prefix}de.example.com/hello?q=1#section`)\n\t\t\t).toBe(\n\t\t\t\t`${protocol === \"http\" ? \"\" : \"http:\"}//example.com/hello?q=1#section`\n\t\t\t);\n\t\t\texpect(\n\t\t\t\truntime.deLocalizeHref(\n\t\t\t\t\t`${prefix}de.example.com:${protocol === \"http\" ? \"80\" : \"443\"}/hello`\n\t\t\t\t)\n\t\t\t).toBe(\n\t\t\t\tprotocol === \"http\"\n\t\t\t\t\t? \"//example.com:80/hello\"\n\t\t\t\t\t: \"http://example.com/hello\"\n\t\t\t);\n\t\t}\n\t}\n);\n\n// useful if domain based localization is used for example\ntest(\"returns an absolute href if the provided href is relative but the origin of the localized href differs\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\", \"globalVariable\", \"baseLocale\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"http://example.com/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://de.example.com/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://example.com/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// simulating routing from current en page to de page\n\truntime.overwriteGetLocale(() => \"en\");\n\truntime.overwriteGetUrlOrigin(() => \"http://example.com\");\n\n\texpect(runtime.localizeHref(\"/hello\", { locale: \"de\" })).toBe(\n\t\t\"http://de.example.com/hello\"\n\t);\n\texpect(runtime.deLocalizeHref(\"http://de.example.com/hello\")).toBe(\n\t\t\"http://example.com/hello\"\n\t);\n\n\t// simulating routing from current de page to en page\n\truntime.overwriteGetLocale(() => \"de\");\n\n\texpect(runtime.localizeHref(\"/hello\", { locale: \"en\" })).toBe(\n\t\t\"http://example.com/hello\"\n\t);\n\texpect(runtime.deLocalizeHref(\"http://example.com/hello\")).toBe(\n\t\t\"http://example.com/hello\"\n\t);\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/362\ntest(\"adding a base path\", async () => {\n\tconst base = \"shop\";\n\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: `/{${base}/}?:path(.*)?`,\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", `/{${base}/}?de/:path(.*)?`],\n\t\t\t\t\t[\"en\", `/{${base}/}?:path(.*)?`],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// simulating the current locale to be en\n\truntime.overwriteGetLocale(() => \"en\");\n\n\texpect(runtime.localizeHref(\"/about\")).toBe(\"/shop/about\");\n\texpect(runtime.deLocalizeHref(\"/about\")).toBe(\"/shop/about\");\n\n\t// simulating current locale to be de\n\truntime.overwriteGetLocale(() => \"de\");\n\texpect(runtime.localizeHref(\"/about\")).toBe(\"/shop/de/about\");\n\texpect(runtime.deLocalizeHref(\"/de/about\")).toBe(\"/shop/about\");\n});\n\ntest(\"default url patterns to improve out of the box experience\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\t\t},\n\t\t}),\n\t\tisServer: \"false\",\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: undefined,\n\t});\n\n\t// polyfilling window\n\tglobalThis.window = { location: new URL(\"http://example.com\") } as any;\n\n\texpect(runtime.urlPatterns).toStrictEqual([\n\t\t{\n\t\t\tpattern: \":protocol://:domain(.*)::port?/:path(.*)?\",\n\t\t\tlocalized: [\n\t\t\t\t[\"de\", \":protocol://:domain(.*)::port?/de/:path(.*)?\"],\n\t\t\t\t[\"fr\", \":protocol://:domain(.*)::port?/fr/:path(.*)?\"],\n\t\t\t\t[\"en\", \":protocol://:domain(.*)::port?/:path(.*)?\"],\n\t\t\t],\n\t\t},\n\t]);\n\n\t// expecting the baseLocale to not be included in the url\n\texpect(runtime.localizeHref(\"/about\", { locale: \"en\" })).toBe(\"/about\");\n\texpect(runtime.localizeHref(\"/about\", { locale: \"de\" })).toBe(\"/de/about\");\n\n\t// expecting root path to work\n\texpect(runtime.localizeHref(\"/\", { locale: \"en\" })).toBe(\"/\");\n\texpect(runtime.localizeHref(\"/\", { locale: \"de\" })).toBe(\"/de/\");\n\n\t// expecting de-localization to work\n\texpect(runtime.deLocalizeHref(\"/de/\")).toBe(\"/\");\n\texpect(runtime.deLocalizeHref(\"/de/about\")).toBe(\"/about\");\n\texpect(runtime.deLocalizeHref(\"/about\")).toBe(\"/about\");\n\n\t// expecting localhost to work (for development)\n\texpect(runtime.localizeHref(\"http://localhost:5173/\", { locale: \"de\" })).toBe(\n\t\t\"http://localhost:5173/de/\"\n\t);\n\n\t// de-localizing localhost\n\texpect(runtime.deLocalizeHref(\"http://localhost:5173/de\")).toBe(\n\t\t\"http://localhost:5173/\"\n\t);\n\n\t// pathnames\n\texpect(\n\t\truntime.localizeHref(\"http://localhost:5173/about\", { locale: \"de\" })\n\t).toBe(\"http://localhost:5173/de/about\");\n\n\texpect(runtime.deLocalizeHref(\"http://localhost:5173/de/about\")).toBe(\n\t\t\"http://localhost:5173/about\"\n\t);\n});\n\ntest(\"normalizes localized root hrefs and anchors\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tisServer: \"false\",\n\t\tstrategy: [\"url\"],\n\t\ttrailingSlash: \"never\",\n\t});\n\n\tglobalThis.window = { location: new URL(\"http://example.com\") } as any;\n\n\texpect(runtime.localizeHref(\"/\", { locale: \"de\" })).toBe(\"/de\");\n\texpect(runtime.localizeHref(\"/#section\", { locale: \"de\" })).toBe(\n\t\t\"/de#section\"\n\t);\n\texpect(runtime.deLocalizeHref(\"/de/\")).toBe(\"/\");\n});\n\ntest(\"normalizes mixed-case explicit locales in localizeHref\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\"],\n\t});\n\n\texpect(runtime.localizeHref(\"/about\", { locale: \"DE\" })).toBe(\"/de/about\");\n\n\texpect(runtime.localizeHref(\"/de/about\", { locale: \"EN\" })).toBe(\"/about\");\n});\n\ntest(\"keeps custom URLPattern path expressions on the generic fallback\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: {\n\t\t\t\tbaseLocale: \"en\",\n\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t},\n\t\t}),\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:slug(.)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/:slug(.)?\"],\n\t\t\t\t\t[\"de\", \"/de/:slug(.)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\truntime.overwriteGetLocale(() => \"en\");\n\truntime.overwriteGetUrlOrigin(() => \"https://example.com\");\n\n\t// `(.)` matches exactly one character in URLPattern. A prefix-only\n\t// implementation must not broaden this route into a catch-all.\n\texpect(runtime.localizeHref(\"/a\", { locale: \"de\" })).toBe(\"/de/a\");\n\texpect(runtime.localizeHref(\"/about\", { locale: \"de\" })).toBe(\"/about\");\n});\n\ntest.each([undefined, \"always\", \"never\"] as const)(\n\t\"default hrefs preserve slashes unless trailingSlash is %s\",\n\tasync (trailingSlash) => {\n\t\tconst runtime = await createParaglide({\n\t\t\tblob: await newProject({\n\t\t\t\tsettings: { baseLocale: \"de\", locales: [\"de\", \"en\"] },\n\t\t\t}),\n\t\t\tstrategy: [\"url\", \"baseLocale\"],\n\t\t\ttrailingSlash,\n\t\t});\n\t\tconst paths = [\"/\", \"/about/\", \"/contact/\"];\n\t\tconst suffix = trailingSlash === \"never\" ? \"\" : \"/\";\n\t\texpect(\n\t\t\tpaths.flatMap((path) =>\n\t\t\t\truntime.locales.map((locale) => runtime.localizeHref(path, { locale }))\n\t\t\t)\n\t\t).toEqual([\n\t\t\t\"/\",\n\t\t\t\"/en\" + suffix,\n\t\t\t\"/about\" + suffix,\n\t\t\t\"/en/about\" + suffix,\n\t\t\t\"/contact\" + suffix,\n\t\t\t\"/en/contact\" + suffix,\n\t\t]);\n\t\texpect(runtime.localizeHref(\"/about\", { locale: \"en\" })).toBe(\n\t\t\t\"/en/about\" + (trailingSlash === \"always\" ? \"/\" : \"\")\n\t\t);\n\t\texpect(runtime.deLocalizeHref(\"/en/about/?q=test#section\")).toBe(\n\t\t\t\"/about\" + suffix + \"?q=test#section\"\n\t\t);\n\t\texpect(\n\t\t\truntime.localizeHref(\"/en/about/?q=test#section\", { locale: \"de\" })\n\t\t).toBe(\"/about\" + suffix + \"?q=test#section\");\n\t}\n);\n\ntest(\"default routes remove detected locales after repeated leading separators\", async () => {\n\tconst runtime = await createParaglide({\n\t\tblob: await newProject({\n\t\t\tsettings: { baseLocale: \"en\", locales: [\"en\", \"de\", \"fr\"] },\n\t\t}),\n\t\tstrategy: [\"url\", \"baseLocale\"],\n\t});\n\tfor (const suffix of [\"\", \"/\"]) {\n\t\tconst input = `https://example.com//de/about${suffix}?q=test#section`;\n\t\texpect(runtime.extractLocaleFromUrl(input)).toBe(\"de\");\n\t\texpect(runtime.localizeUrl(input, { locale: \"en\" }).href).toBe(\n\t\t\t`https://example.com/about${suffix}?q=test#section`\n\t\t);\n\t\texpect(runtime.localizeUrl(input, { locale: \"fr\" }).href).toBe(\n\t\t\t`https://example.com/fr/about${suffix}?q=test#section`\n\t\t);\n\t\texpect(runtime.deLocalizeUrl(input).href).toBe(\n\t\t\t`https://example.com/about${suffix}?q=test#section`\n\t\t);\n\t}\n});\n"]}
@@ -3,7 +3,7 @@ import { clearLocaleCookieCache } from "./extract-locale-from-cookie.js";
3
3
  import { localizeUrl } from "./localize-url.js";
4
4
  import { getStrategyForUrl } from "./route-strategy.js";
5
5
  import { customClientStrategies, isCustomStrategy } from "./strategy.js";
6
- import { cookieDomain, cookieMaxAge, cookieName, isServer, localStorageKey, experimentalStaticLocale, strategy, TREE_SHAKE_COOKIE_STRATEGY_USED, TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED, TREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED, TREE_SHAKE_URL_STRATEGY_USED, } from "./variables.js";
6
+ import { cookieDomain, cookieMaxAge, cookieName, cookieSameSite, cookieSecure, isServer, localStorageKey, experimentalStaticLocale, strategy, TREE_SHAKE_COOKIE_STRATEGY_USED, TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED, TREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED, TREE_SHAKE_URL_STRATEGY_USED, } from "./variables.js";
7
7
  /**
8
8
  * Navigates to the localized URL, or reloads the current page
9
9
  *
@@ -89,10 +89,23 @@ export let setLocale = (newLocale, options) => {
89
89
  continue;
90
90
  }
91
91
  // set the cookie
92
- const cookieString = `${cookieName}=${newLocale}; path=/; max-age=${cookieMaxAge}`;
93
- document.cookie = cookieDomain
94
- ? `${cookieString}; domain=${cookieDomain}`
95
- : cookieString;
92
+ let cookieString = `${cookieName}=${newLocale}; path=/; max-age=${cookieMaxAge}`;
93
+ if (cookieDomain) {
94
+ cookieString += `; domain=${cookieDomain}`;
95
+ }
96
+ if (cookieSameSite) {
97
+ cookieString += `; samesite=${cookieSameSite}`;
98
+ }
99
+ if (cookieSecure === true ||
100
+ (cookieSecure === "auto" && window.location?.protocol === "https:")) {
101
+ cookieString += "; secure";
102
+ }
103
+ try {
104
+ document.cookie = cookieString;
105
+ }
106
+ catch {
107
+ // document.cookie throws in sandboxed iframes and other opaque origins
108
+ }
96
109
  clearLocaleCookieCache();
97
110
  }
98
111
  else if (strat === "baseLocale") {
@@ -118,7 +131,12 @@ export let setLocale = (newLocale, options) => {
118
131
  strat === "localStorage" &&
119
132
  typeof window !== "undefined") {
120
133
  // set the localStorage
121
- localStorage.setItem(localStorageKey, newLocale);
134
+ try {
135
+ localStorage.setItem(localStorageKey, newLocale);
136
+ }
137
+ catch {
138
+ // localStorage throws when storage access is denied
139
+ }
122
140
  }
123
141
  else if (isCustomStrategy(strat) && customClientStrategies.has(strat)) {
124
142
  const handler = customClientStrategies.get(strat);
@@ -1 +1 @@
1
- {"version":3,"file":"set-locale.js","sourceRoot":"","sources":["../../../src/compiler/runtime/set-locale.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,eAAe,EACf,wBAAwB,EACxB,QAAQ,EACR,+BAA+B,EAC/B,wCAAwC,EACxC,sCAAsC,EACtC,4BAA4B,GAC5B,MAAM,gBAAgB,CAAC;AAExB;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,EAAE;IACxC,IAAI,WAAW,EAAE,CAAC;QACjB,+CAA+C;QAC/C,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,WAAW,CAAC;IACpC,CAAC;SAAM,CAAC;QACP,4CAA4C;QAC5C,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC1B,CAAC;AACF,CAAC,CAAC;AAEF;;GAEG;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,IAAI,SAAS,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE;IAC7C,MAAM,mBAAmB,GAAG;QAC3B,MAAM,EAAE,IAAI;QACZ,GAAG,OAAO;KACV,CAAC;IACF,IACC,wBAAwB,KAAK,SAAS;QACtC,SAAS,KAAK,wBAAwB;QACtC,mBAAmB,CAAC,MAAM,KAAK,KAAK,EACnC,CAAC;QACF,OAAO,CAAC,IAAI,CACX,wBAAwB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,4EAA4E,IAAI,CAAC,SAAS,CAAC,wBAAwB,CAAC,sEAAsE,CAC3O,CAAC;QACF,mBAAmB,CAAC,MAAM,GAAG,IAAI,CAAC;IACnC,CAAC;IACD,wBAAwB;IACxB,0DAA0D;IAC1D,iCAAiC;IACjC,IAAI,aAAa,CAAC;IAClB,IAAI,CAAC;QACJ,aAAa,GAAG,SAAS,EAAE,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACR,0CAA0C;IAC3C,CAAC;IACD,mCAAmC;IACnC,MAAM,uBAAuB,GAAG,EAAE,CAAC;IACnC,iCAAiC;IACjC,IAAI,WAAW,GAAG,SAAS,CAAC;IAC5B,IAAI,aAAa,GAAG,QAAQ,CAAC;IAC7B,IAAI,CAAC,QAAQ,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;QACzE,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QACnC,IACC,wCAAwC;YACxC,KAAK,KAAK,gBAAgB,EACzB,CAAC;YACF,yDAAyD;YACzD,+CAA+C;YAC/C,OAAO,GAAG,SAAS,CAAC;QACrB,CAAC;aAAM,IAAI,+BAA+B,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClE,IACC,QAAQ;gBACR,OAAO,QAAQ,KAAK,WAAW;gBAC/B,OAAO,MAAM,KAAK,WAAW,EAC5B,CAAC;gBACF,SAAS;YACV,CAAC;YAED,iBAAiB;YACjB,MAAM,YAAY,GAAG,GAAG,UAAU,IAAI,SAAS,qBAAqB,YAAY,EAAE,CAAC;YACnF,QAAQ,CAAC,MAAM,GAAG,YAAY;gBAC7B,CAAC,CAAC,GAAG,YAAY,YAAY,YAAY,EAAE;gBAC3C,CAAC,CAAC,YAAY,CAAC;YAChB,sBAAsB,EAAE,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;YACnC,wDAAwD;YACxD,SAAS;QACV,CAAC;aAAM,IACN,4BAA4B;YAC5B,KAAK,KAAK,KAAK;YACf,OAAO,MAAM,KAAK,WAAW,EAC5B,CAAC;YACF,uBAAuB;YACvB,EAAE;YACF,gDAAgD;YAChD,4CAA4C;YAC5C,EAAE;YACF,qDAAqD;YACrD,qDAAqD;YACrD,sBAAsB;YACtB,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;gBAC/C,MAAM,EAAE,SAAS;aACjB,CAAC,CAAC,IAAI,CAAC;QACT,CAAC;aAAM,IACN,sCAAsC;YACtC,KAAK,KAAK,cAAc;YACxB,OAAO,MAAM,KAAK,WAAW,EAC5B,CAAC;YACF,uBAAuB;YACvB,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,IAAI,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,OAAO,EAAE,CAAC;gBACb,IAAI,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBAC1C,yBAAyB;gBACzB,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;oBAC/B,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;wBAC/B,MAAM,IAAI,KAAK,CAAC,oBAAoB,KAAK,qBAAqB,EAAE;4BAC/D,KAAK,EAAE,KAAK;yBACZ,CAAC,CAAC;oBACJ,CAAC,CAAC,CAAC;oBACH,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtC,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,EAAE;QACtB,IACC,CAAC,QAAQ;YACT,mBAAmB,CAAC,MAAM;YAC1B,MAAM,CAAC,QAAQ;YACf,SAAS,KAAK,aAAa,EAC1B,CAAC;YACF,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC/B,CAAC;IACF,CAAC,CAAC;IAEF,IAAI,uBAAuB,CAAC,MAAM,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACrD,SAAS,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,SAAS,EAAE,CAAC;IAEZ,OAAO;AACR,CAAC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAE,EAAE,EAAE;IACxC,SAAS,GAAG,EAAE,CAAC;AAChB,CAAC,CAAC","sourcesContent":["import { getLocale } from \"./get-locale.js\";\nimport { clearLocaleCookieCache } from \"./extract-locale-from-cookie.js\";\nimport { localizeUrl } from \"./localize-url.js\";\nimport { getStrategyForUrl } from \"./route-strategy.js\";\nimport { customClientStrategies, isCustomStrategy } from \"./strategy.js\";\nimport {\n\tcookieDomain,\n\tcookieMaxAge,\n\tcookieName,\n\tisServer,\n\tlocalStorageKey,\n\texperimentalStaticLocale,\n\tstrategy,\n\tTREE_SHAKE_COOKIE_STRATEGY_USED,\n\tTREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED,\n\tTREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED,\n\tTREE_SHAKE_URL_STRATEGY_USED,\n} from \"./variables.js\";\n\n/**\n * Navigates to the localized URL, or reloads the current page\n *\n * @param {string} [newLocation] The new location\n */\nconst navigateOrReload = (newLocation) => {\n\tif (newLocation) {\n\t\t// reload the page by navigating to the new url\n\t\twindow.location.href = newLocation;\n\t} else {\n\t\t// reload the page to reflect the new locale\n\t\twindow.location.reload();\n\t}\n};\n\n/**\n * @typedef {(newLocale: Locale, options?: { reload?: boolean }) => void | Promise<void>} SetLocaleFn\n */\n\n/**\n * Set the locale.\n *\n * Updates the locale using your configured strategies (cookie, localStorage, URL, etc.).\n * By default, this navigates the client to the localized URL or reloads the current\n * document to reflect the new locale. `reload: false` is a narrow browser-only escape\n * hatch for a fully client-rendered, non-URL-routed surface that owns its reactive\n * updates and document state. It does not re-render the UI or update the document.\n * Do not use it for normal locale pickers, URL-routed pages, or switching an SSR,\n * SSG, or hydrated document. It is incompatible with per-locale builds.\n *\n * If any custom strategy's `setLocale` function is async, then this function\n * will become async as well.\n *\n * @see https://paraglidejs.com/strategy\n *\n * @example\n * setLocale('en');\n *\n * @example\n * setLocale('en', { reload: false });\n *\n * @type {SetLocaleFn}\n */\nexport let setLocale = (newLocale, options) => {\n\tconst optionsWithDefaults = {\n\t\treload: true,\n\t\t...options,\n\t};\n\tif (\n\t\texperimentalStaticLocale !== undefined &&\n\t\tnewLocale !== experimentalStaticLocale &&\n\t\toptionsWithDefaults.reload === false\n\t) {\n\t\tconsole.warn(\n\t\t\t`Paraglide: setLocale(${JSON.stringify(newLocale)}, { reload: false }) cannot switch away from the statically built locale ${JSON.stringify(experimentalStaticLocale)}. A document navigation is required; reload has been forced to true.`\n\t\t);\n\t\toptionsWithDefaults.reload = true;\n\t}\n\t// locale is already set\n\t// https://github.com/opral/inlang-paraglide-js/issues/430\n\t/** @type {Locale | undefined} */\n\tlet currentLocale;\n\ttry {\n\t\tcurrentLocale = getLocale();\n\t} catch {\n\t\t// do nothing, no locale has been set yet.\n\t}\n\t/** @type {Array<Promise<void>>} */\n\tconst customSetLocalePromises = [];\n\t/** @type {string | undefined} */\n\tlet newLocation = undefined;\n\tlet strategyToUse = strategy;\n\tif (!isServer && typeof window !== \"undefined\" && window.location?.href) {\n\t\tstrategyToUse = getStrategyForUrl(window.location.href);\n\t}\n\tfor (const strat of strategyToUse) {\n\t\tif (\n\t\t\tTREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED &&\n\t\t\tstrat === \"globalVariable\"\n\t\t) {\n\t\t\t// a default for a custom strategy to get started quickly\n\t\t\t// is likely overwritten by `defineSetLocale()`\n\t\t\t_locale = newLocale;\n\t\t} else if (TREE_SHAKE_COOKIE_STRATEGY_USED && strat === \"cookie\") {\n\t\t\tif (\n\t\t\t\tisServer ||\n\t\t\t\ttypeof document === \"undefined\" ||\n\t\t\t\ttypeof window === \"undefined\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// set the cookie\n\t\t\tconst cookieString = `${cookieName}=${newLocale}; path=/; max-age=${cookieMaxAge}`;\n\t\t\tdocument.cookie = cookieDomain\n\t\t\t\t? `${cookieString}; domain=${cookieDomain}`\n\t\t\t\t: cookieString;\n\t\t\tclearLocaleCookieCache();\n\t\t} else if (strat === \"baseLocale\") {\n\t\t\t// nothing to be set here. baseLocale is only a fallback\n\t\t\tcontinue;\n\t\t} else if (\n\t\t\tTREE_SHAKE_URL_STRATEGY_USED &&\n\t\t\tstrat === \"url\" &&\n\t\t\ttypeof window !== \"undefined\"\n\t\t) {\n\t\t\t// route to the new url\n\t\t\t//\n\t\t\t// this triggers a page reload but a user rarely\n\t\t\t// switches locales, so this should be fine.\n\t\t\t//\n\t\t\t// if the behavior is not desired, the implementation\n\t\t\t// can be overwritten by `defineSetLocale()` to avoid\n\t\t\t// a full page reload.\n\t\t\tnewLocation = localizeUrl(window.location.href, {\n\t\t\t\tlocale: newLocale,\n\t\t\t}).href;\n\t\t} else if (\n\t\t\tTREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED &&\n\t\t\tstrat === \"localStorage\" &&\n\t\t\ttypeof window !== \"undefined\"\n\t\t) {\n\t\t\t// set the localStorage\n\t\t\tlocalStorage.setItem(localStorageKey, newLocale);\n\t\t} else if (isCustomStrategy(strat) && customClientStrategies.has(strat)) {\n\t\t\tconst handler = customClientStrategies.get(strat);\n\t\t\tif (handler) {\n\t\t\t\tlet result = handler.setLocale(newLocale);\n\t\t\t\t// Handle async setLocale\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\tresult = result.catch((error) => {\n\t\t\t\t\t\tthrow new Error(`Custom strategy \"${strat}\" setLocale failed.`, {\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\tcustomSetLocalePromises.push(result);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst runReload = () => {\n\t\tif (\n\t\t\t!isServer &&\n\t\t\toptionsWithDefaults.reload &&\n\t\t\twindow.location &&\n\t\t\tnewLocale !== currentLocale\n\t\t) {\n\t\t\tnavigateOrReload(newLocation);\n\t\t}\n\t};\n\n\tif (customSetLocalePromises.length) {\n\t\treturn Promise.all(customSetLocalePromises).then(() => {\n\t\t\trunReload();\n\t\t});\n\t}\n\n\trunReload();\n\n\treturn;\n};\n\n/**\n * Overwrite the `setLocale()` function.\n *\n * Use this function to overwrite how the locale is set. For example,\n * modify a cookie, env variable, or a user's preference.\n *\n * @example\n * overwriteSetLocale((newLocale) => {\n * // set the locale in a cookie\n * return Cookies.set('locale', newLocale)\n * });\n *\n * @param {SetLocaleFn} fn\n */\nexport const overwriteSetLocale = (fn) => {\n\tsetLocale = fn;\n};\n"]}
1
+ {"version":3,"file":"set-locale.js","sourceRoot":"","sources":["../../../src/compiler/runtime/set-locale.js"],"names":[],"mappings":"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","sourcesContent":["import { getLocale } from \"./get-locale.js\";\nimport { clearLocaleCookieCache } from \"./extract-locale-from-cookie.js\";\nimport { localizeUrl } from \"./localize-url.js\";\nimport { getStrategyForUrl } from \"./route-strategy.js\";\nimport { customClientStrategies, isCustomStrategy } from \"./strategy.js\";\nimport {\n\tcookieDomain,\n\tcookieMaxAge,\n\tcookieName,\n\tcookieSameSite,\n\tcookieSecure,\n\tisServer,\n\tlocalStorageKey,\n\texperimentalStaticLocale,\n\tstrategy,\n\tTREE_SHAKE_COOKIE_STRATEGY_USED,\n\tTREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED,\n\tTREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED,\n\tTREE_SHAKE_URL_STRATEGY_USED,\n} from \"./variables.js\";\n\n/**\n * Navigates to the localized URL, or reloads the current page\n *\n * @param {string} [newLocation] The new location\n */\nconst navigateOrReload = (newLocation) => {\n\tif (newLocation) {\n\t\t// reload the page by navigating to the new url\n\t\twindow.location.href = newLocation;\n\t} else {\n\t\t// reload the page to reflect the new locale\n\t\twindow.location.reload();\n\t}\n};\n\n/**\n * @typedef {(newLocale: Locale, options?: { reload?: boolean }) => void | Promise<void>} SetLocaleFn\n */\n\n/**\n * Set the locale.\n *\n * Updates the locale using your configured strategies (cookie, localStorage, URL, etc.).\n * By default, this navigates the client to the localized URL or reloads the current\n * document to reflect the new locale. `reload: false` is a narrow browser-only escape\n * hatch for a fully client-rendered, non-URL-routed surface that owns its reactive\n * updates and document state. It does not re-render the UI or update the document.\n * Do not use it for normal locale pickers, URL-routed pages, or switching an SSR,\n * SSG, or hydrated document. It is incompatible with per-locale builds.\n *\n * If any custom strategy's `setLocale` function is async, then this function\n * will become async as well.\n *\n * @see https://paraglidejs.com/strategy\n *\n * @example\n * setLocale('en');\n *\n * @example\n * setLocale('en', { reload: false });\n *\n * @type {SetLocaleFn}\n */\nexport let setLocale = (newLocale, options) => {\n\tconst optionsWithDefaults = {\n\t\treload: true,\n\t\t...options,\n\t};\n\tif (\n\t\texperimentalStaticLocale !== undefined &&\n\t\tnewLocale !== experimentalStaticLocale &&\n\t\toptionsWithDefaults.reload === false\n\t) {\n\t\tconsole.warn(\n\t\t\t`Paraglide: setLocale(${JSON.stringify(newLocale)}, { reload: false }) cannot switch away from the statically built locale ${JSON.stringify(experimentalStaticLocale)}. A document navigation is required; reload has been forced to true.`\n\t\t);\n\t\toptionsWithDefaults.reload = true;\n\t}\n\t// locale is already set\n\t// https://github.com/opral/inlang-paraglide-js/issues/430\n\t/** @type {Locale | undefined} */\n\tlet currentLocale;\n\ttry {\n\t\tcurrentLocale = getLocale();\n\t} catch {\n\t\t// do nothing, no locale has been set yet.\n\t}\n\t/** @type {Array<Promise<void>>} */\n\tconst customSetLocalePromises = [];\n\t/** @type {string | undefined} */\n\tlet newLocation = undefined;\n\tlet strategyToUse = strategy;\n\tif (!isServer && typeof window !== \"undefined\" && window.location?.href) {\n\t\tstrategyToUse = getStrategyForUrl(window.location.href);\n\t}\n\tfor (const strat of strategyToUse) {\n\t\tif (\n\t\t\tTREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED &&\n\t\t\tstrat === \"globalVariable\"\n\t\t) {\n\t\t\t// a default for a custom strategy to get started quickly\n\t\t\t// is likely overwritten by `defineSetLocale()`\n\t\t\t_locale = newLocale;\n\t\t} else if (TREE_SHAKE_COOKIE_STRATEGY_USED && strat === \"cookie\") {\n\t\t\tif (\n\t\t\t\tisServer ||\n\t\t\t\ttypeof document === \"undefined\" ||\n\t\t\t\ttypeof window === \"undefined\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// set the cookie\n\t\t\tlet cookieString = `${cookieName}=${newLocale}; path=/; max-age=${cookieMaxAge}`;\n\t\t\tif (cookieDomain) {\n\t\t\t\tcookieString += `; domain=${cookieDomain}`;\n\t\t\t}\n\t\t\tif (cookieSameSite) {\n\t\t\t\tcookieString += `; samesite=${cookieSameSite}`;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tcookieSecure === true ||\n\t\t\t\t(cookieSecure === \"auto\" && window.location?.protocol === \"https:\")\n\t\t\t) {\n\t\t\t\tcookieString += \"; secure\";\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tdocument.cookie = cookieString;\n\t\t\t} catch {\n\t\t\t\t// document.cookie throws in sandboxed iframes and other opaque origins\n\t\t\t}\n\n\t\t\tclearLocaleCookieCache();\n\t\t} else if (strat === \"baseLocale\") {\n\t\t\t// nothing to be set here. baseLocale is only a fallback\n\t\t\tcontinue;\n\t\t} else if (\n\t\t\tTREE_SHAKE_URL_STRATEGY_USED &&\n\t\t\tstrat === \"url\" &&\n\t\t\ttypeof window !== \"undefined\"\n\t\t) {\n\t\t\t// route to the new url\n\t\t\t//\n\t\t\t// this triggers a page reload but a user rarely\n\t\t\t// switches locales, so this should be fine.\n\t\t\t//\n\t\t\t// if the behavior is not desired, the implementation\n\t\t\t// can be overwritten by `defineSetLocale()` to avoid\n\t\t\t// a full page reload.\n\t\t\tnewLocation = localizeUrl(window.location.href, {\n\t\t\t\tlocale: newLocale,\n\t\t\t}).href;\n\t\t} else if (\n\t\t\tTREE_SHAKE_LOCAL_STORAGE_STRATEGY_USED &&\n\t\t\tstrat === \"localStorage\" &&\n\t\t\ttypeof window !== \"undefined\"\n\t\t) {\n\t\t\t// set the localStorage\n\t\t\ttry {\n\t\t\t\tlocalStorage.setItem(localStorageKey, newLocale);\n\t\t\t} catch {\n\t\t\t\t// localStorage throws when storage access is denied\n\t\t\t}\n\t\t} else if (isCustomStrategy(strat) && customClientStrategies.has(strat)) {\n\t\t\tconst handler = customClientStrategies.get(strat);\n\t\t\tif (handler) {\n\t\t\t\tlet result = handler.setLocale(newLocale);\n\t\t\t\t// Handle async setLocale\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\tresult = result.catch((error) => {\n\t\t\t\t\t\tthrow new Error(`Custom strategy \"${strat}\" setLocale failed.`, {\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\tcustomSetLocalePromises.push(result);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst runReload = () => {\n\t\tif (\n\t\t\t!isServer &&\n\t\t\toptionsWithDefaults.reload &&\n\t\t\twindow.location &&\n\t\t\tnewLocale !== currentLocale\n\t\t) {\n\t\t\tnavigateOrReload(newLocation);\n\t\t}\n\t};\n\n\tif (customSetLocalePromises.length) {\n\t\treturn Promise.all(customSetLocalePromises).then(() => {\n\t\t\trunReload();\n\t\t});\n\t}\n\n\trunReload();\n\n\treturn;\n};\n\n/**\n * Overwrite the `setLocale()` function.\n *\n * Use this function to overwrite how the locale is set. For example,\n * modify a cookie, env variable, or a user's preference.\n *\n * @example\n * overwriteSetLocale((newLocale) => {\n * // set the locale in a cookie\n * return Cookies.set('locale', newLocale)\n * });\n *\n * @param {SetLocaleFn} fn\n */\nexport const overwriteSetLocale = (fn) => {\n\tsetLocale = fn;\n};\n"]}
@@ -78,6 +78,91 @@ test("sets the cookie with explicit domain to a different locale navigating doma
78
78
  // reloads the site if window is available
79
79
  expect(globalThis.window.location.reload).toBeCalled();
80
80
  });
81
+ test("sets the cookie with samesite and secure attributes", async () => {
82
+ // @ts-expect-error - global variable definition
83
+ globalThis.document = {};
84
+ // @ts-expect-error - global variable definition
85
+ globalThis.window = {};
86
+ // @ts-expect-error - global variable definition
87
+ globalThis.window.location = { hostname: "example.com" };
88
+ globalThis.window.location.reload = vi.fn();
89
+ const runtime = await createParaglide({
90
+ blob: await newProject({
91
+ settings: {
92
+ baseLocale: "en",
93
+ locales: ["en", "de"],
94
+ },
95
+ }),
96
+ strategy: ["cookie"],
97
+ cookieName: "PARAGLIDE_LOCALE",
98
+ cookieDomain: "example.com",
99
+ cookieSameSite: "strict",
100
+ cookieSecure: true,
101
+ });
102
+ globalThis.document.cookie = "PARAGLIDE_LOCALE=en";
103
+ runtime.setLocale("de");
104
+ expect(globalThis.document.cookie).toBe("PARAGLIDE_LOCALE=de; path=/; max-age=34560000; domain=example.com; samesite=strict; secure");
105
+ // exported so server code can write the cookie with the same attributes
106
+ expect(runtime.cookieSameSite).toBe("strict");
107
+ expect(runtime.cookieSecure).toBe(true);
108
+ });
109
+ test.each([true, "auto"])("sets samesite=none with secure on https pages (cookieSecure: %s)", async (cookieSecure) => {
110
+ // @ts-expect-error - global variable definition
111
+ globalThis.document = {};
112
+ // @ts-expect-error - global variable definition
113
+ globalThis.window = {};
114
+ // @ts-expect-error - global variable definition
115
+ globalThis.window.location = {
116
+ hostname: "example.com",
117
+ protocol: "https:",
118
+ };
119
+ globalThis.window.location.reload = vi.fn();
120
+ const runtime = await createParaglide({
121
+ blob: await newProject({
122
+ settings: {
123
+ baseLocale: "en",
124
+ locales: ["en", "de"],
125
+ },
126
+ }),
127
+ strategy: ["cookie"],
128
+ cookieName: "PARAGLIDE_LOCALE",
129
+ cookieSameSite: "none",
130
+ cookieSecure,
131
+ });
132
+ globalThis.document.cookie = "PARAGLIDE_LOCALE=en";
133
+ runtime.setLocale("de");
134
+ expect(globalThis.document.cookie).toBe("PARAGLIDE_LOCALE=de; path=/; max-age=34560000; samesite=none; secure");
135
+ });
136
+ test("cookieSecure 'auto' only sets the secure attribute on https pages", async () => {
137
+ // @ts-expect-error - global variable definition
138
+ globalThis.document = {};
139
+ // @ts-expect-error - global variable definition
140
+ globalThis.window = {};
141
+ // @ts-expect-error - global variable definition
142
+ globalThis.window.location = {
143
+ hostname: "example.com",
144
+ protocol: "https:",
145
+ };
146
+ globalThis.window.location.reload = vi.fn();
147
+ const runtime = await createParaglide({
148
+ blob: await newProject({
149
+ settings: {
150
+ baseLocale: "en",
151
+ locales: ["en", "de"],
152
+ },
153
+ }),
154
+ strategy: ["cookie"],
155
+ cookieName: "PARAGLIDE_LOCALE",
156
+ cookieSameSite: "lax",
157
+ cookieSecure: "auto",
158
+ });
159
+ globalThis.document.cookie = "PARAGLIDE_LOCALE=en";
160
+ runtime.setLocale("de");
161
+ expect(globalThis.document.cookie).toBe("PARAGLIDE_LOCALE=de; path=/; max-age=34560000; samesite=lax; secure");
162
+ globalThis.window.location.protocol = "http:";
163
+ runtime.setLocale("en");
164
+ expect(globalThis.document.cookie).toBe("PARAGLIDE_LOCALE=en; path=/; max-age=34560000; samesite=lax");
165
+ });
81
166
  test("url pattern strategy sets the window location", async () => {
82
167
  // @ts-expect-error - global variable definition
83
168
  globalThis.window = {};
@@ -628,4 +713,101 @@ test("custom strategy setLocale integrates with URL strategy", async () => {
628
713
  expect(globalThis.window.location.href).toBe("https://example.com/de/page");
629
714
  expect(customStoredLocale).toBe("de");
630
715
  });
716
+ // sandboxed iframes without allow-same-origin have an opaque origin and throw
717
+ // a SecurityError on document.cookie and localStorage access
718
+ test("navigates to the localized url when document.cookie throws", async () => {
719
+ const runtime = await createParaglide({
720
+ blob: await newProject({
721
+ settings: {
722
+ baseLocale: "en",
723
+ locales: ["en", "de"],
724
+ },
725
+ }),
726
+ strategy: ["url", "cookie", "baseLocale"],
727
+ cookieName: "PARAGLIDE_LOCALE",
728
+ isServer: "false",
729
+ urlPatterns: [
730
+ {
731
+ pattern: "https://example.com/:path*",
732
+ localized: [
733
+ ["en", "https://example.com/en/:path*"],
734
+ ["de", "https://example.com/de/:path*"],
735
+ ],
736
+ },
737
+ ],
738
+ });
739
+ /** @ts-expect-error - client side api */
740
+ globalThis.document = {
741
+ get cookie() {
742
+ throw new DOMException("The operation is insecure.", "SecurityError");
743
+ },
744
+ set cookie(_value) {
745
+ throw new DOMException("The operation is insecure.", "SecurityError");
746
+ },
747
+ };
748
+ globalThis.window = {
749
+ location: new URL("https://example.com/en/some-path"),
750
+ };
751
+ runtime.setLocale("de");
752
+ expect(globalThis.window.location.href).toBe("https://example.com/de/some-path");
753
+ });
754
+ test("reloads when document.cookie throws", async () => {
755
+ const runtime = await createParaglide({
756
+ blob: await newProject({
757
+ settings: {
758
+ baseLocale: "en",
759
+ locales: ["en", "de"],
760
+ },
761
+ }),
762
+ strategy: ["cookie", "baseLocale"],
763
+ cookieName: "PARAGLIDE_LOCALE",
764
+ isServer: "false",
765
+ });
766
+ /** @ts-expect-error - client side api */
767
+ globalThis.document = {
768
+ get cookie() {
769
+ throw new DOMException("The operation is insecure.", "SecurityError");
770
+ },
771
+ set cookie(_value) {
772
+ throw new DOMException("The operation is insecure.", "SecurityError");
773
+ },
774
+ };
775
+ globalThis.window = {
776
+ location: {
777
+ href: "https://example.com/page",
778
+ reload: vi.fn(),
779
+ },
780
+ };
781
+ runtime.setLocale("de");
782
+ expect(globalThis.window.location.reload).toBeCalled();
783
+ });
784
+ test("reloads when localStorage throws", async () => {
785
+ const runtime = await createParaglide({
786
+ blob: await newProject({
787
+ settings: {
788
+ baseLocale: "en",
789
+ locales: ["en", "de"],
790
+ },
791
+ }),
792
+ strategy: ["localStorage", "baseLocale"],
793
+ isServer: "false",
794
+ });
795
+ // @ts-expect-error - global variable definition
796
+ globalThis.localStorage = {
797
+ getItem: () => {
798
+ throw new DOMException("The operation is insecure.", "SecurityError");
799
+ },
800
+ setItem: () => {
801
+ throw new DOMException("The operation is insecure.", "SecurityError");
802
+ },
803
+ };
804
+ globalThis.window = {
805
+ location: {
806
+ href: "https://example.com/page",
807
+ reload: vi.fn(),
808
+ },
809
+ };
810
+ runtime.setLocale("de");
811
+ expect(globalThis.window.location.reload).toBeCalled();
812
+ });
631
813
  //# sourceMappingURL=set-locale.test.js.map