@inlang/paraglide-js 2.0.0-beta.15 → 2.0.0-beta.17
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/unplugin.d.ts.map +1 -1
- package/dist/bundler-plugins/unplugin.js +10 -3
- package/dist/cli/steps/run-compiler.js +1 -1
- package/dist/compiler/compile-bundle.d.ts.map +1 -1
- package/dist/compiler/compile-bundle.js +9 -4
- package/dist/compiler/compile-bundle.test.js +11 -0
- package/dist/compiler/compile-message.d.ts +0 -3
- package/dist/compiler/compile-message.d.ts.map +1 -1
- package/dist/compiler/compile-message.js +14 -9
- package/dist/compiler/compile-message.test.js +25 -3
- package/dist/compiler/compile-project.d.ts.map +1 -1
- package/dist/compiler/compile-project.js +0 -3
- package/dist/compiler/compile-project.test.js +59 -66
- package/dist/compiler/compile.d.ts +41 -2
- package/dist/compiler/compile.d.ts.map +1 -1
- package/dist/compiler/compile.js +12 -4
- package/dist/compiler/compile.test.js +29 -7
- package/dist/compiler/jsdoc-types.d.ts +9 -3
- package/dist/compiler/jsdoc-types.d.ts.map +1 -1
- package/dist/compiler/jsdoc-types.js +15 -11
- package/dist/compiler/output-structure/locale-modules.d.ts.map +1 -1
- package/dist/compiler/output-structure/locale-modules.js +5 -8
- package/dist/compiler/runtime/assert-is-locale.js +1 -1
- package/dist/compiler/runtime/create-runtime.d.ts +3 -4
- package/dist/compiler/runtime/create-runtime.d.ts.map +1 -1
- package/dist/compiler/runtime/create-runtime.js +28 -11
- package/dist/compiler/runtime/de-localize-path.d.ts +2 -2
- package/dist/compiler/runtime/de-localize-path.d.ts.map +1 -1
- package/dist/compiler/runtime/de-localize-path.js +25 -6
- package/dist/compiler/runtime/de-localize-path.test.js +83 -21
- package/dist/compiler/runtime/de-localized-path.d.ts +27 -0
- package/dist/compiler/runtime/de-localized-path.d.ts.map +1 -0
- package/dist/compiler/runtime/de-localized-path.js +32 -0
- package/dist/compiler/runtime/de-localized-path.test.d.ts +2 -0
- package/dist/compiler/runtime/de-localized-path.test.d.ts.map +1 -0
- package/dist/compiler/runtime/de-localized-path.test.js +48 -0
- package/dist/compiler/runtime/detect-locale-from-request.d.ts +22 -0
- package/dist/compiler/runtime/detect-locale-from-request.d.ts.map +1 -0
- package/dist/compiler/runtime/detect-locale-from-request.js +44 -0
- package/dist/compiler/runtime/e2e.test.d.ts +2 -0
- package/dist/compiler/runtime/e2e.test.d.ts.map +1 -0
- package/dist/compiler/runtime/e2e.test.js +33 -0
- package/dist/compiler/runtime/extract-locale-from-cookie.js +1 -1
- package/dist/compiler/runtime/extract-locale-from-pathname.d.ts.map +1 -1
- package/dist/compiler/runtime/extract-locale-from-pathname.js +19 -3
- package/dist/compiler/runtime/extract-locale-from-pathname.test.js +83 -0
- package/dist/compiler/runtime/extract-locale-from-request.d.ts.map +1 -1
- package/dist/compiler/runtime/extract-locale-from-request.js +2 -4
- package/dist/compiler/runtime/extract-locale-from-request.test.js +5 -0
- package/dist/compiler/runtime/get-locale-from-path.d.ts +13 -0
- package/dist/compiler/runtime/get-locale-from-path.d.ts.map +1 -0
- package/dist/compiler/runtime/get-locale-from-path.js +17 -0
- package/dist/compiler/runtime/get-locale-from-path.test.d.ts +2 -0
- package/dist/compiler/runtime/get-locale-from-path.test.d.ts.map +1 -0
- package/dist/compiler/runtime/get-locale-from-path.test.js +22 -0
- package/dist/compiler/runtime/get-locale.d.ts.map +1 -1
- package/dist/compiler/runtime/get-locale.js +7 -5
- package/dist/compiler/runtime/get-locale.test.js +2 -2
- package/dist/compiler/runtime/is-locale.js +1 -1
- package/dist/compiler/runtime/jsdoc-runtime.d.ts +2 -0
- package/dist/compiler/runtime/jsdoc-runtime.d.ts.map +1 -0
- package/dist/compiler/runtime/jsdoc-runtime.js +131 -0
- package/dist/compiler/runtime/locale-in-path.d.ts +13 -0
- package/dist/compiler/runtime/locale-in-path.d.ts.map +1 -0
- package/dist/compiler/runtime/locale-in-path.js +17 -0
- package/dist/compiler/runtime/locale-in-path.test.d.ts +2 -0
- package/dist/compiler/runtime/locale-in-path.test.d.ts.map +1 -0
- package/dist/compiler/runtime/locale-in-path.test.js +22 -0
- package/dist/compiler/runtime/localize-path.d.ts +2 -2
- package/dist/compiler/runtime/localize-path.d.ts.map +1 -1
- package/dist/compiler/runtime/localize-path.js +61 -13
- package/dist/compiler/runtime/localize-path.test.js +192 -20
- package/dist/compiler/runtime/localized-path.d.ts +32 -0
- package/dist/compiler/runtime/localized-path.d.ts.map +1 -0
- package/dist/compiler/runtime/localized-path.js +44 -0
- package/dist/compiler/runtime/localized-path.test.d.ts +2 -0
- package/dist/compiler/runtime/localized-path.test.d.ts.map +1 -0
- package/dist/compiler/runtime/localized-path.test.js +42 -0
- package/dist/compiler/runtime/mock-runtime.d.ts +6 -0
- package/dist/compiler/runtime/mock-runtime.d.ts.map +1 -0
- package/dist/compiler/runtime/mock-runtime.js +31 -0
- package/dist/compiler/runtime/path-to-regexp.d.ts +2 -0
- package/dist/compiler/runtime/path-to-regexp.d.ts.map +1 -0
- package/dist/compiler/runtime/path-to-regexp.js +1 -0
- package/dist/compiler/runtime/pathname-pattern.d.ts +30 -0
- package/dist/compiler/runtime/pathname-pattern.d.ts.map +1 -0
- package/dist/compiler/runtime/pathname-pattern.js +99 -0
- package/dist/compiler/runtime/pathname-pattern.test.d.ts +2 -0
- package/dist/compiler/runtime/pathname-pattern.test.d.ts.map +1 -0
- package/dist/compiler/runtime/pathname-pattern.test.js +103 -0
- package/dist/compiler/runtime/set-locale.d.ts.map +1 -1
- package/dist/compiler/runtime/set-locale.js +5 -5
- package/dist/compiler/runtime/set-locale.test.js +1 -1
- package/dist/compiler/runtime/ts-runtime.d.ts +2 -0
- package/dist/compiler/runtime/ts-runtime.d.ts.map +1 -0
- package/dist/compiler/runtime/ts-runtime.js +119 -0
- package/dist/compiler/runtime/type.d.ts +2 -2
- package/dist/compiler/runtime/type.d.ts.map +1 -1
- package/dist/compiler/runtime/type.test.js +48 -11
- package/dist/compiler/runtime/variables.d.ts +46 -0
- package/dist/compiler/runtime/variables.d.ts.map +1 -0
- package/dist/compiler/runtime/variables.js +45 -0
- package/dist/compiler/strategy.d.ts +13 -0
- package/dist/compiler/strategy.d.ts.map +1 -0
- package/dist/compiler/strategy.js +12 -0
- package/dist/compiler/strategy.test.d.ts +2 -0
- package/dist/compiler/strategy.test.d.ts.map +1 -0
- package/dist/compiler/strategy.test.js +9 -0
- package/dist/path-to-regexp/index.d.ts +12 -0
- package/dist/path-to-regexp/index.d.ts.map +1 -0
- package/dist/path-to-regexp/index.js +11 -0
- package/dist/services/env-variables/index.js +1 -1
- package/dist/services/file-handling/write-output.d.ts +6 -1
- package/dist/services/file-handling/write-output.d.ts.map +1 -1
- package/dist/services/file-handling/write-output.js +33 -19
- package/dist/services/file-handling/write-output.test.js +60 -11
- package/dist/urlpattern-polyfill/index.d.ts +2 -0
- package/dist/urlpattern-polyfill/index.d.ts.map +1 -0
- package/dist/urlpattern-polyfill/index.js +1 -0
- package/package.json +12 -8
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
export function jsDocBundleFunctionTypes(args) {
|
|
2
|
-
const inputParams = args.inputs
|
|
3
|
-
.map((input) => {
|
|
4
|
-
return `${input.name}: NonNullable<unknown>`;
|
|
5
|
-
})
|
|
6
|
-
.join(", ");
|
|
7
2
|
const localesUnion = args.locales.map((locale) => `"${locale}"`).join(" | ");
|
|
8
3
|
return `
|
|
9
|
-
* @param {
|
|
4
|
+
* @param {${inputsType(args.inputs)}} inputs
|
|
10
5
|
* @param {{ locale?: ${localesUnion} }} options
|
|
11
6
|
* @returns {string}`;
|
|
12
7
|
}
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Returns the types for the input variables.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const inputs = [{ name: "age" }]
|
|
13
|
+
* inputsType(inputs)
|
|
14
|
+
* >> "{ age: NonNullable<unknown> }"
|
|
15
|
+
*/
|
|
16
|
+
export function inputsType(inputs) {
|
|
17
|
+
if (inputs.length === 0) {
|
|
18
|
+
return "{}";
|
|
19
|
+
}
|
|
20
|
+
const inputParams = inputs
|
|
15
21
|
.map((input) => {
|
|
16
22
|
return `${input.name}: NonNullable<unknown>`;
|
|
17
23
|
})
|
|
18
24
|
.join(", ");
|
|
19
|
-
return
|
|
20
|
-
* @param {{ ${inputParams} }} i
|
|
21
|
-
*/`;
|
|
25
|
+
return `{ ${inputParams} }`;
|
|
22
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale-modules.d.ts","sourceRoot":"","sources":["../../../src/compiler/output-structure/locale-modules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAIvE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,wBAAgB,qBAAqB,CACpC,eAAe,EAAE,0BAA0B,EAAE,EAC7C,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,YAAY,CAAC,EACzD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC/C,eAAe,EAAE;IAChB,QAAQ,EAAE,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC;IACnD,UAAU,EAAE,WAAW,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC;CACvD,GACC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"locale-modules.d.ts","sourceRoot":"","sources":["../../../src/compiler/output-structure/locale-modules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAIvE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,wBAAgB,qBAAqB,CACpC,eAAe,EAAE,0BAA0B,EAAE,EAC7C,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,YAAY,CAAC,EACzD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC/C,eAAe,EAAE;IAChB,QAAQ,EAAE,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC;IACnD,UAAU,EAAE,WAAW,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC;CACvD,GACC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwDxB"}
|
|
@@ -24,14 +24,7 @@ export function generateLocaleModules(compiledBundles, settings, fallbackMap, co
|
|
|
24
24
|
// generate message files
|
|
25
25
|
for (const locale of settings.locales) {
|
|
26
26
|
const filename = `messages/${locale}.${fileExt}`;
|
|
27
|
-
let file =
|
|
28
|
-
/**
|
|
29
|
-
* This file contains language specific functions for tree-shaking.
|
|
30
|
-
*
|
|
31
|
-
*! WARNING: Only import from this file if you want to manually
|
|
32
|
-
*! optimize your bundle. Else, import from the \`messages.js\` file.
|
|
33
|
-
*/
|
|
34
|
-
import * as registry from '../registry.${importExt}'`;
|
|
27
|
+
let file = "";
|
|
35
28
|
for (const compiledBundle of compiledBundles) {
|
|
36
29
|
const compiledMessage = compiledBundle.messages[locale];
|
|
37
30
|
const id = jsIdentifier(compiledBundle.bundle.node.id);
|
|
@@ -49,6 +42,10 @@ import * as registry from '../registry.${importExt}'`;
|
|
|
49
42
|
}
|
|
50
43
|
file += `\n\n${compiledMessage.code}`;
|
|
51
44
|
}
|
|
45
|
+
// add import if used
|
|
46
|
+
if (file.includes("registry.")) {
|
|
47
|
+
file = `import * as registry from "./registry.js"\n` + file;
|
|
48
|
+
}
|
|
52
49
|
output[filename] = file;
|
|
53
50
|
}
|
|
54
51
|
return output;
|
|
@@ -9,6 +9,8 @@ export declare function createRuntimeFile(args: {
|
|
|
9
9
|
compilerOptions: {
|
|
10
10
|
strategy: NonNullable<CompilerOptions["strategy"]>;
|
|
11
11
|
cookieName: NonNullable<CompilerOptions["cookieName"]>;
|
|
12
|
+
pathnames?: CompilerOptions["pathnames"];
|
|
13
|
+
pathnameBase?: CompilerOptions["pathnameBase"];
|
|
12
14
|
};
|
|
13
15
|
}): string;
|
|
14
16
|
/**
|
|
@@ -23,9 +25,6 @@ export declare function createRuntimeFile(args: {
|
|
|
23
25
|
export declare function createRuntimeForTesting(args: {
|
|
24
26
|
baseLocale: string;
|
|
25
27
|
locales: string[];
|
|
26
|
-
compilerOptions?:
|
|
27
|
-
strategy?: CompilerOptions["strategy"];
|
|
28
|
-
cookieName?: CompilerOptions["cookieName"];
|
|
29
|
-
};
|
|
28
|
+
compilerOptions?: Omit<CompilerOptions, "outdir" | "project" | "fs">;
|
|
30
29
|
}): Promise<Runtime>;
|
|
31
30
|
//# sourceMappingURL=create-runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/create-runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/create-runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE;QAChB,QAAQ,EAAE,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC;QACnD,UAAU,EAAE,WAAW,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC;QACvD,SAAS,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;QACzC,YAAY,CAAC,EAAE,eAAe,CAAC,cAAc,CAAC,CAAC;KAC/C,CAAC;CACF,GAAG,MAAM,CAsHT;AAkBD;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;CACrE,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBnB"}
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { defaultCompilerOptions } from "../compile.js";
|
|
3
|
+
import * as pathToRegexp from "path-to-regexp";
|
|
3
4
|
/**
|
|
4
5
|
* Returns the code for the `runtime.js` module
|
|
5
6
|
*/
|
|
6
7
|
export function createRuntimeFile(args) {
|
|
8
|
+
const pathnames = args.compilerOptions.pathnames ?? {
|
|
9
|
+
"/{*path}": Object.fromEntries([
|
|
10
|
+
...args.locales.map((locale) => [locale, `/${locale}{/*path}`]),
|
|
11
|
+
[args.baseLocale, `/{*path}`],
|
|
12
|
+
]),
|
|
13
|
+
};
|
|
7
14
|
return `
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
${
|
|
15
|
+
import * as pathToRegexp from "@inlang/paraglide-js/path-to-regexp";
|
|
16
|
+
|
|
17
|
+
${injectCode("./variables.js")
|
|
18
|
+
.replace(`export const baseLocale = "en";`, `export const baseLocale = "${args.baseLocale}";`)
|
|
19
|
+
.replace(`export const locales = /** @type {const} */ (["en", "de"]);`, `export const locales = /** @type {const} */ (["${args.locales.join('", "')}"]);`)
|
|
20
|
+
.replace(`export const strategy = ["globalVariable"];`, `export const strategy = ["${args.compilerOptions.strategy.join('", "')}"]`)
|
|
21
|
+
.replace(`<cookie-name>`, `${args.compilerOptions.cookieName}`)
|
|
22
|
+
.replace(`pathnames = {}`, `pathnames = ${JSON.stringify(pathnames ?? {}, null, 2)}`)
|
|
23
|
+
.replace(`export const TREE_SHAKE_IS_DEFAULT_PATHNAMES = false;`, `const TREE_SHAKE_IS_DEFAULT_PATHNAMES = ${args.compilerOptions.pathnames ? false : true};`)
|
|
24
|
+
.replace(`export const TREE_SHAKE_COOKIE_STRATEGY_USED = false;`, `const TREE_SHAKE_COOKIE_STRATEGY_USED = ${args.compilerOptions.strategy.includes("cookie")};`)
|
|
25
|
+
.replace(`export const TREE_SHAKE_PATHNAME_STRATEGY_USED = false;`, `const TREE_SHAKE_PATHNAME_STRATEGY_USED = ${args.compilerOptions.strategy.includes("pathname")};`)
|
|
26
|
+
.replace(`export const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = false;`, `const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = ${args.compilerOptions.strategy.includes("globalVariable")};`)
|
|
27
|
+
.replace(`export const pathnameBase = undefined;`, `export const pathnameBase = ${args.compilerOptions.pathnameBase ? `"${args.compilerOptions.pathnameBase}"` : "undefined"};`)}
|
|
16
28
|
|
|
17
29
|
/**
|
|
18
30
|
* Define the \`getLocale()\` function.
|
|
@@ -94,7 +106,9 @@ ${injectCode("./extract-locale-from-cookie.js")}
|
|
|
94
106
|
*/
|
|
95
107
|
function injectCode(path) {
|
|
96
108
|
const code = fs.readFileSync(new URL(path, import.meta.url), "utf-8");
|
|
97
|
-
|
|
109
|
+
// Regex to match single-line and multi-line imports
|
|
110
|
+
const importRegex = /import\s+[\s\S]*?from\s+['"][^'"]+['"]\s*;?/g;
|
|
111
|
+
return code.replace(importRegex, "").trim();
|
|
98
112
|
}
|
|
99
113
|
/**
|
|
100
114
|
* Returns the runtime module as an object for testing purposes.
|
|
@@ -111,10 +125,13 @@ export async function createRuntimeForTesting(args) {
|
|
|
111
125
|
locales: args.locales,
|
|
112
126
|
compilerOptions: {
|
|
113
127
|
...defaultCompilerOptions,
|
|
114
|
-
strategy: ["variable"],
|
|
115
128
|
...args.compilerOptions,
|
|
116
129
|
},
|
|
117
|
-
})
|
|
130
|
+
})
|
|
131
|
+
// remove the import statement for path-to-regexp
|
|
132
|
+
.replace(`import * as pathToRegexp from "@inlang/paraglide-js/path-to-regexp";`, "");
|
|
133
|
+
// @ts-expect-error - defining a depdency globally to avoid importing it in the runtime
|
|
134
|
+
globalThis.pathToRegexp = pathToRegexp;
|
|
118
135
|
return await import("data:text/javascript;base64," +
|
|
119
136
|
Buffer.from(file, "utf-8").toString("base64"));
|
|
120
137
|
}
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* deLocalizePath('/home');
|
|
21
21
|
* // '/home' (no change)
|
|
22
22
|
*
|
|
23
|
-
* @param {string}
|
|
23
|
+
* @param {string} pathname - The localized path to de-localize.
|
|
24
24
|
* @returns {string} The de-localized path without the locale prefix.
|
|
25
25
|
*/
|
|
26
|
-
export function deLocalizePath(
|
|
26
|
+
export function deLocalizePath(pathname: string): string;
|
|
27
27
|
//# sourceMappingURL=de-localize-path.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"de-localize-path.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/de-localize-path.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"de-localize-path.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/de-localize-path.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,yCAHW,MAAM,GACJ,MAAM,CA+BlB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { extractLocaleFromPathname } from "./extract-locale-from-pathname.js";
|
|
2
|
+
import { pathnameBase, pathnames, TREE_SHAKE_IS_DEFAULT_PATHNAMES, } from "./variables.js";
|
|
2
3
|
/**
|
|
3
4
|
* De-localizes the given localized path.
|
|
4
5
|
*
|
|
@@ -21,13 +22,31 @@ import { extractLocaleFromPathname } from "./extract-locale-from-pathname.js";
|
|
|
21
22
|
* deLocalizePath('/home');
|
|
22
23
|
* // '/home' (no change)
|
|
23
24
|
*
|
|
24
|
-
* @param {string}
|
|
25
|
+
* @param {string} pathname - The localized path to de-localize.
|
|
25
26
|
* @returns {string} The de-localized path without the locale prefix.
|
|
26
27
|
*/
|
|
27
|
-
export function deLocalizePath(
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
export function deLocalizePath(pathname) {
|
|
29
|
+
const url = new URL(pathname, "http://y.com");
|
|
30
|
+
let path = url.pathname;
|
|
31
|
+
// no dynamic matching is needed if the default pathnames are used
|
|
32
|
+
if (TREE_SHAKE_IS_DEFAULT_PATHNAMES) {
|
|
33
|
+
const locale = extractLocaleFromPathname(path);
|
|
34
|
+
if (locale)
|
|
35
|
+
path = path.replace(`/${locale}`, "") || "/";
|
|
36
|
+
return path + url.search;
|
|
31
37
|
}
|
|
32
|
-
|
|
38
|
+
if (pathnameBase && path.startsWith(pathnameBase)) {
|
|
39
|
+
path = path.replace(pathnameBase, "");
|
|
40
|
+
}
|
|
41
|
+
for (const [unLocalizedPattern, locales] of Object.entries(pathnames)) {
|
|
42
|
+
for (const [, localizedPattern] of Object.entries(locales)) {
|
|
43
|
+
const match = pathToRegexp.match(localizedPattern)(path);
|
|
44
|
+
if (match) {
|
|
45
|
+
return ((pathnameBase || "") +
|
|
46
|
+
pathToRegexp.compile(unLocalizedPattern)(match.params) +
|
|
47
|
+
url.search);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
throw new Error("No match found for localized path. Check pathnames option.");
|
|
33
52
|
}
|
|
@@ -1,47 +1,109 @@
|
|
|
1
1
|
import { test, expect } from "vitest";
|
|
2
2
|
import { createRuntimeForTesting } from "./create-runtime.js";
|
|
3
|
-
test("
|
|
3
|
+
test("handles path that is the root", async () => {
|
|
4
4
|
const runtime = await createRuntimeForTesting({
|
|
5
5
|
baseLocale: "en",
|
|
6
6
|
locales: ["en", "de"],
|
|
7
|
+
compilerOptions: {
|
|
8
|
+
pathnames: {
|
|
9
|
+
"/{*path}": {
|
|
10
|
+
de: "/de{/*path}",
|
|
11
|
+
en: "/{*path}",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
7
15
|
});
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
expect(result).toBe("/home");
|
|
16
|
+
expect(runtime.deLocalizePath("/")).toBe("/");
|
|
17
|
+
expect(runtime.deLocalizePath("/de")).toBe("/");
|
|
11
18
|
});
|
|
12
|
-
test("
|
|
19
|
+
test("delocalizes a localized paths", async () => {
|
|
13
20
|
const runtime = await createRuntimeForTesting({
|
|
14
21
|
baseLocale: "en",
|
|
15
22
|
locales: ["en", "de"],
|
|
23
|
+
compilerOptions: {
|
|
24
|
+
strategy: ["pathname"],
|
|
25
|
+
pathnames: {
|
|
26
|
+
"/about": {
|
|
27
|
+
en: "/UK/about",
|
|
28
|
+
de: "/uber-uns",
|
|
29
|
+
},
|
|
30
|
+
"/blog/:post/suffix": {
|
|
31
|
+
en: "/en/blog/:post/suffix",
|
|
32
|
+
de: "/de/artikel/:post/anhang",
|
|
33
|
+
},
|
|
34
|
+
"/{*path}": {
|
|
35
|
+
en: "/en{/*path}",
|
|
36
|
+
de: "/de{/*path}",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
16
40
|
});
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
expect(
|
|
41
|
+
// check simple cases
|
|
42
|
+
expect(runtime.deLocalizePath("/uber-uns")).toBe("/about");
|
|
43
|
+
expect(runtime.deLocalizePath("/UK/about")).toBe("/about");
|
|
44
|
+
// check parameters
|
|
45
|
+
expect(runtime.deLocalizePath("/de/artikel/123/anhang")).toBe("/blog/123/suffix");
|
|
46
|
+
expect(runtime.deLocalizePath("/en/blog/123/suffix")).toBe("/blog/123/suffix");
|
|
47
|
+
// check wild cards
|
|
48
|
+
expect(runtime.deLocalizePath("/de/something")).toBe("/something");
|
|
49
|
+
expect(runtime.deLocalizePath("/en/something")).toBe("/something");
|
|
20
50
|
});
|
|
21
|
-
test("handles
|
|
51
|
+
test("handles query parameters", async () => {
|
|
22
52
|
const runtime = await createRuntimeForTesting({
|
|
23
53
|
baseLocale: "en",
|
|
24
|
-
locales: ["en", "de"
|
|
54
|
+
locales: ["en", "de"],
|
|
55
|
+
compilerOptions: {
|
|
56
|
+
strategy: ["pathname"],
|
|
57
|
+
pathnames: {
|
|
58
|
+
"/{*path}": {
|
|
59
|
+
en: "/en{/*path}",
|
|
60
|
+
de: "/de{/*path}",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
expect(runtime.deLocalizePath("/en/something?query=123&other=5")).toBe("/something?query=123&other=5");
|
|
66
|
+
});
|
|
67
|
+
test("handles TREE_SHAKE_DEFAULT_PATHNAMES", async () => {
|
|
68
|
+
const runtime = await createRuntimeForTesting({
|
|
69
|
+
baseLocale: "en",
|
|
70
|
+
locales: ["en", "de"],
|
|
71
|
+
compilerOptions: {
|
|
72
|
+
strategy: ["pathname"],
|
|
73
|
+
// will create default pathnames
|
|
74
|
+
pathnames: undefined,
|
|
75
|
+
},
|
|
25
76
|
});
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
expect(
|
|
77
|
+
expect(runtime.deLocalizePath("/")).toBe("/");
|
|
78
|
+
expect(runtime.deLocalizePath("/de")).toBe("/");
|
|
79
|
+
expect(runtime.deLocalizePath("/de/something")).toBe("/something");
|
|
29
80
|
});
|
|
30
|
-
|
|
81
|
+
// https://github.com/opral/inlang-paraglide-js/issues/362
|
|
82
|
+
test("handles pathnameBase for default pathnames option", async () => {
|
|
31
83
|
const runtime = await createRuntimeForTesting({
|
|
32
84
|
baseLocale: "en",
|
|
33
85
|
locales: ["en", "de"],
|
|
86
|
+
compilerOptions: {
|
|
87
|
+
pathnameBase: "/base",
|
|
88
|
+
},
|
|
34
89
|
});
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
expect(result).toBe("/");
|
|
90
|
+
expect(runtime.deLocalizePath("/base/something")).toBe("/base/something");
|
|
91
|
+
expect(runtime.deLocalizePath("/base/de/something")).toBe("/base/something");
|
|
38
92
|
});
|
|
39
|
-
test("handles
|
|
93
|
+
test("handles pathnameBase for matcher pathnames option", async () => {
|
|
40
94
|
const runtime = await createRuntimeForTesting({
|
|
41
95
|
baseLocale: "en",
|
|
42
96
|
locales: ["en", "de"],
|
|
97
|
+
compilerOptions: {
|
|
98
|
+
pathnameBase: "/base",
|
|
99
|
+
pathnames: {
|
|
100
|
+
"/{*path}": {
|
|
101
|
+
de: "/de{/*path}",
|
|
102
|
+
en: "/{*path}",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
43
106
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
expect(result).toBe("/");
|
|
107
|
+
expect(runtime.deLocalizePath("/base/something")).toBe("/base/something");
|
|
108
|
+
expect(runtime.deLocalizePath("/base/de/something")).toBe("/base/something");
|
|
47
109
|
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* De-localizes the given localized path.
|
|
3
|
+
*
|
|
4
|
+
* This function removes the locale from the given path, returning the
|
|
5
|
+
* base path without the locale prefix.
|
|
6
|
+
*
|
|
7
|
+
* Useful when you need to work with non-localized paths from a localized routing system.
|
|
8
|
+
*
|
|
9
|
+
* @tip
|
|
10
|
+
* Use `localizedPath()` for the inverse operation.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Assuming baseLocale = 'en'
|
|
14
|
+
* deLocalizedPath('/fr/home');
|
|
15
|
+
* // '/home'
|
|
16
|
+
*
|
|
17
|
+
* deLocalizedPath('/en/home');
|
|
18
|
+
* // '/home'
|
|
19
|
+
*
|
|
20
|
+
* deLocalizedPath('/home');
|
|
21
|
+
* // '/home' (no change)
|
|
22
|
+
*
|
|
23
|
+
* @param {string} path - The localized path to de-localize.
|
|
24
|
+
* @returns {string} The de-localized path without the locale prefix.
|
|
25
|
+
*/
|
|
26
|
+
export function deLocalizedPath(path: string): string;
|
|
27
|
+
//# sourceMappingURL=de-localized-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"de-localized-path.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/de-localized-path.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,sCAHW,MAAM,GACJ,MAAM,CAQlB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* De-localizes the given localized path.
|
|
3
|
+
*
|
|
4
|
+
* This function removes the locale from the given path, returning the
|
|
5
|
+
* base path without the locale prefix.
|
|
6
|
+
*
|
|
7
|
+
* Useful when you need to work with non-localized paths from a localized routing system.
|
|
8
|
+
*
|
|
9
|
+
* @tip
|
|
10
|
+
* Use `localizedPath()` for the inverse operation.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Assuming baseLocale = 'en'
|
|
14
|
+
* deLocalizedPath('/fr/home');
|
|
15
|
+
* // '/home'
|
|
16
|
+
*
|
|
17
|
+
* deLocalizedPath('/en/home');
|
|
18
|
+
* // '/home'
|
|
19
|
+
*
|
|
20
|
+
* deLocalizedPath('/home');
|
|
21
|
+
* // '/home' (no change)
|
|
22
|
+
*
|
|
23
|
+
* @param {string} path - The localized path to de-localize.
|
|
24
|
+
* @returns {string} The de-localized path without the locale prefix.
|
|
25
|
+
*/
|
|
26
|
+
export function deLocalizedPath(path) {
|
|
27
|
+
const hasLocale = getLocaleFromPath(path);
|
|
28
|
+
if (!hasLocale) {
|
|
29
|
+
return path; // Path is already de-localized
|
|
30
|
+
}
|
|
31
|
+
return "/" + path.split("/").slice(2).join("/");
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"de-localized-path.test.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/de-localized-path.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { test, vi, beforeEach, expect, describe } from "vitest";
|
|
2
|
+
import { deLocalizedPath } from "./de-localized-path.js";
|
|
3
|
+
import { mockRuntime } from "./mock-runtime.js";
|
|
4
|
+
// sequential to avoid global variable conflicts
|
|
5
|
+
describe.sequential("delocalizedPath", () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
vi.resetAllMocks();
|
|
8
|
+
});
|
|
9
|
+
mockRuntime({
|
|
10
|
+
baseLocale: "en",
|
|
11
|
+
locales: ["en", "de", "fr"],
|
|
12
|
+
});
|
|
13
|
+
test("removes the locale from a localized path", () => {
|
|
14
|
+
// @ts-expect-error - global variable definition
|
|
15
|
+
globalThis.getLocaleFromPath = vi.fn().mockReturnValue("de");
|
|
16
|
+
const path = "/de/home";
|
|
17
|
+
const result = deLocalizedPath(path);
|
|
18
|
+
expect(result).toBe("/home");
|
|
19
|
+
});
|
|
20
|
+
test("returns the same path if there is no locale", () => {
|
|
21
|
+
// @ts-expect-error - global variable definition
|
|
22
|
+
globalThis.getLocaleFromPath = vi.fn().mockReturnValue(undefined);
|
|
23
|
+
const path = "/home";
|
|
24
|
+
const result = deLocalizedPath(path);
|
|
25
|
+
expect(result).toBe("/home");
|
|
26
|
+
});
|
|
27
|
+
test("handles paths with different locales", () => {
|
|
28
|
+
// @ts-expect-error - global variable definition
|
|
29
|
+
globalThis.getLocaleFromPath = vi.fn().mockReturnValue("fr");
|
|
30
|
+
const path = "/fr/contact";
|
|
31
|
+
const result = deLocalizedPath(path);
|
|
32
|
+
expect(result).toBe("/contact");
|
|
33
|
+
});
|
|
34
|
+
test("handles paths with no segments after locale", () => {
|
|
35
|
+
// @ts-expect-error - global variable definition
|
|
36
|
+
globalThis.getLocaleFromPath = vi.fn().mockReturnValue("en");
|
|
37
|
+
const path = "/en/";
|
|
38
|
+
const result = deLocalizedPath(path);
|
|
39
|
+
expect(result).toBe("/");
|
|
40
|
+
});
|
|
41
|
+
test("handles paths that are already the root", () => {
|
|
42
|
+
// @ts-expect-error - global variable definition
|
|
43
|
+
globalThis.getLocaleFromPath = vi.fn().mockReturnValue(undefined);
|
|
44
|
+
const path = "/";
|
|
45
|
+
const result = deLocalizedPath(path);
|
|
46
|
+
expect(result).toBe("/");
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect a locale from a request.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* const locale = detectLocaleFromRequest({
|
|
6
|
+
* pathname: '/en/home',
|
|
7
|
+
* headers: {
|
|
8
|
+
* 'accept-language': 'en'
|
|
9
|
+
* },
|
|
10
|
+
* cookies: {
|
|
11
|
+
* 'PARAGLIDE_LOCALE': 'fr'
|
|
12
|
+
* }
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* @type {(args: { pathname: string, headers: Record<string, string>, cookies: Record<string, string> }) => Locale}
|
|
16
|
+
*/
|
|
17
|
+
export const detectLocaleFromRequest: (args: {
|
|
18
|
+
pathname: string;
|
|
19
|
+
headers: Record<string, string>;
|
|
20
|
+
cookies: Record<string, string>;
|
|
21
|
+
}) => Locale;
|
|
22
|
+
//# sourceMappingURL=detect-locale-from-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-locale-from-request.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/detect-locale-from-request.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,sCAFU,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,KAAK,MAAM,CA6BhH"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect a locale from a request.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* const locale = detectLocaleFromRequest({
|
|
6
|
+
* pathname: '/en/home',
|
|
7
|
+
* headers: {
|
|
8
|
+
* 'accept-language': 'en'
|
|
9
|
+
* },
|
|
10
|
+
* cookies: {
|
|
11
|
+
* 'PARAGLIDE_LOCALE': 'fr'
|
|
12
|
+
* }
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* @type {(args: { pathname: string, headers: Record<string, string>, cookies: Record<string, string> }) => Locale}
|
|
16
|
+
*/
|
|
17
|
+
export const detectLocaleFromRequest = (args) => {
|
|
18
|
+
/** @type {string|undefined} */
|
|
19
|
+
let locale;
|
|
20
|
+
for (const strat of strategy) {
|
|
21
|
+
if (strat === "cookie") {
|
|
22
|
+
locale = args.cookies[cookieName];
|
|
23
|
+
}
|
|
24
|
+
else if (strat === "pathname") {
|
|
25
|
+
locale = localeInPath(args.pathname);
|
|
26
|
+
}
|
|
27
|
+
else if (strat === "custom") {
|
|
28
|
+
throw new Error("Custom strategy is not supported for detectLocaleFromRequest");
|
|
29
|
+
}
|
|
30
|
+
else if (strat === "variable") {
|
|
31
|
+
locale = _localeVariable;
|
|
32
|
+
}
|
|
33
|
+
else if (strat === "baseLocale") {
|
|
34
|
+
return baseLocale;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
throw new Error(`Unsupported strategy: ${strat}`);
|
|
38
|
+
}
|
|
39
|
+
if (locale !== undefined) {
|
|
40
|
+
return assertIsLocale(locale);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
throw new Error("No locale found. There is an error in your strategy. Try adding 'baseLocale' as the very last strategy.");
|
|
44
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e.test.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/e2e.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { expect, test, describe } from "vitest";
|
|
2
|
+
import { createRuntimeForTesting } from "./create-runtime.js";
|
|
3
|
+
describe.each([
|
|
4
|
+
{ pathnameBase: "/base" },
|
|
5
|
+
{
|
|
6
|
+
pathnameBase: "/base",
|
|
7
|
+
pathnames: {
|
|
8
|
+
"/{*path}": {
|
|
9
|
+
de: "/de{/*path}",
|
|
10
|
+
en: "/{*path}",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
])("pathnameBase combinations", (compilerOptions) => {
|
|
15
|
+
test(`pathnames: ${compilerOptions.pathnames}`, async () => {
|
|
16
|
+
const runtime = await createRuntimeForTesting({
|
|
17
|
+
baseLocale: "en",
|
|
18
|
+
locales: ["en", "de"],
|
|
19
|
+
compilerOptions,
|
|
20
|
+
});
|
|
21
|
+
// it should auto inject the base path to avoid problems with routing frameworks
|
|
22
|
+
// that might or might not add the base path
|
|
23
|
+
expect(runtime.localizePath("/hello-world")).toBe("/base/hello-world");
|
|
24
|
+
// app sets the locale to de
|
|
25
|
+
runtime.setLocale("de");
|
|
26
|
+
// localizePath should return the localized path with the base path
|
|
27
|
+
expect(runtime.localizePath("/hello-world")).toBe("/base/de/hello-world");
|
|
28
|
+
// deLocalizePath should remove the locale (de)
|
|
29
|
+
expect(runtime.deLocalizePath("/base/de/hello-world")).toBe("/base/hello-world");
|
|
30
|
+
// routing from a de route to an another locale
|
|
31
|
+
expect(runtime.localizePath("/base/de", { locale: "en" })).toBe("/base");
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-locale-from-pathname.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/extract-locale-from-pathname.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extract-locale-from-pathname.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/extract-locale-from-pathname.js"],"names":[],"mappings":"AASA;;;;;;;;;;GAUG;AACH,oDAHW,MAAM,GACJ,MAAM,GAAC,SAAS,CAyB5B"}
|