@sebbro/paraglide-lite 0.1.0 → 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.
- package/dist/bundler-plugins/per-locale-build/index.js +5 -3
- package/dist/bundler-plugins/per-locale-build/index.js.map +1 -1
- package/dist/bundler-plugins/per-locale-build/vite-environments.js +12 -7
- package/dist/bundler-plugins/per-locale-build/vite-environments.js.map +1 -1
- package/dist/bundler-plugins/plugin-core.d.ts +38 -2
- package/dist/bundler-plugins/plugin-core.js +198 -11
- package/dist/bundler-plugins/plugin-core.js.map +1 -1
- package/dist/bundler-plugins/rolldown.test.js +15 -6
- package/dist/bundler-plugins/rolldown.test.js.map +1 -1
- package/dist/bundler-plugins/unplugin.js +5 -0
- package/dist/bundler-plugins/unplugin.js.map +1 -1
- package/dist/bundler-plugins/unplugin.test.js +67 -0
- package/dist/bundler-plugins/unplugin.test.js.map +1 -1
- package/dist/bundler-plugins/virtual-modules.test.js +64 -1
- package/dist/bundler-plugins/virtual-modules.test.js.map +1 -1
- package/dist/cli/commands/compile/command.js +8 -1
- package/dist/cli/commands/compile/command.js.map +1 -1
- package/dist/cli/commands/compile/command.test.js +51 -0
- package/dist/cli/commands/compile/command.test.js.map +1 -1
- package/dist/compiler/compile-annotation.d.ts +2 -2
- package/dist/compiler/compile-annotation.js +9 -9
- package/dist/compiler/compile-annotation.js.map +1 -1
- package/dist/compiler/compile-local-variable.d.ts +2 -1
- package/dist/compiler/compile-local-variable.js +4 -4
- package/dist/compiler/compile-local-variable.js.map +1 -1
- package/dist/compiler/compile-local-variable.test.js +82 -0
- package/dist/compiler/compile-local-variable.test.js.map +1 -1
- package/dist/compiler/compile-message.js +10 -2
- package/dist/compiler/compile-message.js.map +1 -1
- package/dist/compiler/compile-message.test.js +132 -2
- package/dist/compiler/compile-message.test.js.map +1 -1
- package/dist/compiler/compile-pattern.js +4 -2
- package/dist/compiler/compile-pattern.js.map +1 -1
- package/dist/compiler/compile-pattern.test.js +31 -0
- package/dist/compiler/compile-pattern.test.js.map +1 -1
- package/dist/compiler/compile.bench.js +1 -1
- package/dist/compiler/compile.bench.js.map +1 -1
- package/dist/compiler/compile.test.js +14 -0
- package/dist/compiler/compile.test.js.map +1 -1
- package/dist/compiler/compiler-options.d.ts +9 -1
- package/dist/compiler/compiler-options.js.map +1 -1
- package/dist/compiler/emit-message-dts.d.ts +18 -0
- package/dist/compiler/emit-message-dts.js +166 -0
- package/dist/compiler/emit-message-dts.js.map +1 -0
- package/dist/compiler/emit-message-dts.test.d.ts +1 -0
- package/dist/compiler/emit-message-dts.test.js +283 -0
- package/dist/compiler/emit-message-dts.test.js.map +1 -0
- package/dist/compiler/runtime/create-runtime.d.ts +1 -0
- package/dist/compiler/runtime/create-runtime.js +11 -0
- package/dist/compiler/runtime/create-runtime.js.map +1 -1
- package/dist/compiler/runtime/exec-url-pattern.d.ts +9 -0
- package/dist/compiler/runtime/exec-url-pattern.js +31 -0
- package/dist/compiler/runtime/exec-url-pattern.js.map +1 -0
- package/dist/compiler/runtime/extract-locale-from-url.js +9 -4
- package/dist/compiler/runtime/extract-locale-from-url.js.map +1 -1
- package/dist/compiler/runtime/generate-static-localized-urls.js +13 -6
- package/dist/compiler/runtime/generate-static-localized-urls.js.map +1 -1
- package/dist/compiler/runtime/generate-static-localized-urls.test.js +38 -0
- package/dist/compiler/runtime/generate-static-localized-urls.test.js.map +1 -1
- package/dist/compiler/runtime/host-routing.d.ts +3 -3
- package/dist/compiler/runtime/host-routing.js +2 -2
- package/dist/compiler/runtime/host-routing.js.map +1 -1
- package/dist/compiler/runtime/host-routing.test.js +79 -0
- package/dist/compiler/runtime/host-routing.test.js.map +1 -1
- package/dist/compiler/runtime/localize-href.bench.d.ts +1 -0
- package/dist/compiler/runtime/localize-href.bench.js +68 -0
- package/dist/compiler/runtime/localize-href.bench.js.map +1 -0
- package/dist/compiler/runtime/localize-href.test.js +35 -0
- package/dist/compiler/runtime/localize-href.test.js.map +1 -1
- package/dist/compiler/runtime/localize-url.d.ts +14 -0
- package/dist/compiler/runtime/localize-url.js +338 -19
- package/dist/compiler/runtime/localize-url.js.map +1 -1
- package/dist/compiler/runtime/localize-url.test.js +139 -0
- package/dist/compiler/runtime/localize-url.test.js.map +1 -1
- package/dist/compiler/runtime/normalize-trailing-slash.d.ts +10 -0
- package/dist/compiler/runtime/normalize-trailing-slash.js +23 -0
- package/dist/compiler/runtime/normalize-trailing-slash.js.map +1 -0
- package/dist/compiler/runtime/route-strategy.js +4 -2
- package/dist/compiler/runtime/route-strategy.js.map +1 -1
- package/dist/compiler/runtime/should-redirect.js +4 -1
- package/dist/compiler/runtime/should-redirect.js.map +1 -1
- package/dist/compiler/runtime/should-redirect.test.js +26 -2
- package/dist/compiler/runtime/should-redirect.test.js.map +1 -1
- package/dist/compiler/runtime/type.d.ts +1 -0
- package/dist/compiler/runtime/type.js.map +1 -1
- package/dist/compiler/runtime/url-pattern.d.ts +11 -0
- package/dist/compiler/runtime/url-pattern.js +39 -1
- package/dist/compiler/runtime/url-pattern.js.map +1 -1
- package/dist/compiler/runtime/variables.d.ts +9 -3
- package/dist/compiler/runtime/variables.js +7 -1
- package/dist/compiler/runtime/variables.js.map +1 -1
- package/dist/compiler/server/create-server-file.js +18 -4
- package/dist/compiler/server/create-server-file.js.map +1 -1
- package/dist/compiler/server/create-server-file.test.js +76 -0
- package/dist/compiler/server/create-server-file.test.js.map +1 -1
- package/dist/compiler/server/middleware.js +6 -2
- package/dist/compiler/server/middleware.js.map +1 -1
- package/dist/compiler/server/middleware.test.js +30 -0
- package/dist/compiler/server/middleware.test.js.map +1 -1
- package/dist/compiler/strip-jsdoc.d.ts +9 -0
- package/dist/compiler/strip-jsdoc.js +19 -0
- package/dist/compiler/strip-jsdoc.js.map +1 -0
- package/dist/compiler/strip-jsdoc.test.d.ts +1 -0
- package/dist/compiler/strip-jsdoc.test.js +95 -0
- package/dist/compiler/strip-jsdoc.test.js.map +1 -0
- package/dist/compiler/variable-access.d.ts +2 -0
- package/dist/compiler/variable-access.js +6 -0
- package/dist/compiler/variable-access.js.map +1 -1
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +9 -0
- package/dist/index.test.js.map +1 -0
- package/dist/messages/load-messages.js +4 -5
- package/dist/messages/load-messages.js.map +1 -1
- package/dist/services/env-variables/index.js +1 -1
- package/dist/services/env-variables/index.js.map +1 -1
- package/dist/services/file-handling/write-output.bench.d.ts +1 -0
- package/dist/services/file-handling/write-output.bench.js +24 -0
- package/dist/services/file-handling/write-output.bench.js.map +1 -0
- package/dist/services/file-handling/write-output.d.ts +5 -0
- package/dist/services/file-handling/write-output.js +54 -9
- package/dist/services/file-handling/write-output.js.map +1 -1
- package/dist/services/file-handling/write-output.test.js +27 -0
- package/dist/services/file-handling/write-output.test.js.map +1 -1
- package/dist/services/logger/index.js +2 -0
- package/dist/services/logger/index.js.map +1 -1
- package/package.json +86 -86
|
@@ -47,6 +47,122 @@ test("pathname based localization", async () => {
|
|
|
47
47
|
expect(runtime.localizeUrl("https://example.com/blog/56", { locale: "de" }).href).toBe("https://example.com/de/artikel/56");
|
|
48
48
|
expect(runtime.deLocalizeUrl("https://example.com/de/artikel/56").href).toBe("https://example.com/blog/56");
|
|
49
49
|
});
|
|
50
|
+
// https://github.com/opral/paraglide-js/issues/473
|
|
51
|
+
test("normalizes trailing slashes before matching translated pathnames", async () => {
|
|
52
|
+
const runtime = await createParaglide({
|
|
53
|
+
baseLocale: "en",
|
|
54
|
+
locales: ["en", "de"],
|
|
55
|
+
strategy: ["url", "baseLocale"],
|
|
56
|
+
trailingSlash: "never",
|
|
57
|
+
urlPatterns: [
|
|
58
|
+
{
|
|
59
|
+
pattern: "/",
|
|
60
|
+
localized: [
|
|
61
|
+
["de", "/de"],
|
|
62
|
+
["en", "/"],
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
pattern: "/about",
|
|
67
|
+
localized: [
|
|
68
|
+
["de", "/de/ueber"],
|
|
69
|
+
["en", "/about"],
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
});
|
|
74
|
+
expect(runtime.trailingSlash).toBe("never");
|
|
75
|
+
expect("normalizeTrailingSlash" in runtime).toBe(false);
|
|
76
|
+
expect("execUrlPattern" in runtime).toBe(false);
|
|
77
|
+
expect(runtime.extractLocaleFromUrl("https://example.com/de/")).toBe("de");
|
|
78
|
+
expect(runtime.extractLocaleFromUrl("https://example.com/de/ueber/")).toBe("de");
|
|
79
|
+
expect(runtime.deLocalizeUrl("https://example.com/de/").href).toBe("https://example.com/");
|
|
80
|
+
expect(runtime.deLocalizeUrl("https://example.com/de/ueber/").href).toBe("https://example.com/about");
|
|
81
|
+
expect(runtime.localizeUrl("https://example.com/about/", { locale: "de" }).href).toBe("https://example.com/de/ueber");
|
|
82
|
+
expect(runtime.localizeUrl("https://example.com/about/?ref=docs#section", {
|
|
83
|
+
locale: "de",
|
|
84
|
+
}).href).toBe("https://example.com/de/ueber?ref=docs#section");
|
|
85
|
+
});
|
|
86
|
+
test("adds trailing slashes when configured", async () => {
|
|
87
|
+
const runtime = await createParaglide({
|
|
88
|
+
baseLocale: "en",
|
|
89
|
+
locales: ["en", "de"],
|
|
90
|
+
strategy: ["url"],
|
|
91
|
+
trailingSlash: "always",
|
|
92
|
+
urlPatterns: [
|
|
93
|
+
{
|
|
94
|
+
// Existing patterns do not need to be rewritten for the policy.
|
|
95
|
+
pattern: "/about",
|
|
96
|
+
localized: [
|
|
97
|
+
["de", "/de/ueber"],
|
|
98
|
+
["en", "/about"],
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
expect(runtime.localizeUrl("https://example.com/about", { locale: "de" }).href).toBe("https://example.com/de/ueber/");
|
|
104
|
+
expect(runtime.deLocalizeUrl("https://example.com/de/ueber").href).toBe("https://example.com/about/");
|
|
105
|
+
});
|
|
106
|
+
test("does not include a canonical trailing slash in wildcard captures", async () => {
|
|
107
|
+
const runtime = await createParaglide({
|
|
108
|
+
baseLocale: "en",
|
|
109
|
+
locales: ["en", "de"],
|
|
110
|
+
strategy: ["url"],
|
|
111
|
+
trailingSlash: "always",
|
|
112
|
+
urlPatterns: [
|
|
113
|
+
{
|
|
114
|
+
pattern: "/:path(.*)",
|
|
115
|
+
localized: [
|
|
116
|
+
["de", "/de/:path(.*)/details"],
|
|
117
|
+
["en", "/:path(.*)"],
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
expect(runtime.localizeUrl("https://example.com/foo", { locale: "de" }).href).toBe("https://example.com/de/foo/details/");
|
|
123
|
+
expect(runtime.deLocalizeUrl("https://example.com/de/foo/details").href).toBe("https://example.com/foo/");
|
|
124
|
+
});
|
|
125
|
+
test("keeps unmatched custom URLs unchanged", async () => {
|
|
126
|
+
const runtime = await createParaglide({
|
|
127
|
+
baseLocale: "en",
|
|
128
|
+
locales: ["en", "de"],
|
|
129
|
+
strategy: ["url"],
|
|
130
|
+
trailingSlash: "never",
|
|
131
|
+
urlPatterns: [
|
|
132
|
+
{
|
|
133
|
+
pattern: "/about",
|
|
134
|
+
localized: [
|
|
135
|
+
["en", "/about"],
|
|
136
|
+
["de", "/de/ueber"],
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
});
|
|
141
|
+
const input = new URL("https://example.com/assets/");
|
|
142
|
+
expect(runtime.localizeUrl(input, { locale: "de" })).toBe(input);
|
|
143
|
+
expect(runtime.deLocalizeUrl(input)).toBe(input);
|
|
144
|
+
expect(input.href).toBe("https://example.com/assets/");
|
|
145
|
+
});
|
|
146
|
+
test("omitting trailingSlash preserves exact custom pattern matching", async () => {
|
|
147
|
+
const runtime = await createParaglide({
|
|
148
|
+
baseLocale: "en",
|
|
149
|
+
locales: ["en", "de"],
|
|
150
|
+
strategy: ["url"],
|
|
151
|
+
urlPatterns: [
|
|
152
|
+
{
|
|
153
|
+
pattern: "/about",
|
|
154
|
+
localized: [
|
|
155
|
+
["en", "/about"],
|
|
156
|
+
["de", "/de/ueber"],
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
});
|
|
161
|
+
const input = new URL("https://example.com/de/ueber/");
|
|
162
|
+
expect(runtime.trailingSlash).toBeUndefined();
|
|
163
|
+
expect(runtime.extractLocaleFromUrl(input)).toBeUndefined();
|
|
164
|
+
expect(runtime.deLocalizeUrl(input)).toBe(input);
|
|
165
|
+
});
|
|
50
166
|
test("cross domain urls", async () => {
|
|
51
167
|
const runtime = await createParaglide({
|
|
52
168
|
baseLocale: "en",
|
|
@@ -396,6 +512,29 @@ test("defining no localized pattern leads to a fallthrough", async () => {
|
|
|
396
512
|
// doesn't delocalize because no localized pattern is defined
|
|
397
513
|
expect(runtime.deLocalizeUrl("https://example.com/de/specific-path").href).toBe("https://example.com/de/specific-path");
|
|
398
514
|
});
|
|
515
|
+
test("does not cache base-relative patterns containing protocol syntax", async () => {
|
|
516
|
+
const runtime = await createParaglide({
|
|
517
|
+
baseLocale: "en",
|
|
518
|
+
locales: ["en", "de"],
|
|
519
|
+
strategy: ["url"],
|
|
520
|
+
urlPatterns: [
|
|
521
|
+
{
|
|
522
|
+
pattern: "specific-path{/:value(https://.*)}?",
|
|
523
|
+
localized: [
|
|
524
|
+
["en", "specific-path{/:value(https://.*)}?"],
|
|
525
|
+
["de", "/de/specific-path"],
|
|
526
|
+
],
|
|
527
|
+
},
|
|
528
|
+
],
|
|
529
|
+
});
|
|
530
|
+
// Warm the pattern against one base path before using another base path.
|
|
531
|
+
expect(runtime.localizeUrl("https://example.com/a/specific-path", {
|
|
532
|
+
locale: "de",
|
|
533
|
+
}).href).toBe("https://example.com/de/specific-path");
|
|
534
|
+
expect(runtime.localizeUrl("https://example.com/b/specific-path", {
|
|
535
|
+
locale: "de",
|
|
536
|
+
}).href).toBe("https://example.com/de/specific-path");
|
|
537
|
+
});
|
|
399
538
|
// https://github.com/opral/inlang-paraglide-js/issues/456
|
|
400
539
|
test("routing to a 404 page", async () => {
|
|
401
540
|
const runtime = await createParaglide({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localize-url.test.js","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-url.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,IAAI,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;IAC9C,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ,gBAAgB;YAChB;gBACC,OAAO,EAAE,aAAa;gBACtB,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,aAAa,CAAC;oBACrB,CAAC,IAAI,EAAE,uBAAuB,CAAC;iBAC/B;aACD;YACD,YAAY;YACZ;gBACC,OAAO,EAAE,WAAW;gBACpB,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,WAAW,CAAC;oBACnB,CAAC,IAAI,EAAE,iBAAiB,CAAC;iBACzB;aACD;YACD,WAAW;YACX;gBACC,OAAO,EAAE,YAAY;gBACrB,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,eAAe,CAAC;oBACvB,CAAC,IAAI,EAAE,YAAY,CAAC;iBACpB;aACD;SACD;KACD,CAAC,CAAC;IAEH,sBAAsB;IACtB,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,0BAA0B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACtE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAEtC,sBAAsB;IACtB,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAEnC,sBAAsB;IACtB,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEpC,6BAA6B;IAC7B,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtE,2BAA2B,CAC3B,CAAC;IAEF,gBAAgB;IAChB,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,gCAAgC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC5E,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAEnD,MAAM,CACL,OAAO,CAAC,aAAa,CAAC,0CAA0C,CAAC,CAAC,IAAI,CACtE,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAEzC,qBAAqB;IACrB,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAE5C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,mCAAmC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAC3E,6BAA6B,CAC7B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;IACpC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ,iCAAiC;YACjC;gBACC,OAAO,EAAE,gCAAgC;gBACzC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,mCAAmC,CAAC;oBAC3C,CAAC,IAAI,EAAE,gCAAgC,CAAC;iBACxC;aACD;YACD,4BAA4B;YAC5B;gBACC,OAAO,EAAE,4BAA4B;gBACrC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,4BAA4B,CAAC;oBACpC,CAAC,IAAI,EAAE,+BAA+B,CAAC;iBACvC;aACD;SACD;KACD,CAAC,CAAC;IAEH,sDAAsD;IACtD,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC1E,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAE1C,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC1E,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,iCAAiC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACzE,8BAA8B,CAC9B,CAAC;IAEF,aAAa;IACb,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC1E,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,8BAA8B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC1E,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEpC,eAAe;IACf,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtE,2BAA2B,CAC3B,CAAC;IAEF,aAAa;IACb,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEpC,eAAe;IACf,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACnE,2BAA2B,CAC3B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;IAChC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;QAC3B,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ,kFAAkF;YAClF;gBACC,OAAO,EAAE,6BAA6B;gBACtC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,gCAAgC,CAAC;oBACxC,CAAC,IAAI,EAAE,6BAA6B,CAAC;iBACrC;aACD;YACD,mFAAmF;YACnF;gBACC,OAAO,EAAE,8BAA8B;gBACvC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,iCAAiC,CAAC;oBACzC,CAAC,IAAI,EAAE,8BAA8B,CAAC;iBACtC;aACD;YACD,8CAA8C;YAC9C;gBACC,OAAO,EAAE,4BAA4B;gBACrC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,+BAA+B,CAAC;oBACvC,CAAC,IAAI,EAAE,+BAA+B,CAAC;iBACvC;aACD;SACD;KACD,CAAC,CAAC;IACH,2CAA2C;IAC3C,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,4BAA4B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACxE,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAErC,iDAAiD;IACjD,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,4BAA4B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACxE,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IAExC,oCAAoC;IACpC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,+BAA+B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACvE,4BAA4B,CAC5B,CAAC;IAEF,kCAAkC;IAClC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAEtC,iCAAiC;IACjC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAEzC,kCAAkC;IAClC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACxE,6BAA6B,CAC7B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;IAClD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,4BAA4B;gBACrC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,4BAA4B,CAAC;oBACpC,CAAC,IAAI,EAAE,+BAA+B,CAAC;iBACvC;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAEjD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAC3D,8BAA8B,CAC9B,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;AAC3E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;IAC1C,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,2CAA2C;gBACpD,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,8CAA8C,CAAC;oBACtD,CAAC,IAAI,EAAE,2CAA2C,CAAC;iBACnD;aACD;SACD;KACD,CAAC,CAAC;IAEH,OAAO;IACP,MAAM,CACL,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,gCAAgC,CAAC,CAAC,CAAC,IAAI,CACrE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAEtC,QAAQ;IACR,MAAM,CACL,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CACtE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,UAAU;IACV,MAAM,CACL,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CACjE,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAElC,YAAY;IACZ,MAAM,CACL,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAClE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAEtC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACzE,wBAAwB,CACxB,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAC5E,yBAAyB,CACzB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;IAChD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,gCAAgC;gBACzC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,mCAAmC,CAAC;oBAC3C,CAAC,IAAI,EAAE,gCAAgC,CAAC;iBACxC;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2CAA2C,EAAE;QAChE,MAAM,EAAE,IAAI;KACZ,CAAC,CAAC,IAAI,CACP,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;IAEvD,MAAM,CACL,OAAO,CAAC,aAAa,CAAC,8CAA8C,CAAC,CAAC,IAAI,CAC1E,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;IACxC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,gCAAgC;gBACzC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,mCAAmC,CAAC;oBAC3C,CAAC,IAAI,EAAE,gCAAgC,CAAC;iBACxC;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,gCAAgC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC5E,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAE5C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,mCAAmC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAC3E,gCAAgC,CAChC,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,2CAA2C;AAC3C,EAAE;AACF,0EAA0E;AAC1E,+DAA+D;AAC/D,2EAA2E;AAC3E,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;IACxC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,qBAAqB;gBAC9B,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,oBAAoB,CAAC;oBAC5B,CAAC,IAAI,EAAE,qBAAqB,CAAC;iBAC7B;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAEnC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAClE,2BAA2B,CAC3B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;IAC5D,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,gCAAgC;gBACzC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,mCAAmC,CAAC;oBAC3C,CAAC,IAAI,EAAE,mCAAmC,CAAC;iBAC3C;aACD;SACD;KACD,CAAC,CAAC;IAEH,sCAAsC;IACtC,OAAO,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAEvC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEvC,0DAA0D;IAC1D,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACjE,8BAA8B,CAC9B,CAAC;IAEF,iDAAiD;IACjD,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;IACjF,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,gCAAgC;gBACzC,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,mCAAmC,CAAC;oBAC3C,CAAC,IAAI,EAAE,gCAAgC,CAAC;iBACxC;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE;QAChD,MAAM,EAAE,IAAI;KACZ,CAAC,CAAC,IAAI,CACP,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,8BAA8B,EAAE;QACnD,MAAM,EAAE,IAAI;KACZ,CAAC,CAAC,IAAI,CACP,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,0DAA0D;AAC1D,IAAI,CAAC,IAAI,CAAC;IACT,yEAAyE;IACzE,EAAE;IACF,8CAA8C;IAC9C;QACC,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,2CAA2C;gBACpD,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,8CAA8C,CAAC;oBACtD,CAAC,IAAI,EAAE,2CAA2C,CAAC;iBAC7B;aACvB;SACD;KACD;CACD,CAAC,CAAC,qBAAqB,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;IACnD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,GAAG,eAAe;KAClB,CAAC,CAAC;IAEH,OAAO,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAEvC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACjE,2BAA2B,CAC3B,CAAC;IAEF,OAAO,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAEvC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAC5D,yBAAyB,CACzB,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACjE,8BAA8B,CAC9B,CAAC;IAEF,iDAAiD;IACjD,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE;QAChD,MAAM,EAAE,IAAW;KACnB,CAAC,CAAC,IAAI,CACP,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEpC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,8BAA8B,EAAE;QACnD,MAAM,EAAE,IAAW;KACnB,CAAC,CAAC,IAAI,CACP,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEpC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtE,2BAA2B,CAC3B,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACnE,2BAA2B,CAC3B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;IAC/C,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,aAAa;gBACtB,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,gBAAgB,CAAC;oBACxB,CAAC,IAAI,EAAE,aAAa,CAAC;iBACrB;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEpC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtE,2BAA2B,CAC3B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,0DAA0D;AAC1D,IAAI,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;IAC1D,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,aAAa;gBACtB,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,gBAAgB,CAAC;oBACxB,CAAC,IAAI,EAAE,gBAAgB,CAAC;iBACxB;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACjE,sBAAsB,CACtB,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAChE,sBAAsB,CACtB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,kFAAkF;AAClF,IAAI,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;IACrD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,QAAQ;gBACjB,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,QAAQ,CAAC;oBAChB,CAAC,IAAI,EAAE,QAAQ,CAAC;iBAChB;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,sBAAsB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAClE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAE/B,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAC9D,sBAAsB,CACtB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;IACvE,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,gBAAgB;gBACzB,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;aACrC;SACD;KACD,CAAC,CAAC;IAEH,2DAA2D;IAC3D,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,mCAAmC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SACxE,IAAI,CACN,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAE5C,6DAA6D;IAC7D,MAAM,CACL,OAAO,CAAC,aAAa,CAAC,sCAAsC,CAAC,CAAC,IAAI,CAClE,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,0DAA0D;AAC1D,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;IACxC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,MAAM;gBACf,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,MAAM,CAAC;oBACd,CAAC,IAAI,EAAE,SAAS,CAAC;iBACjB;aACD;YACD;gBACC,OAAO,EAAE,eAAe;gBACxB,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,gBAAgB,CAAC;oBACxB,CAAC,IAAI,EAAE,SAAS,CAAC;iBACjB;aACD;YACD;gBACC,OAAO,EAAE,aAAa;gBACtB,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,aAAa,CAAC;oBACrB,CAAC,IAAI,EAAE,gBAAgB,CAAC;iBACxB;aACD;SACD;KACD,CAAC,CAAC;IAEH,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,mCAAmC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SACxE,IAAI,CACN,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAE5C,2BAA2B;IAC3B,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,mCAAmC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SACxE,IAAI,CACN,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAErC,4CAA4C;IAC5C,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,gCAAgC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC5E,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEH,sEAAsE;AACtE,IAAI,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;IACpF,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,aAAa;gBACtB,SAAS,EAAE;oBACV,6CAA6C;oBAC7C,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,oCAAoC;oBAC9D,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,uCAAuC;iBAC9D;aACD;SACD;KACD,CAAC,CAAC;IAEH,mEAAmE;IACnE,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEpC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,2CAA2C;IAC3C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtE,2BAA2B,CAC3B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,sEAAsE;AACtE,IAAI,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;IACrF,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,OAAO,EAAE,aAAa;gBACtB,SAAS,EAAE;oBACV,+CAA+C;oBAC/C,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,uCAAuC;oBAC9D,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,yDAAyD;iBACnF;aACD;SACD;KACD,CAAC,CAAC;IAEH,yCAAyC;IACzC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEpC,4DAA4D;IAC5D,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAEvC,2CAA2C;IAC3C,wDAAwD;IACxD,qDAAqD;IACrD,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtE,8BAA8B,CAC9B,CAAC,CAAC,wCAAwC;AAC5C,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAC3E,IAAI,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;IAC1E,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,qEAAqE;gBACrE,OAAO,EAAE,kCAAkC;gBAC3C,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,qCAAqC,CAAC;oBAC7C,CAAC,IAAI,EAAE,kCAAkC,CAAC;iBAC1C;aACD;SACD;KACD,CAAC,CAAC;IAEH,qCAAqC;IACrC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAEzC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAEtC,uEAAuE;IACvE,oEAAoE;IACpE,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACxE,6BAA6B,CAC7B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,kEAAkE;AAClE,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;IACvE,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACrC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;QACrB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,WAAW,EAAE;YACZ;gBACC,0DAA0D;gBAC1D,OAAO,EAAE,mCAAmC;gBAC5C,SAAS,EAAE;oBACV,CAAC,IAAI,EAAE,sCAAsC,CAAC;oBAC9C,CAAC,IAAI,EAAE,mCAAmC,CAAC;iBAC3C;aACD;SACD;KACD,CAAC,CAAC;IAEH,qCAAqC;IACrC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAEzC,MAAM,CACL,OAAO,CAAC,WAAW,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAEtC,oEAAoE;IACpE,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACxE,6BAA6B,CAC7B,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["import { test, expect } from \"vitest\";\nimport { createParaglide } from \"../create-paraglide.js\";\n\ntest(\"pathname based localization\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t// literal match\n\t\t\t{\n\t\t\t\tpattern: \"/blog/about\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/blog/about\"],\n\t\t\t\t\t[\"de\", \"/de/artikel/ueber-uns\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// parameter\n\t\t\t{\n\t\t\t\tpattern: \"/blog/:id\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/blog/:id\"],\n\t\t\t\t\t[\"de\", \"/de/artikel/:id\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// wildcard\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/de/:path(.*)\"],\n\t\t\t\t\t[\"en\", \"/:path(.*)\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// wildcard - en to de\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/home\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/home\");\n\n\t// wildcard - de to en\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/de/home\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/home\");\n\n\t// wildcard - en to en\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\t// wildcard - delocalizing de\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\n\t// literal match\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/blog/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/artikel/ueber-uns\");\n\n\texpect(\n\t\truntime.deLocalizeUrl(\"https://example.com/de/artikel/ueber-uns\").href\n\t).toBe(\"https://example.com/blog/about\");\n\n\t// parameter matching\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/blog/56\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/artikel/56\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/artikel/56\").href).toBe(\n\t\t\"https://example.com/blog/56\"\n\t);\n});\n\ntest(\"cross domain urls\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t// Development/deployment mapping\n\t\t\t{\n\t\t\t\tpattern: \"https://localhost::port/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://localhost::port/de/:path*\"],\n\t\t\t\t\t[\"en\", \"https://localhost::port/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// Domain based localization\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/:path*\"],\n\t\t\t\t\t[\"de\", \"https://de.example.com/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// in development use localhost with different mapping\n\texpect(\n\t\truntime.localizeUrl(\"https://localhost:5173/about\", { locale: \"de\" }).href\n\t).toBe(\"https://localhost:5173/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://localhost:5173/about\", { locale: \"en\" }).href\n\t).toBe(\"https://localhost:5173/about\");\n\n\texpect(runtime.deLocalizeUrl(\"https://localhost:5173/de/about\").href).toBe(\n\t\t\"https://localhost:5173/about\"\n\t);\n\n\t// DE routing\n\texpect(\n\t\truntime.localizeUrl(\"https://de.example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://de.example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://de.example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\t// delocalizing\n\texpect(runtime.deLocalizeUrl(\"https://de.example.com/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\n\t// EN routing\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://de.example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\t// delocalizing\n\texpect(runtime.deLocalizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\ntest(\"multi tenancy\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t// 1) customer1.fr => root path locale is fr, other locales via sub-path e.g. /en/\n\t\t\t{\n\t\t\t\tpattern: \"https://customer1.fr/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://customer1.fr/en/:path*\"],\n\t\t\t\t\t[\"fr\", \"https://customer1.fr/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// 2) customer2.com => root path locale is en, other locales via sub-path e.g. /fr/\n\t\t\t{\n\t\t\t\tpattern: \"https://customer2.com/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"fr\", \"https://customer2.com/fr/:path*\"],\n\t\t\t\t\t[\"en\", \"https://customer2.com/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// 3) Any other domain => path-based for en/fr\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/en/:path*\"],\n\t\t\t\t\t[\"fr\", \"https://:domain(.*)/fr/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\t// customer 1 - localizing french to french\n\texpect(\n\t\truntime.localizeUrl(\"https://customer1.fr/about\", { locale: \"fr\" }).href\n\t).toBe(\"https://customer1.fr/about\");\n\n\t// customer 1 - localizing from french to english\n\texpect(\n\t\truntime.localizeUrl(\"https://customer1.fr/about\", { locale: \"en\" }).href\n\t).toBe(\"https://customer1.fr/en/about\");\n\n\t// customer 1 - de-localizing french\n\texpect(runtime.deLocalizeUrl(\"https://customer1.fr/en/about\").href).toBe(\n\t\t\"https://customer1.fr/about\"\n\t);\n\n\t// customer 2 - english to english\n\texpect(\n\t\truntime.localizeUrl(\"https://customer2.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://customer2.com/about\");\n\n\t// customer 2 - english to french\n\texpect(\n\t\truntime.localizeUrl(\"https://customer2.com/about\", { locale: \"fr\" }).href\n\t).toBe(\"https://customer2.com/fr/about\");\n\n\t// customer 2 - de-localize french\n\texpect(runtime.deLocalizeUrl(\"https://customer2.com/fr/about\").href).toBe(\n\t\t\"https://customer2.com/about\"\n\t);\n});\n\ntest(\"providing a URL object as input\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/:path*\"],\n\t\t\t\t\t[\"de\", \"https://de.:domain(.*)/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst url = new URL(\"https://example.com/about\");\n\n\texpect(runtime.localizeUrl(url, { locale: \"de\" }).href).toBe(\n\t\t\"https://de.example.com/about\"\n\t);\n\n\texpect(runtime.deLocalizeUrl(url).href).toBe(\"https://example.com/about\");\n});\n\ntest(\"localhost with portname\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \":protocol://:domain(.*)::port?/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \":protocol://:domain(.*)::port?/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \":protocol://:domain(.*)::port?/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// http\n\texpect(\n\t\truntime.deLocalizeUrl(new URL(\"http://localhost:5173/de/about\")).href\n\t).toBe(\"http://localhost:5173/about\");\n\n\t// https\n\texpect(\n\t\truntime.deLocalizeUrl(new URL(\"https://localhost:5173/de/about\")).href\n\t).toBe(\"https://localhost:5173/about\");\n\n\t// no port\n\texpect(\n\t\truntime.deLocalizeUrl(new URL(\"https://localhost/de/about\")).href\n\t).toBe(\"https://localhost/about\");\n\n\t// pathnames\n\texpect(\n\t\truntime.deLocalizeUrl(new URL(\"http://localhost:5173/about\")).href\n\t).toBe(\"http://localhost:5173/about\");\n\n\texpect(runtime.deLocalizeUrl(new URL(\"http://localhost:5173/\")).href).toBe(\n\t\t\"http://localhost:5173/\"\n\t);\n\n\texpect(runtime.deLocalizeUrl(new URL(\"https://localhost:5173/de\")).href).toBe(\n\t\t\"https://localhost:5173/\"\n\t);\n});\n\ntest(\"it keeps the query parameters\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about?foo=bar&baz=qux\", {\n\t\t\tlocale: \"de\",\n\t\t}).href\n\t).toBe(\"https://example.com/de/about?foo=bar&baz=qux\");\n\n\texpect(\n\t\truntime.deLocalizeUrl(\"https://example.com/de/about?foo=bar&baz=qux\").href\n\t).toBe(\"https://example.com/about?foo=bar&baz=qux\");\n});\n\ntest(\"it keeps the url hash\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about#test\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about#test\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about#test\").href).toBe(\n\t\t\"https://example.com/about#test\"\n\t);\n});\n\n// URL Pattern implicitly matches all paths\n//\n// The pattern https://example.com is interpreted as https://example.com.*\n// It effectively matches every path under https://example.com/\n// This means any request, including https://example.com/about, will match.\ntest(\"it keeps the url path\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://example.de\"],\n\t\t\t\t\t[\"en\", \"https://example.com\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.de/about\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\ntest(\"uses getLocale when no locale is provided\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/en/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Override getLocale to return German\n\truntime.overwriteGetLocale(() => \"de\");\n\n\texpect(runtime.getLocale()).toBe(\"de\");\n\n\t// Should use \"de\" from getLocale since no locale provided\n\texpect(runtime.localizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/de/about\"\n\t);\n\n\t// Should still use explicit locale when provided\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/en/about\");\n});\n\ntest(\"normalizes mixed-case explicit locales for custom url patterns\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", {\n\t\t\tlocale: \"DE\",\n\t\t}).href\n\t).toBe(\"https://example.com/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/de/about\", {\n\t\t\tlocale: \"EN\",\n\t\t}).href\n\t).toBe(\"https://example.com/about\");\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/381\ntest.each([\n\t// empty url pattern will set TREE_SHAKE_DEFAULT_ULR_PATTERN_USED to true\n\t{},\n\t// real default url pattern to align behaviour\n\t{\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \":protocol://:domain(.*)::port?/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \":protocol://:domain(.*)::port?/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \":protocol://:domain(.*)::port?/:path(.*)?\"],\n\t\t\t\t] as [string, string][],\n\t\t\t},\n\t\t],\n\t},\n])(\"default url pattern\", async (compilerOptions) => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\t...compilerOptions,\n\t});\n\n\truntime.overwriteGetLocale(() => \"en\");\n\n\texpect(runtime.localizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\n\truntime.overwriteGetLocale(() => \"de\");\n\n\texpect(runtime.localizeUrl(\"https://example.com/\").href).toBe(\n\t\t\"https://example.com/de/\"\n\t);\n\n\texpect(runtime.localizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/de/about\"\n\t);\n\n\t// Should still use explicit locale when provided\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", {\n\t\t\tlocale: \"DE\" as any,\n\t\t}).href\n\t).toBe(\"https://example.com/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/de/about\", {\n\t\t\tlocale: \"EN\" as any,\n\t\t}).href\n\t).toBe(\"https://example.com/about\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\ntest(\"auto fills the url base path\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/454\ntest(\"works with no trailing slash at the end\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/en/:path(.*)?\"],\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/en/\").href).toBe(\n\t\t\"https://example.com/\"\n\t);\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/en\").href).toBe(\n\t\t\"https://example.com/\"\n\t);\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/452#issuecomment-2715761308\ntest(\"falls through if no match is found\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/about\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/ueber\"],\n\t\t\t\t\t[\"en\", \"/about\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/\").href).toBe(\n\t\t\"https://example.com/\"\n\t);\n});\n\ntest(\"defining no localized pattern leads to a fallthrough\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/specific-path\",\n\t\t\t\tlocalized: [[\"en\", \"/specific-path\"]],\n\t\t\t},\n\t\t],\n\t});\n\n\t// doesn't localize because no localized pattern is defined\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/specific-path\", { locale: \"de\" })\n\t\t\t.href\n\t).toBe(\"https://example.com/specific-path\");\n\n\t// doesn't delocalize because no localized pattern is defined\n\texpect(\n\t\truntime.deLocalizeUrl(\"https://example.com/de/specific-path\").href\n\t).toBe(\"https://example.com/de/specific-path\");\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/456\ntest(\"routing to a 404 page\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/404\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/404\"],\n\t\t\t\t\t[\"de\", \"/de/404\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"specific-path\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/specific-path\"],\n\t\t\t\t\t[\"de\", \"/de/404\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/:path(.*)?\"],\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/specific-path\", { locale: \"en\" })\n\t\t\t.href\n\t).toBe(\"https://example.com/specific-path\");\n\n\t// localizing to a 404 page\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/specific-path\", { locale: \"de\" })\n\t\t\t.href\n\t).toBe(\"https://example.com/de/404\");\n\n\t// other paths work because of the catch all\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/other-path\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/other-path\");\n});\n\n// Test showing the importance of pattern order in the localized array\ntest(\"pattern order in localized array - correct order (specific first)\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t// CORRECT ORDER: more specific pattern first\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"], // More specific pattern with prefix\n\t\t\t\t\t[\"en\", \"/:path(.*)?\"], // Less specific pattern without prefix\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// These should work correctly with the specific (de) pattern first\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about\");\n\n\t// Delocalization should work correctly too\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\n// Test showing the importance of pattern order in the localized array\ntest(\"pattern order in localized array - incorrect order (generic first)\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t// INCORRECT ORDER: less specific pattern first\n\t\t\t\t\t[\"en\", \"/:path(.*)?\"], // Less specific pattern without prefix\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"], // More specific pattern with prefix that may never match\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// English localization works as expected\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\t// German localization still works when explicitly requested\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about\");\n\n\t// The problem happens with delocalization:\n\t// With incorrect pattern order, the generic /:path(.*)?\n\t// pattern matches first and swallows the /de/ prefix\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/de/about\"\n\t); // Should be \"https://example.com/about\"\n});\n\n// Test for port number issue with specific port numbers in the URL pattern\ntest(\"handles explicit port numbers in URL patterns correctly\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\t// Using explicit port number - this causes issues with deLocalizeUrl\n\t\t\t\tpattern: \"http://localhost:5173/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://localhost:5173/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://localhost:5173/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Localization should work correctly\n\texpect(\n\t\truntime.localizeUrl(\"http://localhost:5173/about\", { locale: \"de\" }).href\n\t).toBe(\"http://localhost:5173/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"http://localhost:5173/about\", { locale: \"en\" }).href\n\t).toBe(\"http://localhost:5173/about\");\n\n\t// This is where the bug occurs - delocalizing a URL with a port number\n\t// The port number (5173) is incorrectly treated as a path parameter\n\texpect(runtime.deLocalizeUrl(\"http://localhost:5173/de/about\").href).toBe(\n\t\t\"http://localhost:5173/about\"\n\t);\n});\n\n// Test for the correct approach using port as a pattern parameter\ntest(\"correctly handles port numbers as pattern parameters\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\t// Using port as a proper pattern parameter with :: syntax\n\t\t\t\tpattern: \"http://localhost::port/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://localhost::port/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://localhost::port/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Localization should work correctly\n\texpect(\n\t\truntime.localizeUrl(\"http://localhost:5173/about\", { locale: \"de\" }).href\n\t).toBe(\"http://localhost:5173/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"http://localhost:5173/about\", { locale: \"en\" }).href\n\t).toBe(\"http://localhost:5173/about\");\n\n\t// Delocalization should also work correctly with the proper pattern\n\texpect(runtime.deLocalizeUrl(\"http://localhost:5173/de/about\").href).toBe(\n\t\t\"http://localhost:5173/about\"\n\t);\n});\n"]}
|
|
1
|
+
{"version":3,"file":"localize-url.test.js","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-url.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"vitest\";\nimport { createParaglide } from \"../create-paraglide.js\";\n\ntest(\"pathname based localization\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t// literal match\n\t\t\t{\n\t\t\t\tpattern: \"/blog/about\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/blog/about\"],\n\t\t\t\t\t[\"de\", \"/de/artikel/ueber-uns\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// parameter\n\t\t\t{\n\t\t\t\tpattern: \"/blog/:id\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/blog/:id\"],\n\t\t\t\t\t[\"de\", \"/de/artikel/:id\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// wildcard\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/de/:path(.*)\"],\n\t\t\t\t\t[\"en\", \"/:path(.*)\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// wildcard - en to de\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/home\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/home\");\n\n\t// wildcard - de to en\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/de/home\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/home\");\n\n\t// wildcard - en to en\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\t// wildcard - delocalizing de\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\n\t// literal match\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/blog/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/artikel/ueber-uns\");\n\n\texpect(\n\t\truntime.deLocalizeUrl(\"https://example.com/de/artikel/ueber-uns\").href\n\t).toBe(\"https://example.com/blog/about\");\n\n\t// parameter matching\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/blog/56\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/artikel/56\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/artikel/56\").href).toBe(\n\t\t\"https://example.com/blog/56\"\n\t);\n});\n\n// https://github.com/opral/paraglide-js/issues/473\ntest(\"normalizes trailing slashes before matching translated pathnames\", 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: \"/\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/de\"],\n\t\t\t\t\t[\"en\", \"/\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"/about\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/de/ueber\"],\n\t\t\t\t\t[\"en\", \"/about\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(runtime.trailingSlash).toBe(\"never\");\n\texpect(\"normalizeTrailingSlash\" in runtime).toBe(false);\n\texpect(\"execUrlPattern\" in runtime).toBe(false);\n\texpect(runtime.extractLocaleFromUrl(\"https://example.com/de/\")).toBe(\"de\");\n\texpect(runtime.extractLocaleFromUrl(\"https://example.com/de/ueber/\")).toBe(\n\t\t\"de\"\n\t);\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/\").href).toBe(\n\t\t\"https://example.com/\"\n\t);\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/ueber/\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about/\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/ueber\");\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about/?ref=docs#section\", {\n\t\t\tlocale: \"de\",\n\t\t}).href\n\t).toBe(\"https://example.com/de/ueber?ref=docs#section\");\n});\n\ntest(\"adds trailing slashes when configured\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\ttrailingSlash: \"always\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\t// Existing patterns do not need to be rewritten for the policy.\n\t\t\t\tpattern: \"/about\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/de/ueber\"],\n\t\t\t\t\t[\"en\", \"/about\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/ueber/\");\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/ueber\").href).toBe(\n\t\t\"https://example.com/about/\"\n\t);\n});\n\ntest(\"does not include a canonical trailing slash in wildcard captures\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\ttrailingSlash: \"always\",\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/de/:path(.*)/details\"],\n\t\t\t\t\t[\"en\", \"/:path(.*)\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/foo\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/foo/details/\");\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/foo/details\").href).toBe(\n\t\t\"https://example.com/foo/\"\n\t);\n});\n\ntest(\"keeps unmatched custom URLs unchanged\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\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 input = new URL(\"https://example.com/assets/\");\n\texpect(runtime.localizeUrl(input, { locale: \"de\" })).toBe(input);\n\texpect(runtime.deLocalizeUrl(input)).toBe(input);\n\texpect(input.href).toBe(\"https://example.com/assets/\");\n});\n\ntest(\"omitting trailingSlash preserves exact custom pattern matching\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\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 input = new URL(\"https://example.com/de/ueber/\");\n\texpect(runtime.trailingSlash).toBeUndefined();\n\texpect(runtime.extractLocaleFromUrl(input)).toBeUndefined();\n\texpect(runtime.deLocalizeUrl(input)).toBe(input);\n});\n\ntest(\"cross domain urls\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t// Development/deployment mapping\n\t\t\t{\n\t\t\t\tpattern: \"https://localhost::port/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://localhost::port/de/:path*\"],\n\t\t\t\t\t[\"en\", \"https://localhost::port/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// Domain based localization\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/:path*\"],\n\t\t\t\t\t[\"de\", \"https://de.example.com/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// in development use localhost with different mapping\n\texpect(\n\t\truntime.localizeUrl(\"https://localhost:5173/about\", { locale: \"de\" }).href\n\t).toBe(\"https://localhost:5173/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://localhost:5173/about\", { locale: \"en\" }).href\n\t).toBe(\"https://localhost:5173/about\");\n\n\texpect(runtime.deLocalizeUrl(\"https://localhost:5173/de/about\").href).toBe(\n\t\t\"https://localhost:5173/about\"\n\t);\n\n\t// DE routing\n\texpect(\n\t\truntime.localizeUrl(\"https://de.example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://de.example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://de.example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\t// delocalizing\n\texpect(runtime.deLocalizeUrl(\"https://de.example.com/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\n\t// EN routing\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://de.example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\t// delocalizing\n\texpect(runtime.deLocalizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\ntest(\"multi tenancy\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t// 1) customer1.fr => root path locale is fr, other locales via sub-path e.g. /en/\n\t\t\t{\n\t\t\t\tpattern: \"https://customer1.fr/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://customer1.fr/en/:path*\"],\n\t\t\t\t\t[\"fr\", \"https://customer1.fr/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// 2) customer2.com => root path locale is en, other locales via sub-path e.g. /fr/\n\t\t\t{\n\t\t\t\tpattern: \"https://customer2.com/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"fr\", \"https://customer2.com/fr/:path*\"],\n\t\t\t\t\t[\"en\", \"https://customer2.com/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t// 3) Any other domain => path-based for en/fr\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/en/:path*\"],\n\t\t\t\t\t[\"fr\", \"https://:domain(.*)/fr/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\t// customer 1 - localizing french to french\n\texpect(\n\t\truntime.localizeUrl(\"https://customer1.fr/about\", { locale: \"fr\" }).href\n\t).toBe(\"https://customer1.fr/about\");\n\n\t// customer 1 - localizing from french to english\n\texpect(\n\t\truntime.localizeUrl(\"https://customer1.fr/about\", { locale: \"en\" }).href\n\t).toBe(\"https://customer1.fr/en/about\");\n\n\t// customer 1 - de-localizing french\n\texpect(runtime.deLocalizeUrl(\"https://customer1.fr/en/about\").href).toBe(\n\t\t\"https://customer1.fr/about\"\n\t);\n\n\t// customer 2 - english to english\n\texpect(\n\t\truntime.localizeUrl(\"https://customer2.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://customer2.com/about\");\n\n\t// customer 2 - english to french\n\texpect(\n\t\truntime.localizeUrl(\"https://customer2.com/about\", { locale: \"fr\" }).href\n\t).toBe(\"https://customer2.com/fr/about\");\n\n\t// customer 2 - de-localize french\n\texpect(runtime.deLocalizeUrl(\"https://customer2.com/fr/about\").href).toBe(\n\t\t\"https://customer2.com/about\"\n\t);\n});\n\ntest(\"providing a URL object as input\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path*\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/:path*\"],\n\t\t\t\t\t[\"de\", \"https://de.:domain(.*)/:path*\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst url = new URL(\"https://example.com/about\");\n\n\texpect(runtime.localizeUrl(url, { locale: \"de\" }).href).toBe(\n\t\t\"https://de.example.com/about\"\n\t);\n\n\texpect(runtime.deLocalizeUrl(url).href).toBe(\"https://example.com/about\");\n});\n\ntest(\"localhost with portname\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \":protocol://:domain(.*)::port?/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \":protocol://:domain(.*)::port?/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \":protocol://:domain(.*)::port?/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// http\n\texpect(\n\t\truntime.deLocalizeUrl(new URL(\"http://localhost:5173/de/about\")).href\n\t).toBe(\"http://localhost:5173/about\");\n\n\t// https\n\texpect(\n\t\truntime.deLocalizeUrl(new URL(\"https://localhost:5173/de/about\")).href\n\t).toBe(\"https://localhost:5173/about\");\n\n\t// no port\n\texpect(\n\t\truntime.deLocalizeUrl(new URL(\"https://localhost/de/about\")).href\n\t).toBe(\"https://localhost/about\");\n\n\t// pathnames\n\texpect(\n\t\truntime.deLocalizeUrl(new URL(\"http://localhost:5173/about\")).href\n\t).toBe(\"http://localhost:5173/about\");\n\n\texpect(runtime.deLocalizeUrl(new URL(\"http://localhost:5173/\")).href).toBe(\n\t\t\"http://localhost:5173/\"\n\t);\n\n\texpect(runtime.deLocalizeUrl(new URL(\"https://localhost:5173/de\")).href).toBe(\n\t\t\"https://localhost:5173/\"\n\t);\n});\n\ntest(\"it keeps the query parameters\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about?foo=bar&baz=qux\", {\n\t\t\tlocale: \"de\",\n\t\t}).href\n\t).toBe(\"https://example.com/de/about?foo=bar&baz=qux\");\n\n\texpect(\n\t\truntime.deLocalizeUrl(\"https://example.com/de/about?foo=bar&baz=qux\").href\n\t).toBe(\"https://example.com/about?foo=bar&baz=qux\");\n});\n\ntest(\"it keeps the url hash\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about#test\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about#test\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about#test\").href).toBe(\n\t\t\"https://example.com/about#test\"\n\t);\n});\n\n// URL Pattern implicitly matches all paths\n//\n// The pattern https://example.com is interpreted as https://example.com.*\n// It effectively matches every path under https://example.com/\n// This means any request, including https://example.com/about, will match.\ntest(\"it keeps the url path\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://example.com\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://example.de\"],\n\t\t\t\t\t[\"en\", \"https://example.com\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.de/about\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\ntest(\"uses getLocale when no locale is provided\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/en/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Override getLocale to return German\n\truntime.overwriteGetLocale(() => \"de\");\n\n\texpect(runtime.getLocale()).toBe(\"de\");\n\n\t// Should use \"de\" from getLocale since no locale provided\n\texpect(runtime.localizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/de/about\"\n\t);\n\n\t// Should still use explicit locale when provided\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/en/about\");\n});\n\ntest(\"normalizes mixed-case explicit locales for custom url patterns\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"https://:domain(.*)/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"https://:domain(.*)/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"https://:domain(.*)/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", {\n\t\t\tlocale: \"DE\",\n\t\t}).href\n\t).toBe(\"https://example.com/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/de/about\", {\n\t\t\tlocale: \"EN\",\n\t\t}).href\n\t).toBe(\"https://example.com/about\");\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/381\ntest.each([\n\t// empty url pattern will set TREE_SHAKE_DEFAULT_ULR_PATTERN_USED to true\n\t{},\n\t// real default url pattern to align behaviour\n\t{\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \":protocol://:domain(.*)::port?/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \":protocol://:domain(.*)::port?/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \":protocol://:domain(.*)::port?/:path(.*)?\"],\n\t\t\t\t] as [string, string][],\n\t\t\t},\n\t\t],\n\t},\n])(\"default url pattern\", async (compilerOptions) => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\t...compilerOptions,\n\t});\n\n\truntime.overwriteGetLocale(() => \"en\");\n\n\texpect(runtime.localizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\n\truntime.overwriteGetLocale(() => \"de\");\n\n\texpect(runtime.localizeUrl(\"https://example.com/\").href).toBe(\n\t\t\"https://example.com/de/\"\n\t);\n\n\texpect(runtime.localizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/de/about\"\n\t);\n\n\t// Should still use explicit locale when provided\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", {\n\t\t\tlocale: \"DE\" as any,\n\t\t}).href\n\t).toBe(\"https://example.com/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/de/about\", {\n\t\t\tlocale: \"EN\" as any,\n\t\t}).href\n\t).toBe(\"https://example.com/about\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\ntest(\"auto fills the url base path\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/454\ntest(\"works with no trailing slash at the end\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/en/:path(.*)?\"],\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/en/\").href).toBe(\n\t\t\"https://example.com/\"\n\t);\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/en\").href).toBe(\n\t\t\"https://example.com/\"\n\t);\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/452#issuecomment-2715761308\ntest(\"falls through if no match is found\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/about\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"/ueber\"],\n\t\t\t\t\t[\"en\", \"/about\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/\");\n\n\texpect(runtime.deLocalizeUrl(\"https://example.com/\").href).toBe(\n\t\t\"https://example.com/\"\n\t);\n});\n\ntest(\"defining no localized pattern leads to a fallthrough\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/specific-path\",\n\t\t\t\tlocalized: [[\"en\", \"/specific-path\"]],\n\t\t\t},\n\t\t],\n\t});\n\n\t// doesn't localize because no localized pattern is defined\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/specific-path\", { locale: \"de\" })\n\t\t\t.href\n\t).toBe(\"https://example.com/specific-path\");\n\n\t// doesn't delocalize because no localized pattern is defined\n\texpect(\n\t\truntime.deLocalizeUrl(\"https://example.com/de/specific-path\").href\n\t).toBe(\"https://example.com/de/specific-path\");\n});\n\ntest(\"does not cache base-relative patterns containing protocol syntax\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"specific-path{/:value(https://.*)}?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"specific-path{/:value(https://.*)}?\"],\n\t\t\t\t\t[\"de\", \"/de/specific-path\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Warm the pattern against one base path before using another base path.\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/a/specific-path\", {\n\t\t\tlocale: \"de\",\n\t\t}).href\n\t).toBe(\"https://example.com/de/specific-path\");\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/b/specific-path\", {\n\t\t\tlocale: \"de\",\n\t\t}).href\n\t).toBe(\"https://example.com/de/specific-path\");\n});\n\n// https://github.com/opral/inlang-paraglide-js/issues/456\ntest(\"routing to a 404 page\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/404\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/404\"],\n\t\t\t\t\t[\"de\", \"/de/404\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"specific-path\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/specific-path\"],\n\t\t\t\t\t[\"de\", \"/de/404\"],\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"en\", \"/:path(.*)?\"],\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/specific-path\", { locale: \"en\" })\n\t\t\t.href\n\t).toBe(\"https://example.com/specific-path\");\n\n\t// localizing to a 404 page\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/specific-path\", { locale: \"de\" })\n\t\t\t.href\n\t).toBe(\"https://example.com/de/404\");\n\n\t// other paths work because of the catch all\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/other-path\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/other-path\");\n});\n\n// Test showing the importance of pattern order in the localized array\ntest(\"pattern order in localized array - correct order (specific first)\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t// CORRECT ORDER: more specific pattern first\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"], // More specific pattern with prefix\n\t\t\t\t\t[\"en\", \"/:path(.*)?\"], // Less specific pattern without prefix\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// These should work correctly with the specific (de) pattern first\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about\");\n\n\t// Delocalization should work correctly too\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/about\"\n\t);\n});\n\n// Test showing the importance of pattern order in the localized array\ntest(\"pattern order in localized array - incorrect order (generic first)\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\tpattern: \"/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t// INCORRECT ORDER: less specific pattern first\n\t\t\t\t\t[\"en\", \"/:path(.*)?\"], // Less specific pattern without prefix\n\t\t\t\t\t[\"de\", \"/de/:path(.*)?\"], // More specific pattern with prefix that may never match\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// English localization works as expected\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"en\" }).href\n\t).toBe(\"https://example.com/about\");\n\n\t// German localization still works when explicitly requested\n\texpect(\n\t\truntime.localizeUrl(\"https://example.com/about\", { locale: \"de\" }).href\n\t).toBe(\"https://example.com/de/about\");\n\n\t// The problem happens with delocalization:\n\t// With incorrect pattern order, the generic /:path(.*)?\n\t// pattern matches first and swallows the /de/ prefix\n\texpect(runtime.deLocalizeUrl(\"https://example.com/de/about\").href).toBe(\n\t\t\"https://example.com/de/about\"\n\t); // Should be \"https://example.com/about\"\n});\n\n// Test for port number issue with specific port numbers in the URL pattern\ntest(\"handles explicit port numbers in URL patterns correctly\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\t// Using explicit port number - this causes issues with deLocalizeUrl\n\t\t\t\tpattern: \"http://localhost:5173/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://localhost:5173/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://localhost:5173/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Localization should work correctly\n\texpect(\n\t\truntime.localizeUrl(\"http://localhost:5173/about\", { locale: \"de\" }).href\n\t).toBe(\"http://localhost:5173/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"http://localhost:5173/about\", { locale: \"en\" }).href\n\t).toBe(\"http://localhost:5173/about\");\n\n\t// This is where the bug occurs - delocalizing a URL with a port number\n\t// The port number (5173) is incorrectly treated as a path parameter\n\texpect(runtime.deLocalizeUrl(\"http://localhost:5173/de/about\").href).toBe(\n\t\t\"http://localhost:5173/about\"\n\t);\n});\n\n// Test for the correct approach using port as a pattern parameter\ntest(\"correctly handles port numbers as pattern parameters\", async () => {\n\tconst runtime = await createParaglide({\n\t\tbaseLocale: \"en\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tstrategy: [\"url\"],\n\t\turlPatterns: [\n\t\t\t{\n\t\t\t\t// Using port as a proper pattern parameter with :: syntax\n\t\t\t\tpattern: \"http://localhost::port/:path(.*)?\",\n\t\t\t\tlocalized: [\n\t\t\t\t\t[\"de\", \"http://localhost::port/de/:path(.*)?\"],\n\t\t\t\t\t[\"en\", \"http://localhost::port/:path(.*)?\"],\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\t// Localization should work correctly\n\texpect(\n\t\truntime.localizeUrl(\"http://localhost:5173/about\", { locale: \"de\" }).href\n\t).toBe(\"http://localhost:5173/de/about\");\n\n\texpect(\n\t\truntime.localizeUrl(\"http://localhost:5173/about\", { locale: \"en\" }).href\n\t).toBe(\"http://localhost:5173/about\");\n\n\t// Delocalization should also work correctly with the proper pattern\n\texpect(runtime.deLocalizeUrl(\"http://localhost:5173/de/about\").href).toBe(\n\t\t\"http://localhost:5173/about\"\n\t);\n});\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applies the configured trailing slash policy to a URL.
|
|
3
|
+
*
|
|
4
|
+
* The root pathname always remains `/`. Query parameters and hashes are not
|
|
5
|
+
* modified.
|
|
6
|
+
*
|
|
7
|
+
* @param {URL} url
|
|
8
|
+
* @returns {URL}
|
|
9
|
+
*/
|
|
10
|
+
export declare function normalizeTrailingSlash(url: URL): URL;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { trailingSlash } from "./variables.js";
|
|
2
|
+
/**
|
|
3
|
+
* Applies the configured trailing slash policy to a URL.
|
|
4
|
+
*
|
|
5
|
+
* The root pathname always remains `/`. Query parameters and hashes are not
|
|
6
|
+
* modified.
|
|
7
|
+
*
|
|
8
|
+
* @param {URL} url
|
|
9
|
+
* @returns {URL}
|
|
10
|
+
*/
|
|
11
|
+
export function normalizeTrailingSlash(url) {
|
|
12
|
+
if (trailingSlash === undefined || url.pathname === "/") {
|
|
13
|
+
return url;
|
|
14
|
+
}
|
|
15
|
+
if (trailingSlash === "never") {
|
|
16
|
+
url.pathname = url.pathname.replace(/\/+$/, "") || "/";
|
|
17
|
+
}
|
|
18
|
+
else if (trailingSlash === "always") {
|
|
19
|
+
url.pathname = url.pathname.replace(/\/+$/, "") + "/";
|
|
20
|
+
}
|
|
21
|
+
return url;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=normalize-trailing-slash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-trailing-slash.js","sourceRoot":"","sources":["../../../src/compiler/runtime/normalize-trailing-slash.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAG;IACzC,IAAI,aAAa,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;QACzD,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;QAC/B,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;IACxD,CAAC;SAAM,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;QACvC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC;IACvD,CAAC;IAED,OAAO,GAAG,CAAC;AACZ,CAAC","sourcesContent":["import { trailingSlash } from \"./variables.js\";\n\n/**\n * Applies the configured trailing slash policy to a URL.\n *\n * The root pathname always remains `/`. Query parameters and hashes are not\n * modified.\n *\n * @param {URL} url\n * @returns {URL}\n */\nexport function normalizeTrailingSlash(url) {\n\tif (trailingSlash === undefined || url.pathname === \"/\") {\n\t\treturn url;\n\t}\n\n\tif (trailingSlash === \"never\") {\n\t\turl.pathname = url.pathname.replace(/\\/+$/, \"\") || \"/\";\n\t} else if (trailingSlash === \"always\") {\n\t\turl.pathname = url.pathname.replace(/\\/+$/, \"\") + \"/\";\n\t}\n\n\treturn url;\n}\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { deLocalizeUrl } from "./localize-url.js";
|
|
2
|
+
import { normalizeTrailingSlash } from "./normalize-trailing-slash.js";
|
|
3
|
+
import { execUrlPattern } from "./exec-url-pattern.js";
|
|
2
4
|
import { routeStrategies, strategy } from "./variables.js";
|
|
3
5
|
/** @type {string | undefined} */
|
|
4
6
|
let cachedRouteStrategyUrl;
|
|
@@ -21,7 +23,7 @@ export function findMatchingRouteStrategy(url) {
|
|
|
21
23
|
if (cachedRouteStrategyUrl === urlString) {
|
|
22
24
|
return cachedRouteStrategy;
|
|
23
25
|
}
|
|
24
|
-
const publicUrl = new URL(urlString, "http://example.com");
|
|
26
|
+
const publicUrl = normalizeTrailingSlash(new URL(urlString, "http://example.com"));
|
|
25
27
|
const canonicalUrl = deLocalizeUrl(publicUrl);
|
|
26
28
|
const candidateUrls = canonicalUrl.href === publicUrl.href
|
|
27
29
|
? [publicUrl]
|
|
@@ -30,7 +32,7 @@ export function findMatchingRouteStrategy(url) {
|
|
|
30
32
|
for (const candidateUrl of candidateUrls) {
|
|
31
33
|
for (const routeStrategy of routeStrategies) {
|
|
32
34
|
const pattern = new URLPattern(routeStrategy.match, candidateUrl.href);
|
|
33
|
-
if (pattern
|
|
35
|
+
if (execUrlPattern(pattern, candidateUrl)) {
|
|
34
36
|
match = routeStrategy;
|
|
35
37
|
break;
|
|
36
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-strategy.js","sourceRoot":"","sources":["../../../src/compiler/runtime/route-strategy.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE3D,iCAAiC;AACjC,IAAI,sBAAsB,CAAC;AAC3B,2FAA2F;AAC3F,IAAI,mBAAmB,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAG;IAC5C,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC3D,IAAI,sBAAsB,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,mBAAmB,CAAC;IAC5B,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"route-strategy.js","sourceRoot":"","sources":["../../../src/compiler/runtime/route-strategy.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE3D,iCAAiC;AACjC,IAAI,sBAAsB,CAAC;AAC3B,2FAA2F;AAC3F,IAAI,mBAAmB,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAG;IAC5C,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC3D,IAAI,sBAAsB,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,mBAAmB,CAAC;IAC5B,CAAC;IAED,MAAM,SAAS,GAAG,sBAAsB,CACvC,IAAI,GAAG,CAAC,SAAS,EAAE,oBAAoB,CAAC,CACxC,CAAC;IACF,MAAM,YAAY,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,aAAa,GAClB,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;QACnC,CAAC,CAAC,CAAC,SAAS,CAAC;QACb,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC;IACV,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QAC1C,KAAK,MAAM,aAAa,IAAI,eAAe,EAAE,CAAC;YAC7C,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;YACvE,IAAI,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;gBAC3C,KAAK,GAAG,aAAa,CAAC;gBACtB,MAAM;YACP,CAAC;QACF,CAAC;QACD,IAAI,KAAK;YAAE,MAAM;IAClB,CAAC;IAED,sBAAsB,GAAG,SAAS,CAAC;IACnC,mBAAmB,GAAG,KAAK,CAAC;IAC5B,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG;IACpC,MAAM,aAAa,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;IACrD,IACC,aAAa;QACb,aAAa,CAAC,OAAO,KAAK,IAAI;QAC9B,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,EACpC,CAAC;QACF,OAAO,aAAa,CAAC,QAAQ,CAAC;IAC/B,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAG;IAC5C,OAAO,yBAAyB,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AACzD,CAAC","sourcesContent":["import { deLocalizeUrl } from \"./localize-url.js\";\nimport { normalizeTrailingSlash } from \"./normalize-trailing-slash.js\";\nimport { execUrlPattern } from \"./exec-url-pattern.js\";\nimport { routeStrategies, strategy } from \"./variables.js\";\n\n/** @type {string | undefined} */\nlet cachedRouteStrategyUrl;\n/** @type {{ match: string; strategy?: typeof strategy; exclude?: boolean } | undefined} */\nlet cachedRouteStrategy;\n\n/**\n * Match route policy against both the public URL and its canonical URL.\n *\n * The function is deliberately separate from variables.js: configuration is\n * inert data, while canonicalization and route selection form a routing layer.\n *\n * @param {string | URL} url\n * @returns {{ match: string; strategy?: typeof strategy; exclude?: boolean } | undefined}\n */\nexport function findMatchingRouteStrategy(url) {\n\tif (routeStrategies.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tconst urlString = typeof url === \"string\" ? url : url.href;\n\tif (cachedRouteStrategyUrl === urlString) {\n\t\treturn cachedRouteStrategy;\n\t}\n\n\tconst publicUrl = normalizeTrailingSlash(\n\t\tnew URL(urlString, \"http://example.com\")\n\t);\n\tconst canonicalUrl = deLocalizeUrl(publicUrl);\n\tconst candidateUrls =\n\t\tcanonicalUrl.href === publicUrl.href\n\t\t\t? [publicUrl]\n\t\t\t: [publicUrl, canonicalUrl];\n\tlet match;\n\tfor (const candidateUrl of candidateUrls) {\n\t\tfor (const routeStrategy of routeStrategies) {\n\t\t\tconst pattern = new URLPattern(routeStrategy.match, candidateUrl.href);\n\t\t\tif (execUrlPattern(pattern, candidateUrl)) {\n\t\t\t\tmatch = routeStrategy;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (match) break;\n\t}\n\n\tcachedRouteStrategyUrl = urlString;\n\tcachedRouteStrategy = match;\n\treturn match;\n}\n\n/**\n * Returns the strategy to use for a specific URL.\n *\n * If no route strategy matches (or the matching rule is `exclude: true`),\n * the global strategy is returned.\n *\n * @param {string | URL} url\n * @returns {typeof strategy}\n */\nexport function getStrategyForUrl(url) {\n\tconst routeStrategy = findMatchingRouteStrategy(url);\n\tif (\n\t\trouteStrategy &&\n\t\trouteStrategy.exclude !== true &&\n\t\tArray.isArray(routeStrategy.strategy)\n\t) {\n\t\treturn routeStrategy.strategy;\n\t}\n\treturn strategy;\n}\n\n/**\n * Returns whether the given URL is excluded from middleware i18n processing.\n *\n * @param {string | URL} url\n * @returns {boolean}\n */\nexport function isExcludedByRouteStrategy(url) {\n\treturn findMatchingRouteStrategy(url)?.exclude === true;\n}\n"]}
|
|
@@ -4,6 +4,7 @@ import { getLocale, getLocaleForUrl } from "./get-locale.js";
|
|
|
4
4
|
import { getUrlOrigin } from "./get-url-origin.js";
|
|
5
5
|
import { extractLocaleFromRequestAsync } from "./extract-locale-from-request-async.js";
|
|
6
6
|
import { getStrategyForUrl, isExcludedByRouteStrategy, } from "./route-strategy.js";
|
|
7
|
+
import { trailingSlash } from "./variables.js";
|
|
7
8
|
/**
|
|
8
9
|
* @typedef {object} ShouldRedirectServerInput
|
|
9
10
|
* @property {Request} request
|
|
@@ -149,7 +150,9 @@ function resolveUrl(input) {
|
|
|
149
150
|
*/
|
|
150
151
|
function normalizeUrl(url) {
|
|
151
152
|
const urlObj = new URL(url);
|
|
152
|
-
|
|
153
|
+
if (trailingSlash === undefined) {
|
|
154
|
+
urlObj.pathname = urlObj.pathname.replace(/\/$/, "");
|
|
155
|
+
}
|
|
153
156
|
return urlObj.href;
|
|
154
157
|
}
|
|
155
158
|
//# sourceMappingURL=should-redirect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"should-redirect.js","sourceRoot":"","sources":["../../../src/compiler/runtime/should-redirect.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,6BAA6B,EAAE,MAAM,wCAAwC,CAAC;AACvF,OAAO,EACN,iBAAiB,EACjB,yBAAyB,GACzB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"should-redirect.js","sourceRoot":"","sources":["../../../src/compiler/runtime/should-redirect.js"],"names":[],"mappings":"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","sourcesContent":["import { localizeUrl } from \"./localize-url.js\";\nimport { toLocale } from \"./check-locale.js\";\nimport { getLocale, getLocaleForUrl } from \"./get-locale.js\";\nimport { getUrlOrigin } from \"./get-url-origin.js\";\nimport { extractLocaleFromRequestAsync } from \"./extract-locale-from-request-async.js\";\nimport {\n\tgetStrategyForUrl,\n\tisExcludedByRouteStrategy,\n} from \"./route-strategy.js\";\nimport { trailingSlash } from \"./variables.js\";\n\n/**\n * @typedef {object} ShouldRedirectServerInput\n * @property {Request} request\n * @property {string | URL} [effectiveRequestUrl] - Effective request URL to use for route matching, locale detection with the URL strategy, and redirect targets.\n * @property {Locale} [locale]\n *\n * @typedef {object} ShouldRedirectClientInput\n * @property {undefined} [request]\n * @property {string | URL} [url]\n * @property {Locale} [locale]\n *\n * @typedef {ShouldRedirectServerInput | ShouldRedirectClientInput} ShouldRedirectInput\n *\n * @typedef {object} ShouldRedirectResult\n * @property {boolean} shouldRedirect - Indicates whether the consumer should perform a redirect.\n * @property {Locale} locale - Locale resolved using the configured strategies.\n * @property {URL | undefined} redirectUrl - Destination URL when a redirect is required.\n */\n\n/**\n * Determines whether a redirect is required to align the current URL with the active locale.\n *\n * This helper mirrors the logic that powers `paraglideMiddleware`, but works in both server\n * and client environments. It evaluates the configured strategies in order, computes the\n * canonical localized URL, and reports when the current URL does not match.\n *\n * When called in the browser without arguments, the current `window.location.href` is used.\n *\n * @see https://paraglidejs.com/i18n-routing#redirects\n *\n * @example\n * // Client side usage (e.g. TanStack Router beforeLoad hook)\n * async function beforeLoad({ location }) {\n * const decision = await shouldRedirect({ url: location.href });\n *\n * if (decision.shouldRedirect) {\n * throw redirect({ to: decision.redirectUrl.href });\n * }\n * }\n *\n * @example\n * // Server side usage with a Request\n * export async function handle(request) {\n * const decision = await shouldRedirect({ request });\n *\n * if (decision.shouldRedirect) {\n * return Response.redirect(decision.redirectUrl, 307);\n * }\n *\n * return render(request, decision.locale);\n * }\n *\n * @example\n * // Server side usage behind a proxy where request.url is not public-facing\n * export async function handle(request) {\n * const effectiveRequestUrl = new URL(request.url);\n * effectiveRequestUrl.protocol = \"https:\";\n * effectiveRequestUrl.host = \"example.com\";\n *\n * const decision = await shouldRedirect({\n * request,\n * effectiveRequestUrl,\n * });\n *\n * if (decision.shouldRedirect) {\n * return Response.redirect(decision.redirectUrl, 307);\n * }\n * }\n *\n * @param {ShouldRedirectInput} [input]\n * @returns {Promise<ShouldRedirectResult>}\n */\nexport async function shouldRedirect(input = {}) {\n\tconst currentUrl = resolveUrl(input);\n\tconst locale = await resolveLocale(input, currentUrl);\n\tconst strategy = getStrategyForUrl(currentUrl.href);\n\n\tif (isExcludedByRouteStrategy(currentUrl.href) || !strategy.includes(\"url\")) {\n\t\treturn { shouldRedirect: false, locale, redirectUrl: undefined };\n\t}\n\n\tconst localizedUrl = localizeUrl(currentUrl.href, { locale });\n\n\tconst shouldRedirectToLocalizedUrl =\n\t\tnormalizeUrl(localizedUrl.href) !== normalizeUrl(currentUrl.href);\n\n\treturn {\n\t\tshouldRedirect: shouldRedirectToLocalizedUrl,\n\t\tlocale,\n\t\tredirectUrl: shouldRedirectToLocalizedUrl ? localizedUrl : undefined,\n\t};\n}\n\n/**\n * Resolves the locale either from the provided input or by using the configured strategies.\n *\n * @param {ShouldRedirectInput} input\n * @param {URL} currentUrl\n * @returns {Promise<Locale>}\n */\nasync function resolveLocale(input, currentUrl) {\n\tconst locale = toLocale(input.locale);\n\tif (locale) {\n\t\treturn locale;\n\t}\n\n\tif (input.request) {\n\t\treturn extractLocaleFromRequestAsync(input.request, {\n\t\t\teffectiveRequestUrl: currentUrl,\n\t\t});\n\t}\n\n\tif (\"url\" in input && typeof input.url !== \"undefined\") {\n\t\treturn getLocaleForUrl(currentUrl.href);\n\t}\n\n\treturn getLocale();\n}\n\n/**\n * Resolves the current URL from the provided input or runtime context.\n *\n * @param {ShouldRedirectInput} input\n * @returns {URL}\n */\nfunction resolveUrl(input) {\n\tif (\n\t\t\"effectiveRequestUrl\" in input &&\n\t\tinput.effectiveRequestUrl instanceof URL\n\t) {\n\t\treturn new URL(input.effectiveRequestUrl.href);\n\t}\n\n\tif (\n\t\t\"effectiveRequestUrl\" in input &&\n\t\ttypeof input.effectiveRequestUrl === \"string\"\n\t) {\n\t\treturn new URL(\n\t\t\tinput.effectiveRequestUrl,\n\t\t\tinput.request ? input.request.url : getUrlOrigin()\n\t\t);\n\t}\n\n\tif (input.request) {\n\t\treturn new URL(input.request.url);\n\t}\n\n\tif (\"url\" in input && input.url instanceof URL) {\n\t\treturn new URL(input.url.href);\n\t}\n\n\tif (\"url\" in input && typeof input.url === \"string\") {\n\t\treturn new URL(input.url, getUrlOrigin());\n\t}\n\n\tif (typeof window !== \"undefined\" && window?.location?.href) {\n\t\treturn new URL(window.location.href);\n\t}\n\n\tthrow new Error(\n\t\t\"shouldRedirect() requires either a request, an absolute URL, or must run in a browser environment.\"\n\t);\n}\n\n/**\n * Normalize url for comparison by stripping the trailing slash.\n *\n * @param {string} url\n * @returns {string}\n */\nfunction normalizeUrl(url) {\n\tconst urlObj = new URL(url);\n\tif (trailingSlash === undefined) {\n\t\turlObj.pathname = urlObj.pathname.replace(/\\/$/, \"\");\n\t}\n\treturn urlObj.href;\n}\n"]}
|