@inlang/paraglide-js 2.28.0 → 2.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,171 @@
1
+ import { afterEach, expect, test, vi } from "vitest";
2
+ import fs from "node:fs/promises";
3
+ import nodeFs from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import path from "node:path";
6
+ import { createServer } from "vite";
7
+ import { loadProjectInMemory, newProject, saveProjectToDirectory, } from "@inlang/sdk";
8
+ import { paraglideVitePlugin } from "./vite.js";
9
+ const cleanups = [];
10
+ const initialNodeEnv = process.env.NODE_ENV;
11
+ afterEach(async () => {
12
+ for (const cleanup of cleanups.splice(0).reverse())
13
+ await cleanup();
14
+ vi.restoreAllMocks();
15
+ if (initialNodeEnv === undefined)
16
+ delete process.env.NODE_ENV;
17
+ else
18
+ process.env.NODE_ENV = initialNodeEnv;
19
+ });
20
+ async function createFixture(options) {
21
+ process.env.NODE_ENV = "development";
22
+ const root = nodeFs.realpathSync(await fs.mkdtemp(path.join(tmpdir(), "paraglide-error-response-")));
23
+ cleanups.push(() => fs.rm(root, { recursive: true, force: true }));
24
+ const projectDir = path.join(root, "project.inlang");
25
+ const project = await loadProjectInMemory({
26
+ blob: await newProject({ settings: { baseLocale: "en", locales: ["en"] } }),
27
+ });
28
+ try {
29
+ await saveProjectToDirectory({ project, path: projectDir, fs });
30
+ }
31
+ finally {
32
+ await project.close();
33
+ }
34
+ const configFile = path.join(projectDir, "paraglide.config.js");
35
+ await fs.writeFile(configFile, "export default {};");
36
+ await fs.writeFile(path.join(root, "index.html"), "<p>Translation preview</p>");
37
+ const file = options.source === "settings"
38
+ ? path.join(projectDir, "settings.json")
39
+ : configFile;
40
+ const original = await fs.readFile(file, "utf8");
41
+ const invalid = options.source === "settings" ? "{" : "export default { outdir: 42 };";
42
+ if (options.isInitiallyInvalid)
43
+ await fs.writeFile(file, invalid);
44
+ const server = await createServer({
45
+ root,
46
+ configFile: false,
47
+ logLevel: "silent",
48
+ plugins: [
49
+ paraglideVitePlugin({
50
+ project: projectDir,
51
+ outdir: path.join(root, "paraglide"),
52
+ devErrorResponse: options.devErrorResponse,
53
+ experimentalPerLocaleBuild: options.experimentalPerLocaleBuild,
54
+ }),
55
+ ],
56
+ server: { host: "127.0.0.1", port: 0, watch: null },
57
+ optimizeDeps: { noDiscovery: true, include: [] },
58
+ });
59
+ cleanups.push(() => server.close());
60
+ await server.listen();
61
+ const url = server.resolvedUrls.local[0];
62
+ return { server, file, original, invalid, url };
63
+ }
64
+ async function notifyChange(server, file) {
65
+ await server.pluginContainer.watchChange(file, { event: "update" });
66
+ }
67
+ test.each(["settings", "config"])("serves HTTP 500 for invalid %s on startup and recovers without restarting", async (source) => {
68
+ const fixture = await createFixture({
69
+ source,
70
+ devErrorResponse: true,
71
+ isInitiallyInvalid: true,
72
+ });
73
+ const response = await fetch(fixture.url);
74
+ expect(response.status).toBe(500);
75
+ expect(response.headers.get("content-type")).toContain("text/plain");
76
+ expect(response.headers.get("cache-control")).toBe("no-store");
77
+ expect(await response.text()).not.toContain("Translation preview");
78
+ await fs.writeFile(fixture.file, fixture.original);
79
+ await notifyChange(fixture.server, fixture.file);
80
+ const recovered = await fetch(fixture.url);
81
+ expect(recovered.status).toBe(200);
82
+ expect(await recovered.text()).toContain("Translation preview");
83
+ });
84
+ test.each(["settings", "config"])("blocks stale responses after invalid %s and restores them after recovery", async (source) => {
85
+ const fixture = await createFixture({ source, devErrorResponse: true });
86
+ const before = await fetch(fixture.url);
87
+ expect(before.status).toBe(200);
88
+ await before.body?.cancel();
89
+ await fs.writeFile(fixture.file, fixture.invalid);
90
+ await notifyChange(fixture.server, fixture.file);
91
+ const failed = await fetch(fixture.url);
92
+ expect(failed.status).toBe(500);
93
+ expect(await failed.text()).not.toContain("Translation preview");
94
+ await fs.writeFile(fixture.file, fixture.original);
95
+ await notifyChange(fixture.server, fixture.file);
96
+ const recovered = await fetch(fixture.url);
97
+ expect(recovered.status).toBe(200);
98
+ await recovered.body?.cancel();
99
+ });
100
+ test.each(["settings", "config"])("keeps the default HTTP behavior after invalid %s", async (source) => {
101
+ const fixture = await createFixture({ source });
102
+ await fs.writeFile(fixture.file, fixture.invalid);
103
+ await notifyChange(fixture.server, fixture.file);
104
+ const response = await fetch(fixture.url);
105
+ expect(response.status).toBe(200);
106
+ expect(await response.text()).toContain("Translation preview");
107
+ });
108
+ test("preserves error responses with experimental per-locale builds enabled", async () => {
109
+ const fixture = await createFixture({
110
+ source: "config",
111
+ devErrorResponse: true,
112
+ experimentalPerLocaleBuild: true,
113
+ });
114
+ await fs.writeFile(fixture.file, fixture.invalid);
115
+ await notifyChange(fixture.server, fixture.file);
116
+ const response = await fetch(fixture.url);
117
+ expect(response.status).toBe(500);
118
+ await response.body?.cancel();
119
+ await fs.writeFile(fixture.file, fixture.original);
120
+ await notifyChange(fixture.server, fixture.file);
121
+ const recovered = await fetch(fixture.url);
122
+ expect(recovered.status).toBe(200);
123
+ await recovered.body?.cancel();
124
+ });
125
+ test("blocks generated modules while preserving errors and recovery for connected clients", async () => {
126
+ const fixture = await createFixture({
127
+ source: "settings",
128
+ devErrorResponse: true,
129
+ });
130
+ const moduleUrl = new URL("paraglide/runtime.js", fixture.url);
131
+ const before = await fetch(moduleUrl);
132
+ expect(before.status).toBe(200);
133
+ expect(await before.text()).toContain("baseLocale");
134
+ const socketUrl = new URL(fixture.url);
135
+ socketUrl.protocol = "ws:";
136
+ socketUrl.searchParams.set("token", fixture.server.config.webSocketToken);
137
+ const socket = new WebSocket(socketUrl, "vite-hmr");
138
+ cleanups.push(() => {
139
+ if (socket.readyState === WebSocket.CLOSED)
140
+ return Promise.resolve();
141
+ return new Promise((resolve) => {
142
+ socket.addEventListener("close", () => resolve(), { once: true });
143
+ socket.close();
144
+ });
145
+ });
146
+ const messages = [];
147
+ socket.addEventListener("message", (event) => {
148
+ messages.push(JSON.parse(String(event.data)));
149
+ });
150
+ await vi.waitFor(() => {
151
+ expect(messages).toContainEqual({ type: "connected" });
152
+ });
153
+ await fs.writeFile(fixture.file, fixture.invalid);
154
+ await notifyChange(fixture.server, fixture.file);
155
+ await vi.waitFor(() => {
156
+ expect(messages.some((message) => message.type === "error")).toBe(true);
157
+ });
158
+ const failed = await fetch(moduleUrl);
159
+ expect(failed.status).toBe(500);
160
+ const diagnostic = messages.find((message) => message.type === "error");
161
+ expect(await failed.text()).toBe(diagnostic?.err.message);
162
+ await fs.writeFile(fixture.file, fixture.original);
163
+ await notifyChange(fixture.server, fixture.file);
164
+ await vi.waitFor(() => {
165
+ expect(messages).toContainEqual({ type: "full-reload" });
166
+ });
167
+ const recovered = await fetch(moduleUrl);
168
+ expect(recovered.status).toBe(200);
169
+ expect(await recovered.text()).toContain("baseLocale");
170
+ });
171
+ //# sourceMappingURL=vite-error-response.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-error-response.test.js","sourceRoot":"","sources":["../../src/bundler-plugins/vite-error-response.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, expect, test, vi } from \"vitest\";\nimport fs from \"node:fs/promises\";\nimport nodeFs from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { createServer, type HotPayload, type ViteDevServer } from \"vite\";\nimport {\n\tloadProjectInMemory,\n\tnewProject,\n\tsaveProjectToDirectory,\n} from \"@inlang/sdk\";\nimport { paraglideVitePlugin } from \"./vite.js\";\n\ntype FixtureOptions = {\n\tdevErrorResponse?: boolean;\n\texperimentalPerLocaleBuild?: boolean;\n\tsource: \"settings\" | \"config\";\n\tisInitiallyInvalid?: boolean;\n};\n\nconst cleanups: Array<() => Promise<void>> = [];\nconst initialNodeEnv = process.env.NODE_ENV;\n\nafterEach(async () => {\n\tfor (const cleanup of cleanups.splice(0).reverse()) await cleanup();\n\tvi.restoreAllMocks();\n\tif (initialNodeEnv === undefined) delete process.env.NODE_ENV;\n\telse process.env.NODE_ENV = initialNodeEnv;\n});\n\nasync function createFixture(options: FixtureOptions) {\n\tprocess.env.NODE_ENV = \"development\";\n\tconst root = nodeFs.realpathSync(\n\t\tawait fs.mkdtemp(path.join(tmpdir(), \"paraglide-error-response-\"))\n\t);\n\tcleanups.push(() => fs.rm(root, { recursive: true, force: true }));\n\tconst projectDir = path.join(root, \"project.inlang\");\n\tconst project = await loadProjectInMemory({\n\t\tblob: await newProject({ settings: { baseLocale: \"en\", locales: [\"en\"] } }),\n\t});\n\ttry {\n\t\tawait saveProjectToDirectory({ project, path: projectDir, fs });\n\t} finally {\n\t\tawait project.close();\n\t}\n\tconst configFile = path.join(projectDir, \"paraglide.config.js\");\n\tawait fs.writeFile(configFile, \"export default {};\");\n\tawait fs.writeFile(\n\t\tpath.join(root, \"index.html\"),\n\t\t\"<p>Translation preview</p>\"\n\t);\n\tconst file =\n\t\toptions.source === \"settings\"\n\t\t\t? path.join(projectDir, \"settings.json\")\n\t\t\t: configFile;\n\tconst original = await fs.readFile(file, \"utf8\");\n\tconst invalid =\n\t\toptions.source === \"settings\" ? \"{\" : \"export default { outdir: 42 };\";\n\tif (options.isInitiallyInvalid) await fs.writeFile(file, invalid);\n\tconst server = await createServer({\n\t\troot,\n\t\tconfigFile: false,\n\t\tlogLevel: \"silent\",\n\t\tplugins: [\n\t\t\tparaglideVitePlugin({\n\t\t\t\tproject: projectDir,\n\t\t\t\toutdir: path.join(root, \"paraglide\"),\n\t\t\t\tdevErrorResponse: options.devErrorResponse,\n\t\t\t\texperimentalPerLocaleBuild: options.experimentalPerLocaleBuild,\n\t\t\t}),\n\t\t],\n\t\tserver: { host: \"127.0.0.1\", port: 0, watch: null },\n\t\toptimizeDeps: { noDiscovery: true, include: [] },\n\t});\n\tcleanups.push(() => server.close());\n\tawait server.listen();\n\tconst url = server.resolvedUrls!.local[0]!;\n\treturn { server, file, original, invalid, url };\n}\n\nasync function notifyChange(server: ViteDevServer, file: string) {\n\tawait server.pluginContainer.watchChange(file, { event: \"update\" });\n}\n\ntest.each([\"settings\", \"config\"] as const)(\n\t\"serves HTTP 500 for invalid %s on startup and recovers without restarting\",\n\tasync (source) => {\n\t\tconst fixture = await createFixture({\n\t\t\tsource,\n\t\t\tdevErrorResponse: true,\n\t\t\tisInitiallyInvalid: true,\n\t\t});\n\t\tconst response = await fetch(fixture.url);\n\t\texpect(response.status).toBe(500);\n\t\texpect(response.headers.get(\"content-type\")).toContain(\"text/plain\");\n\t\texpect(response.headers.get(\"cache-control\")).toBe(\"no-store\");\n\t\texpect(await response.text()).not.toContain(\"Translation preview\");\n\t\tawait fs.writeFile(fixture.file, fixture.original);\n\t\tawait notifyChange(fixture.server, fixture.file);\n\t\tconst recovered = await fetch(fixture.url);\n\t\texpect(recovered.status).toBe(200);\n\t\texpect(await recovered.text()).toContain(\"Translation preview\");\n\t}\n);\n\ntest.each([\"settings\", \"config\"] as const)(\n\t\"blocks stale responses after invalid %s and restores them after recovery\",\n\tasync (source) => {\n\t\tconst fixture = await createFixture({ source, devErrorResponse: true });\n\t\tconst before = await fetch(fixture.url);\n\t\texpect(before.status).toBe(200);\n\t\tawait before.body?.cancel();\n\t\tawait fs.writeFile(fixture.file, fixture.invalid);\n\t\tawait notifyChange(fixture.server, fixture.file);\n\t\tconst failed = await fetch(fixture.url);\n\t\texpect(failed.status).toBe(500);\n\t\texpect(await failed.text()).not.toContain(\"Translation preview\");\n\t\tawait fs.writeFile(fixture.file, fixture.original);\n\t\tawait notifyChange(fixture.server, fixture.file);\n\t\tconst recovered = await fetch(fixture.url);\n\t\texpect(recovered.status).toBe(200);\n\t\tawait recovered.body?.cancel();\n\t}\n);\n\ntest.each([\"settings\", \"config\"] as const)(\n\t\"keeps the default HTTP behavior after invalid %s\",\n\tasync (source) => {\n\t\tconst fixture = await createFixture({ source });\n\t\tawait fs.writeFile(fixture.file, fixture.invalid);\n\t\tawait notifyChange(fixture.server, fixture.file);\n\t\tconst response = await fetch(fixture.url);\n\t\texpect(response.status).toBe(200);\n\t\texpect(await response.text()).toContain(\"Translation preview\");\n\t}\n);\n\ntest(\"preserves error responses with experimental per-locale builds enabled\", async () => {\n\tconst fixture = await createFixture({\n\t\tsource: \"config\",\n\t\tdevErrorResponse: true,\n\t\texperimentalPerLocaleBuild: true,\n\t});\n\tawait fs.writeFile(fixture.file, fixture.invalid);\n\tawait notifyChange(fixture.server, fixture.file);\n\tconst response = await fetch(fixture.url);\n\texpect(response.status).toBe(500);\n\tawait response.body?.cancel();\n\tawait fs.writeFile(fixture.file, fixture.original);\n\tawait notifyChange(fixture.server, fixture.file);\n\tconst recovered = await fetch(fixture.url);\n\texpect(recovered.status).toBe(200);\n\tawait recovered.body?.cancel();\n});\n\ntest(\"blocks generated modules while preserving errors and recovery for connected clients\", async () => {\n\tconst fixture = await createFixture({\n\t\tsource: \"settings\",\n\t\tdevErrorResponse: true,\n\t});\n\tconst moduleUrl = new URL(\"paraglide/runtime.js\", fixture.url);\n\tconst before = await fetch(moduleUrl);\n\texpect(before.status).toBe(200);\n\texpect(await before.text()).toContain(\"baseLocale\");\n\tconst socketUrl = new URL(fixture.url);\n\tsocketUrl.protocol = \"ws:\";\n\tsocketUrl.searchParams.set(\"token\", fixture.server.config.webSocketToken);\n\tconst socket = new WebSocket(socketUrl, \"vite-hmr\");\n\tcleanups.push(() => {\n\t\tif (socket.readyState === WebSocket.CLOSED) return Promise.resolve();\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tsocket.addEventListener(\"close\", () => resolve(), { once: true });\n\t\t\tsocket.close();\n\t\t});\n\t});\n\tconst messages: HotPayload[] = [];\n\tsocket.addEventListener(\"message\", (event) => {\n\t\tmessages.push(JSON.parse(String(event.data)) as HotPayload);\n\t});\n\tawait vi.waitFor(() => {\n\t\texpect(messages).toContainEqual({ type: \"connected\" });\n\t});\n\tawait fs.writeFile(fixture.file, fixture.invalid);\n\tawait notifyChange(fixture.server, fixture.file);\n\tawait vi.waitFor(() => {\n\t\texpect(messages.some((message) => message.type === \"error\")).toBe(true);\n\t});\n\tconst failed = await fetch(moduleUrl);\n\texpect(failed.status).toBe(500);\n\tconst diagnostic = messages.find((message) => message.type === \"error\");\n\texpect(await failed.text()).toBe(diagnostic?.err.message);\n\tawait fs.writeFile(fixture.file, fixture.original);\n\tawait notifyChange(fixture.server, fixture.file);\n\tawait vi.waitFor(() => {\n\t\texpect(messages).toContainEqual({ type: \"full-reload\" });\n\t});\n\tconst recovered = await fetch(moduleUrl);\n\texpect(recovered.status).toBe(200);\n\texpect(await recovered.text()).toContain(\"baseLocale\");\n});\n"]}
@@ -1,6 +1,14 @@
1
1
  import type { Plugin } from "vite";
2
2
  import type { ParaglidePluginOptions } from "./unplugin.js";
3
3
  export type ParaglideVitePluginOptions = ParaglidePluginOptions & {
4
+ /**
5
+ * Respond with HTTP 500 while the development compiler or its config is
6
+ * invalid, instead of serving the last successful output. Error overlays
7
+ * remain enabled. Set this on the Vite plugin, not in paraglide.config.
8
+ *
9
+ * @default false
10
+ */
11
+ devErrorResponse?: boolean;
4
12
  /**
5
13
  * Emit one compiler-specialized client asset tree per project locale.
6
14
  *
@@ -1,16 +1,25 @@
1
1
  import { createVitePlugin } from "unplugin";
2
2
  import { createPerLocaleBuildPlugins } from "./per-locale-build/index.js";
3
3
  import { unpluginFactory } from "./unplugin.js";
4
- const createCompilerVitePlugin = createVitePlugin(unpluginFactory);
5
- const createPerLocaleCompilerVitePlugin = createVitePlugin((options, meta) => unpluginFactory(options, meta, { outputStructure: "locale-modules" }));
4
+ const createCompilerVitePlugin = createVitePlugin(({ devErrorResponse, ...options }, meta) => unpluginFactory(options, meta, { devErrorResponse }));
5
+ const createPerLocaleCompilerVitePlugin = createVitePlugin(({ devErrorResponse, ...options }, meta) => unpluginFactory(options, meta, {
6
+ outputStructure: "locale-modules",
7
+ devErrorResponse,
8
+ }));
6
9
  export function paraglideVitePlugin(options) {
7
- const { experimentalPerLocaleBuild, ...compilerOptions } = options;
10
+ const { experimentalPerLocaleBuild, devErrorResponse, ...compilerOptions } = options;
8
11
  if (!experimentalPerLocaleBuild) {
9
- return createCompilerVitePlugin(compilerOptions);
12
+ return createCompilerVitePlugin({
13
+ ...compilerOptions,
14
+ devErrorResponse,
15
+ });
10
16
  }
11
17
  return createPerLocaleBuildPlugins({
12
18
  compilerOptions,
13
- createCompilerPlugin: (options) => createPerLocaleCompilerVitePlugin(options),
19
+ createCompilerPlugin: (options) => createPerLocaleCompilerVitePlugin({
20
+ ...options,
21
+ devErrorResponse,
22
+ }),
14
23
  });
15
24
  }
16
25
  //# sourceMappingURL=vite.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vite.js","sourceRoot":"","sources":["../../src/bundler-plugins/vite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAiBhD,MAAM,wBAAwB,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC;AACnE,MAAM,iCAAiC,GACtC,gBAAgB,CAAyB,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAC1D,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC,CACrE,CAAC;AAEH,MAAM,UAAU,mBAAmB,CAClC,OAAmC;IAEnC,MAAM,EAAE,0BAA0B,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC;IACnE,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACjC,OAAO,wBAAwB,CAAC,eAAe,CAAW,CAAC;IAC5D,CAAC;IAED,OAAO,2BAA2B,CAAC;QAClC,eAAe;QACf,oBAAoB,EAAE,CAAC,OAAO,EAAE,EAAE,CACjC,iCAAiC,CAAC,OAAO,CAAW;KACrD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { createVitePlugin } from \"unplugin\";\nimport type { Plugin } from \"vite\";\nimport type { ParaglidePluginOptions } from \"./unplugin.js\";\nimport { createPerLocaleBuildPlugins } from \"./per-locale-build/index.js\";\nimport { unpluginFactory } from \"./unplugin.js\";\n\nexport type ParaglideVitePluginOptions = ParaglidePluginOptions & {\n\t/**\n\t * Emit one compiler-specialized client asset tree per project locale.\n\t *\n\t * Requires Vite 8+. Builds one untouched Rolldown client environment per\n\t * locale and emits `paraglide-vite-locales.json`. Locale changes need to use\n\t * full-document navigation. Framework SSR graph selection requires a public\n\t * framework integration API.\n\t *\n\t * @experimental\n\t * @default false\n\t */\n\texperimentalPerLocaleBuild?: boolean;\n};\n\nconst createCompilerVitePlugin = createVitePlugin(unpluginFactory);\nconst createPerLocaleCompilerVitePlugin =\n\tcreateVitePlugin<ParaglidePluginOptions>((options, meta) =>\n\t\tunpluginFactory(options, meta, { outputStructure: \"locale-modules\" })\n\t);\n\nexport function paraglideVitePlugin(\n\toptions: ParaglideVitePluginOptions\n): Plugin | Plugin[] {\n\tconst { experimentalPerLocaleBuild, ...compilerOptions } = options;\n\tif (!experimentalPerLocaleBuild) {\n\t\treturn createCompilerVitePlugin(compilerOptions) as Plugin;\n\t}\n\n\treturn createPerLocaleBuildPlugins({\n\t\tcompilerOptions,\n\t\tcreateCompilerPlugin: (options) =>\n\t\t\tcreatePerLocaleCompilerVitePlugin(options) as Plugin,\n\t});\n}\n"]}
1
+ {"version":3,"file":"vite.js","sourceRoot":"","sources":["../../src/bundler-plugins/vite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AA8BhD,MAAM,wBAAwB,GAAG,gBAAgB,CAChD,CAAC,EAAE,gBAAgB,EAAE,GAAG,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,CAC1C,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,gBAAgB,EAAE,CAAC,CACrD,CAAC;AACF,MAAM,iCAAiC,GACtC,gBAAgB,CACf,CAAC,EAAE,gBAAgB,EAAE,GAAG,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,CAC1C,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE;IAC9B,eAAe,EAAE,gBAAgB;IACjC,gBAAgB;CAChB,CAAC,CACH,CAAC;AAEH,MAAM,UAAU,mBAAmB,CAClC,OAAmC;IAEnC,MAAM,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,GAAG,eAAe,EAAE,GACzE,OAAO,CAAC;IACT,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACjC,OAAO,wBAAwB,CAAC;YAC/B,GAAG,eAAe;YAClB,gBAAgB;SAChB,CAAW,CAAC;IACd,CAAC;IAED,OAAO,2BAA2B,CAAC;QAClC,eAAe;QACf,oBAAoB,EAAE,CAAC,OAAO,EAAE,EAAE,CACjC,iCAAiC,CAAC;YACjC,GAAG,OAAO;YACV,gBAAgB;SAChB,CAAW;KACb,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { createVitePlugin } from \"unplugin\";\nimport type { Plugin } from \"vite\";\nimport type { ParaglidePluginOptions } from \"./unplugin.js\";\nimport { createPerLocaleBuildPlugins } from \"./per-locale-build/index.js\";\nimport { unpluginFactory } from \"./unplugin.js\";\n\nexport type ParaglideVitePluginOptions = ParaglidePluginOptions & {\n\t/**\n\t * Respond with HTTP 500 while the development compiler or its config is\n\t * invalid, instead of serving the last successful output. Error overlays\n\t * remain enabled. Set this on the Vite plugin, not in paraglide.config.\n\t *\n\t * @default false\n\t */\n\tdevErrorResponse?: boolean;\n\t/**\n\t * Emit one compiler-specialized client asset tree per project locale.\n\t *\n\t * Requires Vite 8+. Builds one untouched Rolldown client environment per\n\t * locale and emits `paraglide-vite-locales.json`. Locale changes need to use\n\t * full-document navigation. Framework SSR graph selection requires a public\n\t * framework integration API.\n\t *\n\t * @experimental\n\t * @default false\n\t */\n\texperimentalPerLocaleBuild?: boolean;\n};\n\ntype CompilerVitePluginOptions = Omit<\n\tParaglideVitePluginOptions,\n\t\"experimentalPerLocaleBuild\"\n>;\n\nconst createCompilerVitePlugin = createVitePlugin<CompilerVitePluginOptions>(\n\t({ devErrorResponse, ...options }, meta) =>\n\t\tunpluginFactory(options, meta, { devErrorResponse })\n);\nconst createPerLocaleCompilerVitePlugin =\n\tcreateVitePlugin<CompilerVitePluginOptions>(\n\t\t({ devErrorResponse, ...options }, meta) =>\n\t\t\tunpluginFactory(options, meta, {\n\t\t\t\toutputStructure: \"locale-modules\",\n\t\t\t\tdevErrorResponse,\n\t\t\t})\n\t);\n\nexport function paraglideVitePlugin(\n\toptions: ParaglideVitePluginOptions\n): Plugin | Plugin[] {\n\tconst { experimentalPerLocaleBuild, devErrorResponse, ...compilerOptions } =\n\t\toptions;\n\tif (!experimentalPerLocaleBuild) {\n\t\treturn createCompilerVitePlugin({\n\t\t\t...compilerOptions,\n\t\t\tdevErrorResponse,\n\t\t}) as Plugin;\n\t}\n\n\treturn createPerLocaleBuildPlugins({\n\t\tcompilerOptions,\n\t\tcreateCompilerPlugin: (options) =>\n\t\t\tcreatePerLocaleCompilerVitePlugin({\n\t\t\t\t...options,\n\t\t\t\tdevErrorResponse,\n\t\t\t}) as Plugin,\n\t});\n}\n"]}
@@ -37,12 +37,14 @@
37
37
  * // => URL("https://de.example.com/store")
38
38
  * ```
39
39
  *
40
- * @param {string | URL} url - The URL to localize. If string, must be absolute.
40
+ * @param {string | { readonly href: string }} url - The URL to localize. Accepts readonly URL objects. If string, must be absolute.
41
41
  * @param {object} [options] - Options for localization
42
42
  * @param {Locale} [options.locale] - Target locale. If not provided, uses getLocale()
43
43
  * @returns {URL} The localized URL, always absolute
44
44
  */
45
- export declare function localizeUrl(url: string | URL, options?: {
45
+ export declare function localizeUrl(url: string | {
46
+ readonly href: string;
47
+ }, options?: {
46
48
  locale?: Locale;
47
49
  }): URL;
48
50
  /**
@@ -81,10 +83,12 @@ export declare function localizeUrl(url: string | URL, options?: {
81
83
  * deLocalizeUrl(url); // => URL("https://example.com/store")
82
84
  * ```
83
85
  *
84
- * @param {string | URL} url - The URL to de-localize. If string, must be absolute.
86
+ * @param {string | { readonly href: string }} url - The URL to de-localize. Accepts readonly URL objects. If string, must be absolute.
85
87
  * @returns {URL} The de-localized URL, always absolute
86
88
  */
87
- export declare function deLocalizeUrl(url: string | URL): URL;
89
+ export declare function deLocalizeUrl(url: string | {
90
+ readonly href: string;
91
+ }): URL;
88
92
  /**
89
93
  * Aggregates named groups from various parts of the URLPattern match result.
90
94
  *
@@ -46,7 +46,7 @@ import { getUrlPatternCandidates, currentRoutingConfigVersion, } from "./url-pat
46
46
  * // => URL("https://de.example.com/store")
47
47
  * ```
48
48
  *
49
- * @param {string | URL} url - The URL to localize. If string, must be absolute.
49
+ * @param {string | { readonly href: string }} url - The URL to localize. Accepts readonly URL objects. If string, must be absolute.
50
50
  * @param {object} [options] - Options for localization
51
51
  * @param {Locale} [options.locale] - Target locale. If not provided, uses getLocale()
52
52
  * @returns {URL} The localized URL, always absolute
@@ -58,7 +58,9 @@ export function localizeUrl(url, options) {
58
58
  if (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {
59
59
  return localizeUrlDefaultPattern(url, targetLocale);
60
60
  }
61
- const originalUrl = typeof url === "string" ? new URL(url) : url;
61
+ const originalUrl = url instanceof URL
62
+ ? url
63
+ : new URL(typeof url === "string" ? url : url.href);
62
64
  const urlObj = trailingSlash === undefined
63
65
  ? originalUrl
64
66
  : normalizeTrailingSlash(new URL(originalUrl));
@@ -101,12 +103,12 @@ export function localizeUrl(url, options) {
101
103
  /**
102
104
  * https://github.com/opral/inlang-paraglide-js/issues/381
103
105
  *
104
- * @param {string | URL} url
106
+ * @param {string | { readonly href: string }} url
105
107
  * @param {Locale} locale
106
108
  * @returns {URL}
107
109
  */
108
110
  function localizeUrlDefaultPattern(url, locale) {
109
- const urlObj = normalizeTrailingSlash(typeof url === "string" ? new URL(url, getUrlOrigin()) : new URL(url));
111
+ const urlObj = normalizeTrailingSlash(typeof url === "string" ? new URL(url, getUrlOrigin()) : new URL(url.href));
110
112
  const currentLocale = extractLocaleFromUrl(urlObj);
111
113
  // If current locale matches target locale, no change needed
112
114
  if (currentLocale === locale) {
@@ -164,14 +166,16 @@ function localizeUrlDefaultPattern(url, locale) {
164
166
  * deLocalizeUrl(url); // => URL("https://example.com/store")
165
167
  * ```
166
168
  *
167
- * @param {string | URL} url - The URL to de-localize. If string, must be absolute.
169
+ * @param {string | { readonly href: string }} url - The URL to de-localize. Accepts readonly URL objects. If string, must be absolute.
168
170
  * @returns {URL} The de-localized URL, always absolute
169
171
  */
170
172
  export function deLocalizeUrl(url) {
171
173
  if (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {
172
174
  return deLocalizeUrlDefaultPattern(url);
173
175
  }
174
- const originalUrl = typeof url === "string" ? new URL(url) : url;
176
+ const originalUrl = url instanceof URL
177
+ ? url
178
+ : new URL(typeof url === "string" ? url : url.href);
175
179
  const urlObj = trailingSlash === undefined
176
180
  ? originalUrl
177
181
  : normalizeTrailingSlash(new URL(originalUrl));
@@ -203,11 +207,11 @@ export function deLocalizeUrl(url) {
203
207
  }
204
208
  /**
205
209
  * De-localizes a URL using the default pattern (/:locale/*)
206
- * @param {string|URL} url
210
+ * @param {string | { readonly href: string }} url
207
211
  * @returns {URL}
208
212
  */
209
213
  function deLocalizeUrlDefaultPattern(url) {
210
- const urlObj = normalizeTrailingSlash(typeof url === "string" ? new URL(url, getUrlOrigin()) : new URL(url));
214
+ const urlObj = normalizeTrailingSlash(typeof url === "string" ? new URL(url, getUrlOrigin()) : new URL(url.href));
211
215
  // Ignore leading separators like locale detection, preserving the remaining path.
212
216
  const pathSegments = urlObj.pathname.replace(/^\/+/, "").split("/");
213
217
  // If first segment is a locale, remove it
@@ -1 +1 @@
1
- {"version":3,"file":"localize-url.js","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-url.js"],"names":[],"mappings":"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","sourcesContent":["import { extractLocaleFromUrl } from \"./extract-locale-from-url.js\";\nimport { getLocale } from \"./get-locale.js\";\nimport { getUrlOrigin } from \"./get-url-origin.js\";\nimport { assertIsLocale, toLocale } from \"./check-locale.js\";\nimport {\n\tbaseLocale,\n\tTREE_SHAKE_DEFAULT_URL_PATTERN_USED,\n\ttrailingSlash,\n} from \"./variables.js\";\nimport { normalizeTrailingSlash } from \"./normalize-trailing-slash.js\";\nimport { execUrlPattern } from \"./exec-url-pattern.js\";\nimport { getUrlPattern } from \"./url-pattern-cache.js\";\nimport {\n\tgetUrlPatternCandidates,\n\tcurrentRoutingConfigVersion,\n} from \"./url-pattern-index.js\";\n\n/**\n * Lower-level URL localization function, primarily used in server contexts.\n *\n * This function is designed for server-side usage where you need precise control\n * over URL localization, such as in middleware or request handlers. It works with\n * URL objects and always returns absolute URLs.\n *\n * For client-side UI components, use `localizeHref()` instead, which provides\n * a more convenient API with relative paths and automatic locale detection.\n *\n * @see https://paraglidejs.com/i18n-routing\n *\n * @example\n * ```typescript\n * // Server middleware example\n * app.use((req, res, next) => {\n * const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);\n * const localized = localizeUrl(url, { locale: \"de\" });\n *\n * if (localized.href !== url.href) {\n * return res.redirect(localized.href);\n * }\n * next();\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Using with URL patterns\n * const url = new URL(\"https://example.com/about\");\n * localizeUrl(url, { locale: \"de\" });\n * // => URL(\"https://example.com/de/about\")\n *\n * // Using with domain-based localization\n * const url = new URL(\"https://example.com/store\");\n * localizeUrl(url, { locale: \"de\" });\n * // => URL(\"https://de.example.com/store\")\n * ```\n *\n * @param {string | URL} url - The URL to localize. If string, must be absolute.\n * @param {object} [options] - Options for localization\n * @param {Locale} [options.locale] - Target locale. If not provided, uses getLocale()\n * @returns {URL} The localized URL, always absolute\n */\nexport function localizeUrl(url, options) {\n\tconst targetLocale = options?.locale\n\t\t? assertIsLocale(options?.locale)\n\t\t: getLocale();\n\n\tif (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {\n\t\treturn localizeUrlDefaultPattern(url, targetLocale);\n\t}\n\n\tconst originalUrl = typeof url === \"string\" ? new URL(url) : url;\n\tconst urlObj =\n\t\ttrailingSlash === undefined\n\t\t\t? originalUrl\n\t\t\t: normalizeTrailingSlash(new URL(originalUrl));\n\n\t// Iterate over URL patterns\n\tfor (const element of getUrlPatternCandidates(urlObj)) {\n\t\t// Most applications use a locale prefix (and sometimes a fixed domain)\n\t\t// with a trailing catch-all path. Those routes do not need URLPattern's\n\t\t// parser or matcher on every call. Keep the generic matcher below as the\n\t\t// fallback for every other URLPattern shape. This stays inside the outer\n\t\t// loop so specific patterns retain precedence over a later catch-all.\n\t\tconst fastPathLocalized = localizeUrlFastPath(\n\t\t\turlObj,\n\t\t\ttargetLocale,\n\t\t\telement\n\t\t);\n\t\tif (fastPathLocalized !== undefined) {\n\t\t\treturn fastPathLocalized;\n\t\t}\n\n\t\t// match localized patterns\n\t\tfor (const [, localizedPattern] of element.localized) {\n\t\t\tconst match = execUrlPattern(\n\t\t\t\tgetUrlPattern(localizedPattern, urlObj),\n\t\t\t\turlObj\n\t\t\t);\n\n\t\t\tif (!match) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst targetPattern = element.localized.find(\n\t\t\t\t([locale]) => locale === targetLocale\n\t\t\t)?.[1];\n\n\t\t\tif (!targetPattern) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst localizedUrl = fillPattern(\n\t\t\t\ttargetPattern,\n\t\t\t\taggregateGroups(match),\n\t\t\t\turlObj.origin\n\t\t\t);\n\t\t\treturn normalizeTrailingSlash(fillMissingUrlParts(localizedUrl, match));\n\t\t}\n\t\tconst unlocalizedMatch = execUrlPattern(\n\t\t\tgetUrlPattern(element.pattern, urlObj),\n\t\t\turlObj\n\t\t);\n\t\tif (unlocalizedMatch) {\n\t\t\tconst targetPattern = element.localized.find(\n\t\t\t\t([locale]) => locale === targetLocale\n\t\t\t)?.[1];\n\t\t\tif (targetPattern) {\n\t\t\t\tconst localizedUrl = fillPattern(\n\t\t\t\t\ttargetPattern,\n\t\t\t\t\taggregateGroups(unlocalizedMatch),\n\t\t\t\t\turlObj.origin\n\t\t\t\t);\n\t\t\t\treturn normalizeTrailingSlash(\n\t\t\t\t\tfillMissingUrlParts(localizedUrl, unlocalizedMatch)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\t// If no match found, return the original URL\n\treturn originalUrl;\n}\n\n/**\n * https://github.com/opral/inlang-paraglide-js/issues/381\n *\n * @param {string | URL} url\n * @param {Locale} locale\n * @returns {URL}\n */\nfunction localizeUrlDefaultPattern(url, locale) {\n\tconst urlObj = normalizeTrailingSlash(\n\t\ttypeof url === \"string\" ? new URL(url, getUrlOrigin()) : new URL(url)\n\t);\n\n\tconst currentLocale = extractLocaleFromUrl(urlObj);\n\n\t// If current locale matches target locale, no change needed\n\tif (currentLocale === locale) {\n\t\treturn normalizeTrailingSlash(urlObj);\n\t}\n\n\t// Ignore leading separators like locale detection, preserving the remaining path.\n\tconst pathSegments = urlObj.pathname.replace(/^\\/+/, \"\").split(\"/\");\n\n\t// If current path starts with a locale, remove it\n\tif (pathSegments.length > 0 && toLocale(pathSegments[0])) {\n\t\tpathSegments.shift();\n\t}\n\n\t// For base locale, don't add prefix\n\tif (locale === baseLocale) {\n\t\turlObj.pathname = \"/\" + pathSegments.join(\"/\");\n\t} else {\n\t\t// For other locales, add prefix\n\t\turlObj.pathname = \"/\" + locale + \"/\" + pathSegments.join(\"/\");\n\t}\n\n\treturn normalizeTrailingSlash(urlObj);\n}\n\n/**\n * Low-level URL de-localization function, primarily used in server contexts.\n *\n * This function is designed for server-side usage where you need precise control\n * over URL de-localization, such as in middleware or request handlers. It works with\n * URL objects and always returns absolute URLs.\n *\n * For client-side UI components, use `deLocalizeHref()` instead, which provides\n * a more convenient API with relative paths.\n *\n * @see https://paraglidejs.com/i18n-routing\n *\n * @example\n * ```typescript\n * // Server middleware example\n * app.use((req, res, next) => {\n * const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);\n * const baseUrl = deLocalizeUrl(url);\n *\n * // Store the base URL for later use\n * req.baseUrl = baseUrl;\n * next();\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Using with URL patterns\n * const url = new URL(\"https://example.com/de/about\");\n * deLocalizeUrl(url); // => URL(\"https://example.com/about\")\n *\n * // Using with domain-based localization\n * const url = new URL(\"https://de.example.com/store\");\n * deLocalizeUrl(url); // => URL(\"https://example.com/store\")\n * ```\n *\n * @param {string | URL} url - The URL to de-localize. If string, must be absolute.\n * @returns {URL} The de-localized URL, always absolute\n */\nexport function deLocalizeUrl(url) {\n\tif (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {\n\t\treturn deLocalizeUrlDefaultPattern(url);\n\t}\n\n\tconst originalUrl = typeof url === \"string\" ? new URL(url) : url;\n\tconst urlObj =\n\t\ttrailingSlash === undefined\n\t\t\t? originalUrl\n\t\t\t: normalizeTrailingSlash(new URL(originalUrl));\n\n\t// Iterate over URL patterns\n\tfor (const element of getUrlPatternCandidates(urlObj)) {\n\t\tconst fastPathDeLocalized = deLocalizeUrlFastPath(urlObj, element);\n\t\tif (fastPathDeLocalized !== undefined) {\n\t\t\treturn fastPathDeLocalized;\n\t\t}\n\n\t\t// Iterate over localized versions\n\t\tfor (const [, localizedPattern] of element.localized) {\n\t\t\tconst match = execUrlPattern(\n\t\t\t\tgetUrlPattern(localizedPattern, urlObj),\n\t\t\t\turlObj\n\t\t\t);\n\n\t\t\tif (match) {\n\t\t\t\t// Convert localized URL back to the base pattern\n\t\t\t\tconst groups = aggregateGroups(match);\n\n\t\t\t\tconst baseUrl = fillPattern(element.pattern, groups, urlObj.origin);\n\t\t\t\treturn normalizeTrailingSlash(fillMissingUrlParts(baseUrl, match));\n\t\t\t}\n\t\t}\n\t\t// match unlocalized pattern\n\t\tconst unlocalizedMatch = execUrlPattern(\n\t\t\tgetUrlPattern(element.pattern, urlObj),\n\t\t\turlObj\n\t\t);\n\t\tif (unlocalizedMatch) {\n\t\t\tconst baseUrl = fillPattern(\n\t\t\t\telement.pattern,\n\t\t\t\taggregateGroups(unlocalizedMatch),\n\t\t\t\turlObj.origin\n\t\t\t);\n\t\t\treturn normalizeTrailingSlash(\n\t\t\t\tfillMissingUrlParts(baseUrl, unlocalizedMatch)\n\t\t\t);\n\t\t}\n\t}\n\t// no match found return the original url\n\treturn originalUrl;\n}\n\n/**\n * De-localizes a URL using the default pattern (/:locale/*)\n * @param {string|URL} url\n * @returns {URL}\n */\nfunction deLocalizeUrlDefaultPattern(url) {\n\tconst urlObj = normalizeTrailingSlash(\n\t\ttypeof url === \"string\" ? new URL(url, getUrlOrigin()) : new URL(url)\n\t);\n\t// Ignore leading separators like locale detection, preserving the remaining path.\n\tconst pathSegments = urlObj.pathname.replace(/^\\/+/, \"\").split(\"/\");\n\n\t// If first segment is a locale, remove it\n\tif (pathSegments.length > 0 && toLocale(pathSegments[0])) {\n\t\turlObj.pathname = \"/\" + pathSegments.slice(1).join(\"/\");\n\t}\n\n\treturn normalizeTrailingSlash(urlObj);\n}\n\n/**\n * Takes matches of implicit wildcards in the UrlPattern (when a part is missing\n * it is equal to '*') and adds them back to the result of fillPattern.\n *\n * At least protocol and hostname are required to create a valid URL inside fillPattern.\n *\n * @param {URL} url\n * @param {any} match\n * @returns {URL}\n */\nfunction fillMissingUrlParts(url, match) {\n\tif (match.protocol.groups[\"0\"]) {\n\t\turl.protocol = match.protocol.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.hostname.groups[\"0\"]) {\n\t\turl.hostname = match.hostname.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.username.groups[\"0\"]) {\n\t\turl.username = match.username.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.password.groups[\"0\"]) {\n\t\turl.password = match.password.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.port.groups[\"0\"]) {\n\t\turl.port = match.port.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.pathname.groups[\"0\"]) {\n\t\turl.pathname = match.pathname.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.search.groups[\"0\"]) {\n\t\turl.search = match.search.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.hash.groups[\"0\"]) {\n\t\turl.hash = match.hash.groups[\"0\"] ?? \"\";\n\t}\n\n\treturn url;\n}\n\n/**\n * Fills a URL pattern with values for named groups, supporting all URLPattern-style modifiers.\n *\n * This function will eventually be replaced by https://github.com/whatwg/urlpattern/issues/73\n *\n * Matches:\n * - :name -> Simple\n * - :name? -> Optional\n * - :name+ -> One or more\n * - :name* -> Zero or more\n * - :name(...) -> Regex group\n * - {text} -> Group delimiter\n * - {text}? -> Optional group delimiter\n *\n * If the value is `null`, the segment is removed.\n *\n * @param {string} pattern - The URL pattern containing named groups.\n * @param {Record<string, string | null | undefined>} values - Object of values for named groups.\n * @param {string} origin - Base URL to use for URL construction.\n * @returns {URL} - The constructed URL with named groups filled.\n */\nfunction fillPattern(pattern, values, origin) {\n\t// Pre-process the pattern to handle explicit port numbers\n\t// This detects patterns like \"http://localhost:5173\" and protects the port number\n\t// from being interpreted as a parameter\n\tlet processedPattern = pattern.replace(\n\t\t/(https?:\\/\\/[^:/]+):(\\d+)(\\/|$)/g,\n\t\t(_, protocol, port, slash) => {\n\t\t\t// Replace \":5173\" with \"#PORT-5173#\" to protect it from parameter replacement\n\t\t\treturn `${protocol}#PORT-${port}#${slash}`;\n\t\t}\n\t);\n\n\t// First, handle group delimiters with curly braces\n\tlet processedGroupDelimiters = processedPattern.replace(\n\t\t/\\{([^{}]*)\\}([?+*]?)/g,\n\t\t(_, content, modifier) => {\n\t\t\t// For optional group delimiters\n\t\t\tif (modifier === \"?\") {\n\t\t\t\t// For optional groups, we'll include the content\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\t// For non-optional group delimiters, always include the content\n\t\t\treturn content;\n\t\t}\n\t);\n\n\t// Then handle named groups\n\tlet filled = processedGroupDelimiters.replace(\n\t\t/(\\/?):([a-zA-Z0-9_]+)(\\([^)]*\\))?([?+*]?)/g,\n\t\t(_, slash, name, __, modifier) => {\n\t\t\tconst value = values[name];\n\n\t\t\tif (value === null) {\n\t\t\t\t// If value is null, remove the entire segment including the preceding slash\n\t\t\t\treturn \"\";\n\t\t\t}\n\n\t\t\tif (modifier === \"?\") {\n\t\t\t\t// Optional segment\n\t\t\t\treturn value !== undefined ? `${slash}${value}` : \"\";\n\t\t\t}\n\n\t\t\tif (modifier === \"+\" || modifier === \"*\") {\n\t\t\t\t// Repeatable segments\n\t\t\t\tif (value === undefined && modifier === \"+\") {\n\t\t\t\t\tthrow new Error(`Missing value for \"${name}\" (one or more required)`);\n\t\t\t\t}\n\t\t\t\treturn value ? `${slash}${value}` : \"\";\n\t\t\t}\n\n\t\t\t// Simple named group (no modifier)\n\t\t\tif (value === undefined) {\n\t\t\t\tthrow new Error(`Missing value for \"${name}\"`);\n\t\t\t}\n\n\t\t\treturn `${slash}${value}`;\n\t\t}\n\t);\n\n\t// Restore port numbers\n\tfilled = filled.replace(/#PORT-(\\d+)#/g, \":$1\");\n\n\treturn new URL(filled, origin);\n}\n\n/**\n * Aggregates named groups from various parts of the URLPattern match result.\n *\n *\n * @param {any} match - The URLPattern match result object.\n * @returns {Record<string, string | null | undefined>} An object containing all named groups from the match.\n */\nexport function aggregateGroups(match) {\n\treturn {\n\t\t...match.hash.groups,\n\t\t...match.hostname.groups,\n\t\t...match.password.groups,\n\t\t...match.pathname.groups,\n\t\t...match.port.groups,\n\t\t...match.protocol.groups,\n\t\t...match.search.groups,\n\t\t...match.username.groups,\n\t};\n}\n\n/**\n * A small, deliberately conservative subset of URLPattern routing.\n *\n * The compiler emits routes such as `/:path(.*)?`, `/de/:path*`, or\n * `https://example.com/:path*`. For those routes matching is equivalent to a\n * pathname prefix check and (optionally) an origin check. Everything that has\n * a dynamic host, a custom path regexp, or another URLPattern modifier keeps\n * using the generic implementation above.\n *\n * @typedef {{\n * protocol: string | undefined;\n * hostname: string | undefined;\n * port: string | undefined;\n * pathnamePrefix: string;\n * pathMode: \"segments\" | \"catch-all-optional\" | \"catch-all-required\";\n * }} FastPathPattern\n * @typedef {{\n * base: FastPathPattern;\n * localized: Array<{ locale: string; pattern: FastPathPattern }>;\n * }} FastPathRoute\n */\n\n/** @type {WeakMap<object, { version: number; route: FastPathRoute | null }>} */\nconst fastPathRouteCache = new WeakMap();\n\n/**\n * @param {URL} urlObj\n * @param {string} targetLocale\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {URL | undefined}\n */\nfunction localizeUrlFastPath(urlObj, targetLocale, element) {\n\tconst route = getFastPathRoute(element);\n\tif (route === null) return undefined;\n\n\t// Preserve URLPattern's ordering: localized patterns are checked before\n\t// the unlocalized pattern, and the first matching pattern wins.\n\tfor (const localized of route.localized) {\n\t\tconst suffix = matchFastPathPattern(localized.pattern, urlObj);\n\t\tif (suffix === undefined) continue;\n\n\t\tconst target = route.localized.find(\n\t\t\t(candidate) => candidate.locale === targetLocale\n\t\t)?.pattern;\n\t\tif (target === undefined) continue;\n\n\t\treturn applyFastPathPattern(target, suffix, urlObj);\n\t}\n\n\tconst suffix = matchFastPathPattern(route.base, urlObj);\n\tif (suffix !== undefined) {\n\t\tconst target = route.localized.find(\n\t\t\t(candidate) => candidate.locale === targetLocale\n\t\t)?.pattern;\n\t\tif (target !== undefined) {\n\t\t\treturn applyFastPathPattern(target, suffix, urlObj);\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\n/**\n * @param {URL} urlObj\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {URL | undefined}\n */\nfunction deLocalizeUrlFastPath(urlObj, element) {\n\tconst route = getFastPathRoute(element);\n\tif (route === null) return undefined;\n\n\tfor (const localized of route.localized) {\n\t\tconst suffix = matchFastPathPattern(localized.pattern, urlObj);\n\t\tif (suffix !== undefined) {\n\t\t\treturn applyFastPathPattern(route.base, suffix, urlObj);\n\t\t}\n\t}\n\n\tconst suffix = matchFastPathPattern(route.base, urlObj);\n\tif (suffix !== undefined) {\n\t\treturn applyFastPathPattern(route.base, suffix, urlObj);\n\t}\n\n\treturn undefined;\n}\n\n/**\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {FastPathRoute | null}\n */\nfunction getFastPathRoute(element) {\n\tconst cached = fastPathRouteCache.get(element);\n\tif (cached?.version === currentRoutingConfigVersion()) return cached.route;\n\n\tconst base = parseFastPathPattern(element.pattern);\n\tif (base === undefined) {\n\t\tfastPathRouteCache.set(element, {\n\t\t\tversion: currentRoutingConfigVersion(),\n\t\t\troute: null,\n\t\t});\n\t\treturn null;\n\t}\n\n\tconst localized = [];\n\tfor (const [locale, pattern] of element.localized) {\n\t\tconst parsed = parseFastPathPattern(pattern);\n\t\tif (parsed === undefined || parsed.pathMode !== base.pathMode) {\n\t\t\tfastPathRouteCache.set(element, {\n\t\t\t\tversion: currentRoutingConfigVersion(),\n\t\t\t\troute: null,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t\tlocalized.push({ locale, pattern: parsed });\n\t}\n\n\tconst route = { base, localized };\n\tfastPathRouteCache.set(element, {\n\t\tversion: currentRoutingConfigVersion(),\n\t\troute,\n\t});\n\treturn route;\n}\n\n/**\n * Parse only catch-all path patterns. In particular, do not treat `:path(.)?`\n * as a catch-all: URLPattern's `(.)` means exactly one character and cannot be\n * represented by this prefix matcher without changing routing semantics.\n *\n * @param {string} pattern\n * @returns {FastPathPattern | undefined}\n */\nfunction parseFastPathPattern(pattern) {\n\tconst wildcard = pattern.match(/\\/:path(?:\\(\\.\\*\\)(?:\\?)?|\\*)$/);\n\tif (wildcard === null || wildcard.index === undefined) return undefined;\n\n\tconst prefix = pattern.slice(0, wildcard.index);\n\tconst originAndPath = parseFastPathOriginAndPath(prefix);\n\tif (originAndPath === undefined) return undefined;\n\tconst pathMode = wildcard[0].endsWith(\"*\")\n\t\t? \"segments\"\n\t\t: wildcard[0].endsWith(\"?\")\n\t\t\t? \"catch-all-optional\"\n\t\t\t: \"catch-all-required\";\n\n\treturn { ...originAndPath, pathMode };\n}\n\n/**\n * @param {string} prefix\n * @returns {FastPathPattern | undefined}\n */\nfunction parseFastPathOriginAndPath(prefix) {\n\tif (prefix === \"\" || prefix.startsWith(\"/\")) {\n\t\tif (hasUrlPatternSyntax(prefix)) return undefined;\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\thostname: undefined,\n\t\t\tport: undefined,\n\t\t\tpathnamePrefix: normalizePathPrefix(prefix),\n\t\t\tpathMode: \"catch-all-optional\",\n\t\t};\n\t}\n\n\t// A `:protocol://host` pattern is common in generated configurations. The\n\t// protocol is intentionally left unconstrained, just like URLPattern.\n\tconst dynamicProtocol = prefix.match(/^:protocol:\\/\\/([^/]+)(\\/.*)?$/);\n\tconst staticOrigin = prefix.match(\n\t\t/^([A-Za-z][A-Za-z\\d+.-]*):\\/\\/([^/]+)(\\/.*)?$/\n\t);\n\tif (dynamicProtocol !== null) {\n\t\tconst dynamicHost = dynamicProtocol[1] ?? \"\";\n\t\tconst hostMatch = dynamicHost.match(/^([^:(){}?*+]+)(?::(\\d+))?$/);\n\t\tif (\n\t\t\thostMatch === null ||\n\t\t\t(dynamicProtocol[2] !== undefined &&\n\t\t\t\thasUrlPatternSyntax(dynamicProtocol[2]))\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\thostname: (hostMatch[1] ?? \"\").toLowerCase(),\n\t\t\tport: hostMatch[2],\n\t\t\tpathnamePrefix: normalizePathPrefix(dynamicProtocol[2] ?? \"\"),\n\t\t\tpathMode: \"catch-all-optional\",\n\t\t};\n\t}\n\n\tif (staticOrigin === null) return undefined;\n\n\tconst host = staticOrigin[2] ?? \"\";\n\tconst pathname = staticOrigin[3];\n\tconst hostMatch = host.match(/^([^:(){}?*+]+)(?::(\\d+))?$/);\n\tif (\n\t\thostMatch === null ||\n\t\t(pathname !== undefined && hasUrlPatternSyntax(pathname))\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tprotocol: `${staticOrigin[1]}:`,\n\t\thostname: (hostMatch[1] ?? \"\").toLowerCase(),\n\t\tport: normalizePatternPort(hostMatch[2], `${staticOrigin[1]}:`),\n\t\tpathnamePrefix: normalizePathPrefix(pathname ?? \"\"),\n\t\tpathMode: \"catch-all-optional\",\n\t};\n}\n\n/**\n * @param {string | undefined} port\n * @param {string} protocol\n * @returns {string | undefined}\n */\nfunction normalizePatternPort(port, protocol) {\n\tif (port === \"80\" && protocol === \"http:\") return \"\";\n\tif (port === \"443\" && protocol === \"https:\") return \"\";\n\treturn port;\n}\n\n/**\n * @param {string} value\n * @returns {boolean}\n */\nfunction hasUrlPatternSyntax(value) {\n\treturn /[:(){}?*+]/.test(value);\n}\n\n/**\n * @param {string} pathname\n * @returns {string}\n */\nfunction normalizePathPrefix(pathname) {\n\tif (pathname === \"\" || pathname === \"/\") return \"/\";\n\treturn pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n}\n\n/**\n * @param {FastPathPattern} pattern\n * @param {URL} urlObj\n * @returns {string | undefined}\n */\nfunction matchFastPathPattern(pattern, urlObj) {\n\tif (pattern.protocol !== undefined && pattern.protocol !== urlObj.protocol) {\n\t\treturn undefined;\n\t}\n\tif (\n\t\tpattern.hostname !== undefined &&\n\t\tpattern.hostname !== urlObj.hostname.toLowerCase()\n\t) {\n\t\treturn undefined;\n\t}\n\tif (pattern.hostname !== undefined) {\n\t\tconst expectedPort =\n\t\t\tpattern.port ??\n\t\t\tdefaultPortForProtocol(pattern.protocol ?? urlObj.protocol);\n\t\tif (expectedPort !== urlObj.port) return undefined;\n\t}\n\n\tconst prefix = pattern.pathnamePrefix;\n\tif (prefix === \"/\") {\n\t\tif (urlObj.pathname.startsWith(\"//\")) return undefined;\n\t\tif (pattern.pathMode === \"segments\") {\n\t\t\treturn isNonEmptyPathSegments(urlObj.pathname)\n\t\t\t\t? urlObj.pathname\n\t\t\t\t: undefined;\n\t\t}\n\t\treturn urlObj.pathname;\n\t}\n\tif (urlObj.pathname === prefix) {\n\t\treturn pattern.pathMode === \"catch-all-required\" ? undefined : \"\";\n\t}\n\tif (urlObj.pathname.startsWith(`${prefix}/`)) {\n\t\tconst suffix = urlObj.pathname.slice(prefix.length);\n\t\tif (suffix.startsWith(\"//\")) return undefined;\n\t\tif (pattern.pathMode === \"segments\" && !isNonEmptyPathSegments(suffix)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn suffix;\n\t}\n\treturn undefined;\n}\n\n/**\n * @param {string} pathname\n * @returns {boolean}\n */\nfunction isNonEmptyPathSegments(pathname) {\n\treturn (\n\t\tpathname.length > 1 && !pathname.endsWith(\"/\") && !pathname.includes(\"//\")\n\t);\n}\n\n/**\n * URLPattern treats the default port as empty in URL instances.\n *\n * @param {string} protocol\n * @returns {string}\n */\nfunction defaultPortForProtocol(protocol) {\n\tif (protocol === \"http:\") return \"\";\n\tif (protocol === \"https:\") return \"\";\n\treturn \"\";\n}\n\n/**\n * @param {FastPathPattern} pattern\n * @param {string} suffix\n * @param {URL} source\n * @returns {URL}\n */\nfunction applyFastPathPattern(pattern, suffix, source) {\n\tconst localized = new URL(source.href);\n\tif (pattern.protocol !== undefined) localized.protocol = pattern.protocol;\n\tif (pattern.hostname !== undefined) {\n\t\tlocalized.hostname = pattern.hostname;\n\t\tlocalized.port = pattern.port ?? defaultPortForProtocol(localized.protocol);\n\t}\n\tlocalized.pathname = joinFastPathPrefix(pattern.pathnamePrefix, suffix);\n\treturn localized;\n}\n\n/**\n * @param {string} prefix\n * @param {string} suffix\n * @returns {string}\n */\nfunction joinFastPathPrefix(prefix, suffix) {\n\tif (prefix === \"/\") return suffix === \"\" ? \"/\" : suffix;\n\tif (suffix === \"\") return prefix;\n\treturn `${prefix}${suffix.startsWith(\"/\") ? suffix : `/${suffix}`}`;\n}\n"]}
1
+ {"version":3,"file":"localize-url.js","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-url.js"],"names":[],"mappings":"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","sourcesContent":["import { extractLocaleFromUrl } from \"./extract-locale-from-url.js\";\nimport { getLocale } from \"./get-locale.js\";\nimport { getUrlOrigin } from \"./get-url-origin.js\";\nimport { assertIsLocale, toLocale } from \"./check-locale.js\";\nimport {\n\tbaseLocale,\n\tTREE_SHAKE_DEFAULT_URL_PATTERN_USED,\n\ttrailingSlash,\n} from \"./variables.js\";\nimport { normalizeTrailingSlash } from \"./normalize-trailing-slash.js\";\nimport { execUrlPattern } from \"./exec-url-pattern.js\";\nimport { getUrlPattern } from \"./url-pattern-cache.js\";\nimport {\n\tgetUrlPatternCandidates,\n\tcurrentRoutingConfigVersion,\n} from \"./url-pattern-index.js\";\n\n/**\n * Lower-level URL localization function, primarily used in server contexts.\n *\n * This function is designed for server-side usage where you need precise control\n * over URL localization, such as in middleware or request handlers. It works with\n * URL objects and always returns absolute URLs.\n *\n * For client-side UI components, use `localizeHref()` instead, which provides\n * a more convenient API with relative paths and automatic locale detection.\n *\n * @see https://paraglidejs.com/i18n-routing\n *\n * @example\n * ```typescript\n * // Server middleware example\n * app.use((req, res, next) => {\n * const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);\n * const localized = localizeUrl(url, { locale: \"de\" });\n *\n * if (localized.href !== url.href) {\n * return res.redirect(localized.href);\n * }\n * next();\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Using with URL patterns\n * const url = new URL(\"https://example.com/about\");\n * localizeUrl(url, { locale: \"de\" });\n * // => URL(\"https://example.com/de/about\")\n *\n * // Using with domain-based localization\n * const url = new URL(\"https://example.com/store\");\n * localizeUrl(url, { locale: \"de\" });\n * // => URL(\"https://de.example.com/store\")\n * ```\n *\n * @param {string | { readonly href: string }} url - The URL to localize. Accepts readonly URL objects. If string, must be absolute.\n * @param {object} [options] - Options for localization\n * @param {Locale} [options.locale] - Target locale. If not provided, uses getLocale()\n * @returns {URL} The localized URL, always absolute\n */\nexport function localizeUrl(url, options) {\n\tconst targetLocale = options?.locale\n\t\t? assertIsLocale(options?.locale)\n\t\t: getLocale();\n\n\tif (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {\n\t\treturn localizeUrlDefaultPattern(url, targetLocale);\n\t}\n\n\tconst originalUrl =\n\t\turl instanceof URL\n\t\t\t? url\n\t\t\t: new URL(typeof url === \"string\" ? url : url.href);\n\tconst urlObj =\n\t\ttrailingSlash === undefined\n\t\t\t? originalUrl\n\t\t\t: normalizeTrailingSlash(new URL(originalUrl));\n\n\t// Iterate over URL patterns\n\tfor (const element of getUrlPatternCandidates(urlObj)) {\n\t\t// Most applications use a locale prefix (and sometimes a fixed domain)\n\t\t// with a trailing catch-all path. Those routes do not need URLPattern's\n\t\t// parser or matcher on every call. Keep the generic matcher below as the\n\t\t// fallback for every other URLPattern shape. This stays inside the outer\n\t\t// loop so specific patterns retain precedence over a later catch-all.\n\t\tconst fastPathLocalized = localizeUrlFastPath(\n\t\t\turlObj,\n\t\t\ttargetLocale,\n\t\t\telement\n\t\t);\n\t\tif (fastPathLocalized !== undefined) {\n\t\t\treturn fastPathLocalized;\n\t\t}\n\n\t\t// match localized patterns\n\t\tfor (const [, localizedPattern] of element.localized) {\n\t\t\tconst match = execUrlPattern(\n\t\t\t\tgetUrlPattern(localizedPattern, urlObj),\n\t\t\t\turlObj\n\t\t\t);\n\n\t\t\tif (!match) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst targetPattern = element.localized.find(\n\t\t\t\t([locale]) => locale === targetLocale\n\t\t\t)?.[1];\n\n\t\t\tif (!targetPattern) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst localizedUrl = fillPattern(\n\t\t\t\ttargetPattern,\n\t\t\t\taggregateGroups(match),\n\t\t\t\turlObj.origin\n\t\t\t);\n\t\t\treturn normalizeTrailingSlash(fillMissingUrlParts(localizedUrl, match));\n\t\t}\n\t\tconst unlocalizedMatch = execUrlPattern(\n\t\t\tgetUrlPattern(element.pattern, urlObj),\n\t\t\turlObj\n\t\t);\n\t\tif (unlocalizedMatch) {\n\t\t\tconst targetPattern = element.localized.find(\n\t\t\t\t([locale]) => locale === targetLocale\n\t\t\t)?.[1];\n\t\t\tif (targetPattern) {\n\t\t\t\tconst localizedUrl = fillPattern(\n\t\t\t\t\ttargetPattern,\n\t\t\t\t\taggregateGroups(unlocalizedMatch),\n\t\t\t\t\turlObj.origin\n\t\t\t\t);\n\t\t\t\treturn normalizeTrailingSlash(\n\t\t\t\t\tfillMissingUrlParts(localizedUrl, unlocalizedMatch)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\t// If no match found, return the original URL\n\treturn originalUrl;\n}\n\n/**\n * https://github.com/opral/inlang-paraglide-js/issues/381\n *\n * @param {string | { readonly href: string }} url\n * @param {Locale} locale\n * @returns {URL}\n */\nfunction localizeUrlDefaultPattern(url, locale) {\n\tconst urlObj = normalizeTrailingSlash(\n\t\ttypeof url === \"string\" ? new URL(url, getUrlOrigin()) : new URL(url.href)\n\t);\n\n\tconst currentLocale = extractLocaleFromUrl(urlObj);\n\n\t// If current locale matches target locale, no change needed\n\tif (currentLocale === locale) {\n\t\treturn normalizeTrailingSlash(urlObj);\n\t}\n\n\t// Ignore leading separators like locale detection, preserving the remaining path.\n\tconst pathSegments = urlObj.pathname.replace(/^\\/+/, \"\").split(\"/\");\n\n\t// If current path starts with a locale, remove it\n\tif (pathSegments.length > 0 && toLocale(pathSegments[0])) {\n\t\tpathSegments.shift();\n\t}\n\n\t// For base locale, don't add prefix\n\tif (locale === baseLocale) {\n\t\turlObj.pathname = \"/\" + pathSegments.join(\"/\");\n\t} else {\n\t\t// For other locales, add prefix\n\t\turlObj.pathname = \"/\" + locale + \"/\" + pathSegments.join(\"/\");\n\t}\n\n\treturn normalizeTrailingSlash(urlObj);\n}\n\n/**\n * Low-level URL de-localization function, primarily used in server contexts.\n *\n * This function is designed for server-side usage where you need precise control\n * over URL de-localization, such as in middleware or request handlers. It works with\n * URL objects and always returns absolute URLs.\n *\n * For client-side UI components, use `deLocalizeHref()` instead, which provides\n * a more convenient API with relative paths.\n *\n * @see https://paraglidejs.com/i18n-routing\n *\n * @example\n * ```typescript\n * // Server middleware example\n * app.use((req, res, next) => {\n * const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);\n * const baseUrl = deLocalizeUrl(url);\n *\n * // Store the base URL for later use\n * req.baseUrl = baseUrl;\n * next();\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Using with URL patterns\n * const url = new URL(\"https://example.com/de/about\");\n * deLocalizeUrl(url); // => URL(\"https://example.com/about\")\n *\n * // Using with domain-based localization\n * const url = new URL(\"https://de.example.com/store\");\n * deLocalizeUrl(url); // => URL(\"https://example.com/store\")\n * ```\n *\n * @param {string | { readonly href: string }} url - The URL to de-localize. Accepts readonly URL objects. If string, must be absolute.\n * @returns {URL} The de-localized URL, always absolute\n */\nexport function deLocalizeUrl(url) {\n\tif (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {\n\t\treturn deLocalizeUrlDefaultPattern(url);\n\t}\n\n\tconst originalUrl =\n\t\turl instanceof URL\n\t\t\t? url\n\t\t\t: new URL(typeof url === \"string\" ? url : url.href);\n\tconst urlObj =\n\t\ttrailingSlash === undefined\n\t\t\t? originalUrl\n\t\t\t: normalizeTrailingSlash(new URL(originalUrl));\n\n\t// Iterate over URL patterns\n\tfor (const element of getUrlPatternCandidates(urlObj)) {\n\t\tconst fastPathDeLocalized = deLocalizeUrlFastPath(urlObj, element);\n\t\tif (fastPathDeLocalized !== undefined) {\n\t\t\treturn fastPathDeLocalized;\n\t\t}\n\n\t\t// Iterate over localized versions\n\t\tfor (const [, localizedPattern] of element.localized) {\n\t\t\tconst match = execUrlPattern(\n\t\t\t\tgetUrlPattern(localizedPattern, urlObj),\n\t\t\t\turlObj\n\t\t\t);\n\n\t\t\tif (match) {\n\t\t\t\t// Convert localized URL back to the base pattern\n\t\t\t\tconst groups = aggregateGroups(match);\n\n\t\t\t\tconst baseUrl = fillPattern(element.pattern, groups, urlObj.origin);\n\t\t\t\treturn normalizeTrailingSlash(fillMissingUrlParts(baseUrl, match));\n\t\t\t}\n\t\t}\n\t\t// match unlocalized pattern\n\t\tconst unlocalizedMatch = execUrlPattern(\n\t\t\tgetUrlPattern(element.pattern, urlObj),\n\t\t\turlObj\n\t\t);\n\t\tif (unlocalizedMatch) {\n\t\t\tconst baseUrl = fillPattern(\n\t\t\t\telement.pattern,\n\t\t\t\taggregateGroups(unlocalizedMatch),\n\t\t\t\turlObj.origin\n\t\t\t);\n\t\t\treturn normalizeTrailingSlash(\n\t\t\t\tfillMissingUrlParts(baseUrl, unlocalizedMatch)\n\t\t\t);\n\t\t}\n\t}\n\t// no match found return the original url\n\treturn originalUrl;\n}\n\n/**\n * De-localizes a URL using the default pattern (/:locale/*)\n * @param {string | { readonly href: string }} url\n * @returns {URL}\n */\nfunction deLocalizeUrlDefaultPattern(url) {\n\tconst urlObj = normalizeTrailingSlash(\n\t\ttypeof url === \"string\" ? new URL(url, getUrlOrigin()) : new URL(url.href)\n\t);\n\t// Ignore leading separators like locale detection, preserving the remaining path.\n\tconst pathSegments = urlObj.pathname.replace(/^\\/+/, \"\").split(\"/\");\n\n\t// If first segment is a locale, remove it\n\tif (pathSegments.length > 0 && toLocale(pathSegments[0])) {\n\t\turlObj.pathname = \"/\" + pathSegments.slice(1).join(\"/\");\n\t}\n\n\treturn normalizeTrailingSlash(urlObj);\n}\n\n/**\n * Takes matches of implicit wildcards in the UrlPattern (when a part is missing\n * it is equal to '*') and adds them back to the result of fillPattern.\n *\n * At least protocol and hostname are required to create a valid URL inside fillPattern.\n *\n * @param {URL} url\n * @param {any} match\n * @returns {URL}\n */\nfunction fillMissingUrlParts(url, match) {\n\tif (match.protocol.groups[\"0\"]) {\n\t\turl.protocol = match.protocol.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.hostname.groups[\"0\"]) {\n\t\turl.hostname = match.hostname.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.username.groups[\"0\"]) {\n\t\turl.username = match.username.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.password.groups[\"0\"]) {\n\t\turl.password = match.password.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.port.groups[\"0\"]) {\n\t\turl.port = match.port.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.pathname.groups[\"0\"]) {\n\t\turl.pathname = match.pathname.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.search.groups[\"0\"]) {\n\t\turl.search = match.search.groups[\"0\"] ?? \"\";\n\t}\n\tif (match.hash.groups[\"0\"]) {\n\t\turl.hash = match.hash.groups[\"0\"] ?? \"\";\n\t}\n\n\treturn url;\n}\n\n/**\n * Fills a URL pattern with values for named groups, supporting all URLPattern-style modifiers.\n *\n * This function will eventually be replaced by https://github.com/whatwg/urlpattern/issues/73\n *\n * Matches:\n * - :name -> Simple\n * - :name? -> Optional\n * - :name+ -> One or more\n * - :name* -> Zero or more\n * - :name(...) -> Regex group\n * - {text} -> Group delimiter\n * - {text}? -> Optional group delimiter\n *\n * If the value is `null`, the segment is removed.\n *\n * @param {string} pattern - The URL pattern containing named groups.\n * @param {Record<string, string | null | undefined>} values - Object of values for named groups.\n * @param {string} origin - Base URL to use for URL construction.\n * @returns {URL} - The constructed URL with named groups filled.\n */\nfunction fillPattern(pattern, values, origin) {\n\t// Pre-process the pattern to handle explicit port numbers\n\t// This detects patterns like \"http://localhost:5173\" and protects the port number\n\t// from being interpreted as a parameter\n\tlet processedPattern = pattern.replace(\n\t\t/(https?:\\/\\/[^:/]+):(\\d+)(\\/|$)/g,\n\t\t(_, protocol, port, slash) => {\n\t\t\t// Replace \":5173\" with \"#PORT-5173#\" to protect it from parameter replacement\n\t\t\treturn `${protocol}#PORT-${port}#${slash}`;\n\t\t}\n\t);\n\n\t// First, handle group delimiters with curly braces\n\tlet processedGroupDelimiters = processedPattern.replace(\n\t\t/\\{([^{}]*)\\}([?+*]?)/g,\n\t\t(_, content, modifier) => {\n\t\t\t// For optional group delimiters\n\t\t\tif (modifier === \"?\") {\n\t\t\t\t// For optional groups, we'll include the content\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\t// For non-optional group delimiters, always include the content\n\t\t\treturn content;\n\t\t}\n\t);\n\n\t// Then handle named groups\n\tlet filled = processedGroupDelimiters.replace(\n\t\t/(\\/?):([a-zA-Z0-9_]+)(\\([^)]*\\))?([?+*]?)/g,\n\t\t(_, slash, name, __, modifier) => {\n\t\t\tconst value = values[name];\n\n\t\t\tif (value === null) {\n\t\t\t\t// If value is null, remove the entire segment including the preceding slash\n\t\t\t\treturn \"\";\n\t\t\t}\n\n\t\t\tif (modifier === \"?\") {\n\t\t\t\t// Optional segment\n\t\t\t\treturn value !== undefined ? `${slash}${value}` : \"\";\n\t\t\t}\n\n\t\t\tif (modifier === \"+\" || modifier === \"*\") {\n\t\t\t\t// Repeatable segments\n\t\t\t\tif (value === undefined && modifier === \"+\") {\n\t\t\t\t\tthrow new Error(`Missing value for \"${name}\" (one or more required)`);\n\t\t\t\t}\n\t\t\t\treturn value ? `${slash}${value}` : \"\";\n\t\t\t}\n\n\t\t\t// Simple named group (no modifier)\n\t\t\tif (value === undefined) {\n\t\t\t\tthrow new Error(`Missing value for \"${name}\"`);\n\t\t\t}\n\n\t\t\treturn `${slash}${value}`;\n\t\t}\n\t);\n\n\t// Restore port numbers\n\tfilled = filled.replace(/#PORT-(\\d+)#/g, \":$1\");\n\n\treturn new URL(filled, origin);\n}\n\n/**\n * Aggregates named groups from various parts of the URLPattern match result.\n *\n *\n * @param {any} match - The URLPattern match result object.\n * @returns {Record<string, string | null | undefined>} An object containing all named groups from the match.\n */\nexport function aggregateGroups(match) {\n\treturn {\n\t\t...match.hash.groups,\n\t\t...match.hostname.groups,\n\t\t...match.password.groups,\n\t\t...match.pathname.groups,\n\t\t...match.port.groups,\n\t\t...match.protocol.groups,\n\t\t...match.search.groups,\n\t\t...match.username.groups,\n\t};\n}\n\n/**\n * A small, deliberately conservative subset of URLPattern routing.\n *\n * The compiler emits routes such as `/:path(.*)?`, `/de/:path*`, or\n * `https://example.com/:path*`. For those routes matching is equivalent to a\n * pathname prefix check and (optionally) an origin check. Everything that has\n * a dynamic host, a custom path regexp, or another URLPattern modifier keeps\n * using the generic implementation above.\n *\n * @typedef {{\n * protocol: string | undefined;\n * hostname: string | undefined;\n * port: string | undefined;\n * pathnamePrefix: string;\n * pathMode: \"segments\" | \"catch-all-optional\" | \"catch-all-required\";\n * }} FastPathPattern\n * @typedef {{\n * base: FastPathPattern;\n * localized: Array<{ locale: string; pattern: FastPathPattern }>;\n * }} FastPathRoute\n */\n\n/** @type {WeakMap<object, { version: number; route: FastPathRoute | null }>} */\nconst fastPathRouteCache = new WeakMap();\n\n/**\n * @param {URL} urlObj\n * @param {string} targetLocale\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {URL | undefined}\n */\nfunction localizeUrlFastPath(urlObj, targetLocale, element) {\n\tconst route = getFastPathRoute(element);\n\tif (route === null) return undefined;\n\n\t// Preserve URLPattern's ordering: localized patterns are checked before\n\t// the unlocalized pattern, and the first matching pattern wins.\n\tfor (const localized of route.localized) {\n\t\tconst suffix = matchFastPathPattern(localized.pattern, urlObj);\n\t\tif (suffix === undefined) continue;\n\n\t\tconst target = route.localized.find(\n\t\t\t(candidate) => candidate.locale === targetLocale\n\t\t)?.pattern;\n\t\tif (target === undefined) continue;\n\n\t\treturn applyFastPathPattern(target, suffix, urlObj);\n\t}\n\n\tconst suffix = matchFastPathPattern(route.base, urlObj);\n\tif (suffix !== undefined) {\n\t\tconst target = route.localized.find(\n\t\t\t(candidate) => candidate.locale === targetLocale\n\t\t)?.pattern;\n\t\tif (target !== undefined) {\n\t\t\treturn applyFastPathPattern(target, suffix, urlObj);\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\n/**\n * @param {URL} urlObj\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {URL | undefined}\n */\nfunction deLocalizeUrlFastPath(urlObj, element) {\n\tconst route = getFastPathRoute(element);\n\tif (route === null) return undefined;\n\n\tfor (const localized of route.localized) {\n\t\tconst suffix = matchFastPathPattern(localized.pattern, urlObj);\n\t\tif (suffix !== undefined) {\n\t\t\treturn applyFastPathPattern(route.base, suffix, urlObj);\n\t\t}\n\t}\n\n\tconst suffix = matchFastPathPattern(route.base, urlObj);\n\tif (suffix !== undefined) {\n\t\treturn applyFastPathPattern(route.base, suffix, urlObj);\n\t}\n\n\treturn undefined;\n}\n\n/**\n * @param {{ pattern: string; localized: Array<[string, string]> }} element\n * @returns {FastPathRoute | null}\n */\nfunction getFastPathRoute(element) {\n\tconst cached = fastPathRouteCache.get(element);\n\tif (cached?.version === currentRoutingConfigVersion()) return cached.route;\n\n\tconst base = parseFastPathPattern(element.pattern);\n\tif (base === undefined) {\n\t\tfastPathRouteCache.set(element, {\n\t\t\tversion: currentRoutingConfigVersion(),\n\t\t\troute: null,\n\t\t});\n\t\treturn null;\n\t}\n\n\tconst localized = [];\n\tfor (const [locale, pattern] of element.localized) {\n\t\tconst parsed = parseFastPathPattern(pattern);\n\t\tif (parsed === undefined || parsed.pathMode !== base.pathMode) {\n\t\t\tfastPathRouteCache.set(element, {\n\t\t\t\tversion: currentRoutingConfigVersion(),\n\t\t\t\troute: null,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t\tlocalized.push({ locale, pattern: parsed });\n\t}\n\n\tconst route = { base, localized };\n\tfastPathRouteCache.set(element, {\n\t\tversion: currentRoutingConfigVersion(),\n\t\troute,\n\t});\n\treturn route;\n}\n\n/**\n * Parse only catch-all path patterns. In particular, do not treat `:path(.)?`\n * as a catch-all: URLPattern's `(.)` means exactly one character and cannot be\n * represented by this prefix matcher without changing routing semantics.\n *\n * @param {string} pattern\n * @returns {FastPathPattern | undefined}\n */\nfunction parseFastPathPattern(pattern) {\n\tconst wildcard = pattern.match(/\\/:path(?:\\(\\.\\*\\)(?:\\?)?|\\*)$/);\n\tif (wildcard === null || wildcard.index === undefined) return undefined;\n\n\tconst prefix = pattern.slice(0, wildcard.index);\n\tconst originAndPath = parseFastPathOriginAndPath(prefix);\n\tif (originAndPath === undefined) return undefined;\n\tconst pathMode = wildcard[0].endsWith(\"*\")\n\t\t? \"segments\"\n\t\t: wildcard[0].endsWith(\"?\")\n\t\t\t? \"catch-all-optional\"\n\t\t\t: \"catch-all-required\";\n\n\treturn { ...originAndPath, pathMode };\n}\n\n/**\n * @param {string} prefix\n * @returns {FastPathPattern | undefined}\n */\nfunction parseFastPathOriginAndPath(prefix) {\n\tif (prefix === \"\" || prefix.startsWith(\"/\")) {\n\t\tif (hasUrlPatternSyntax(prefix)) return undefined;\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\thostname: undefined,\n\t\t\tport: undefined,\n\t\t\tpathnamePrefix: normalizePathPrefix(prefix),\n\t\t\tpathMode: \"catch-all-optional\",\n\t\t};\n\t}\n\n\t// A `:protocol://host` pattern is common in generated configurations. The\n\t// protocol is intentionally left unconstrained, just like URLPattern.\n\tconst dynamicProtocol = prefix.match(/^:protocol:\\/\\/([^/]+)(\\/.*)?$/);\n\tconst staticOrigin = prefix.match(\n\t\t/^([A-Za-z][A-Za-z\\d+.-]*):\\/\\/([^/]+)(\\/.*)?$/\n\t);\n\tif (dynamicProtocol !== null) {\n\t\tconst dynamicHost = dynamicProtocol[1] ?? \"\";\n\t\tconst hostMatch = dynamicHost.match(/^([^:(){}?*+]+)(?::(\\d+))?$/);\n\t\tif (\n\t\t\thostMatch === null ||\n\t\t\t(dynamicProtocol[2] !== undefined &&\n\t\t\t\thasUrlPatternSyntax(dynamicProtocol[2]))\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tprotocol: undefined,\n\t\t\thostname: (hostMatch[1] ?? \"\").toLowerCase(),\n\t\t\tport: hostMatch[2],\n\t\t\tpathnamePrefix: normalizePathPrefix(dynamicProtocol[2] ?? \"\"),\n\t\t\tpathMode: \"catch-all-optional\",\n\t\t};\n\t}\n\n\tif (staticOrigin === null) return undefined;\n\n\tconst host = staticOrigin[2] ?? \"\";\n\tconst pathname = staticOrigin[3];\n\tconst hostMatch = host.match(/^([^:(){}?*+]+)(?::(\\d+))?$/);\n\tif (\n\t\thostMatch === null ||\n\t\t(pathname !== undefined && hasUrlPatternSyntax(pathname))\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tprotocol: `${staticOrigin[1]}:`,\n\t\thostname: (hostMatch[1] ?? \"\").toLowerCase(),\n\t\tport: normalizePatternPort(hostMatch[2], `${staticOrigin[1]}:`),\n\t\tpathnamePrefix: normalizePathPrefix(pathname ?? \"\"),\n\t\tpathMode: \"catch-all-optional\",\n\t};\n}\n\n/**\n * @param {string | undefined} port\n * @param {string} protocol\n * @returns {string | undefined}\n */\nfunction normalizePatternPort(port, protocol) {\n\tif (port === \"80\" && protocol === \"http:\") return \"\";\n\tif (port === \"443\" && protocol === \"https:\") return \"\";\n\treturn port;\n}\n\n/**\n * @param {string} value\n * @returns {boolean}\n */\nfunction hasUrlPatternSyntax(value) {\n\treturn /[:(){}?*+]/.test(value);\n}\n\n/**\n * @param {string} pathname\n * @returns {string}\n */\nfunction normalizePathPrefix(pathname) {\n\tif (pathname === \"\" || pathname === \"/\") return \"/\";\n\treturn pathname.endsWith(\"/\") ? pathname.slice(0, -1) : pathname;\n}\n\n/**\n * @param {FastPathPattern} pattern\n * @param {URL} urlObj\n * @returns {string | undefined}\n */\nfunction matchFastPathPattern(pattern, urlObj) {\n\tif (pattern.protocol !== undefined && pattern.protocol !== urlObj.protocol) {\n\t\treturn undefined;\n\t}\n\tif (\n\t\tpattern.hostname !== undefined &&\n\t\tpattern.hostname !== urlObj.hostname.toLowerCase()\n\t) {\n\t\treturn undefined;\n\t}\n\tif (pattern.hostname !== undefined) {\n\t\tconst expectedPort =\n\t\t\tpattern.port ??\n\t\t\tdefaultPortForProtocol(pattern.protocol ?? urlObj.protocol);\n\t\tif (expectedPort !== urlObj.port) return undefined;\n\t}\n\n\tconst prefix = pattern.pathnamePrefix;\n\tif (prefix === \"/\") {\n\t\tif (urlObj.pathname.startsWith(\"//\")) return undefined;\n\t\tif (pattern.pathMode === \"segments\") {\n\t\t\treturn isNonEmptyPathSegments(urlObj.pathname)\n\t\t\t\t? urlObj.pathname\n\t\t\t\t: undefined;\n\t\t}\n\t\treturn urlObj.pathname;\n\t}\n\tif (urlObj.pathname === prefix) {\n\t\treturn pattern.pathMode === \"catch-all-required\" ? undefined : \"\";\n\t}\n\tif (urlObj.pathname.startsWith(`${prefix}/`)) {\n\t\tconst suffix = urlObj.pathname.slice(prefix.length);\n\t\tif (suffix.startsWith(\"//\")) return undefined;\n\t\tif (pattern.pathMode === \"segments\" && !isNonEmptyPathSegments(suffix)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn suffix;\n\t}\n\treturn undefined;\n}\n\n/**\n * @param {string} pathname\n * @returns {boolean}\n */\nfunction isNonEmptyPathSegments(pathname) {\n\treturn (\n\t\tpathname.length > 1 && !pathname.endsWith(\"/\") && !pathname.includes(\"//\")\n\t);\n}\n\n/**\n * URLPattern treats the default port as empty in URL instances.\n *\n * @param {string} protocol\n * @returns {string}\n */\nfunction defaultPortForProtocol(protocol) {\n\tif (protocol === \"http:\") return \"\";\n\tif (protocol === \"https:\") return \"\";\n\treturn \"\";\n}\n\n/**\n * @param {FastPathPattern} pattern\n * @param {string} suffix\n * @param {URL} source\n * @returns {URL}\n */\nfunction applyFastPathPattern(pattern, suffix, source) {\n\tconst localized = new URL(source.href);\n\tif (pattern.protocol !== undefined) localized.protocol = pattern.protocol;\n\tif (pattern.hostname !== undefined) {\n\t\tlocalized.hostname = pattern.hostname;\n\t\tlocalized.port = pattern.port ?? defaultPortForProtocol(localized.protocol);\n\t}\n\tlocalized.pathname = joinFastPathPrefix(pattern.pathnamePrefix, suffix);\n\treturn localized;\n}\n\n/**\n * @param {string} prefix\n * @param {string} suffix\n * @returns {string}\n */\nfunction joinFastPathPrefix(prefix, suffix) {\n\tif (prefix === \"/\") return suffix === \"\" ? \"/\" : suffix;\n\tif (suffix === \"\") return prefix;\n\treturn `${prefix}${suffix.startsWith(\"/\") ? suffix : `/${suffix}`}`;\n}\n"]}