@inlang/paraglide-js 2.0.0-beta.20 → 2.0.0-beta.21
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/rollup.d.ts +1 -1
- package/dist/bundler-plugins/rollup.d.ts.map +1 -1
- package/dist/bundler-plugins/unplugin.d.ts.map +1 -1
- package/dist/bundler-plugins/unplugin.js +10 -17
- package/dist/compiler/compile-bundle.d.ts.map +1 -1
- package/dist/compiler/compile-bundle.js +9 -21
- package/dist/compiler/compile-bundle.test.js +62 -39
- package/dist/compiler/compile-message.d.ts.map +1 -1
- package/dist/compiler/compile-message.js +5 -2
- package/dist/compiler/compile-message.test.js +23 -0
- package/dist/compiler/compile-project.test.js +26 -0
- package/dist/compiler/compile.d.ts +6 -3
- package/dist/compiler/compile.d.ts.map +1 -1
- package/dist/compiler/compile.js +6 -2
- package/dist/compiler/compile.test.js +6 -2
- package/dist/compiler/compiler-options.d.ts +1 -1
- package/dist/compiler/compiler-options.js +1 -1
- package/dist/compiler/output-structure/locale-modules.d.ts.map +1 -1
- package/dist/compiler/output-structure/locale-modules.js +6 -5
- package/dist/compiler/output-structure/message-modules.d.ts.map +1 -1
- package/dist/compiler/output-structure/message-modules.js +37 -24
- package/dist/compiler/output-structure/message-modules.test.js +48 -0
- package/dist/compiler/runtime/create-runtime.d.ts.map +1 -1
- package/dist/compiler/runtime/create-runtime.js +6 -3
- package/dist/compiler/runtime/extract-locale-from-url.d.ts +2 -2
- package/dist/compiler/runtime/extract-locale-from-url.d.ts.map +1 -1
- package/dist/compiler/runtime/extract-locale-from-url.js +24 -2
- package/dist/compiler/runtime/extract-locale-from-url.test.js +12 -0
- package/dist/compiler/runtime/localize-href.d.ts +63 -27
- package/dist/compiler/runtime/localize-href.d.ts.map +1 -1
- package/dist/compiler/runtime/localize-href.js +64 -38
- package/dist/compiler/runtime/localize-url.d.ts +80 -8
- package/dist/compiler/runtime/localize-url.d.ts.map +1 -1
- package/dist/compiler/runtime/localize-url.js +146 -16
- package/dist/compiler/runtime/localize-url.test.js +84 -0
- package/dist/compiler/runtime/server-middleware.d.ts +1 -3
- package/dist/compiler/runtime/server-middleware.d.ts.map +1 -1
- package/dist/compiler/runtime/server-middleware.js +1 -3
- package/dist/compiler/runtime/variables.d.ts +1 -0
- package/dist/compiler/runtime/variables.d.ts.map +1 -1
- package/dist/compiler/runtime/variables.js +1 -0
- package/dist/compiler/safe-module-id.d.ts +8 -0
- package/dist/compiler/safe-module-id.d.ts.map +1 -0
- package/dist/compiler/safe-module-id.js +71 -0
- package/dist/compiler/safe-module-id.test.d.ts +2 -0
- package/dist/compiler/safe-module-id.test.d.ts.map +1 -0
- package/dist/compiler/safe-module-id.test.js +27 -0
- package/dist/services/env-variables/index.js +1 -1
- package/dist/services/file-handling/write-output.d.ts +1 -1
- package/dist/services/file-handling/write-output.d.ts.map +1 -1
- package/dist/services/file-handling/write-output.js +1 -1
- package/dist/services/file-handling/write-output.test.js +2 -1
- package/package.json +3 -3
|
@@ -37,3 +37,51 @@ test("should emit per locale message files", () => {
|
|
|
37
37
|
expect(output).toHaveProperty("messages/happy_elephant/de.js");
|
|
38
38
|
expect(output).toHaveProperty("messages/happy_elephant/index.js");
|
|
39
39
|
});
|
|
40
|
+
test("handles case senstivity by creating directories and files only in lowercase", () => {
|
|
41
|
+
const resources = [
|
|
42
|
+
{
|
|
43
|
+
bundle: {
|
|
44
|
+
code: "export const HappyElephant = () => en.HappyElephant",
|
|
45
|
+
node: {
|
|
46
|
+
id: "HappyElephant",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
messages: {
|
|
50
|
+
en: {
|
|
51
|
+
code: 'export const HappyElephant = () => "HappyElephant0"',
|
|
52
|
+
node: {},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
bundle: {
|
|
58
|
+
code: "export const happyelephant = () => en.happyelephant",
|
|
59
|
+
node: {
|
|
60
|
+
id: "happyelephant",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
messages: {
|
|
64
|
+
en: {
|
|
65
|
+
code: 'export const happyelephant = () => "happyelephant1"',
|
|
66
|
+
node: {},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
const settings = {
|
|
72
|
+
locales: ["en"],
|
|
73
|
+
baseLocale: "en",
|
|
74
|
+
};
|
|
75
|
+
const output = generateMessageModules(resources, settings, {}, defaultCompilerOptions);
|
|
76
|
+
// expecting only lowercase directories and files
|
|
77
|
+
expect(output).toHaveProperty("messages/happyelephant/en.js");
|
|
78
|
+
expect(output).toHaveProperty("messages/happyelephant/index.js");
|
|
79
|
+
expect(output).not.toHaveProperty("messages/HappyElephant/en.js");
|
|
80
|
+
expect(output).not.toHaveProperty("messages/HappyElephant/index.js");
|
|
81
|
+
// expecting both bundles to be merged into the "happyelephant" module
|
|
82
|
+
expect(output["messages/happyelephant/index.js"]).includes(`export const happyelephant = () => en.happyelephant`);
|
|
83
|
+
expect(output["messages/happyelephant/index.js"]).includes(`export const HappyElephant = () => en.HappyElephant`);
|
|
84
|
+
// expecting both messages to be in their respective files
|
|
85
|
+
expect(output["messages/happyelephant/en.js"]).includes(`export const HappyElephant = () => "HappyElephant0"`);
|
|
86
|
+
expect(output["messages/happyelephant/en.js"]).includes(`export const HappyElephant = () => "HappyElephant0"`);
|
|
87
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/create-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAEN,KAAK,eAAe,EACpB,MAAM,wBAAwB,CAAC;AAEhC;;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,WAAW,CAAC,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;KAC7C,CAAC;CACF,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/create-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAEN,KAAK,eAAe,EACpB,MAAM,wBAAwB,CAAC;AAEhC;;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,WAAW,CAAC,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;KAC7C,CAAC;CACF,GAAG,MAAM,CAiGT;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,CAkBnB"}
|
|
@@ -5,8 +5,10 @@ import { defaultCompilerOptions, } from "../compiler-options.js";
|
|
|
5
5
|
*/
|
|
6
6
|
export function createRuntimeFile(args) {
|
|
7
7
|
const urlPatterns = args.compilerOptions.urlPatterns ?? [];
|
|
8
|
+
let defaultUrlPatternUsed = false;
|
|
8
9
|
// add default urlPatterns for a good out of the box experience
|
|
9
10
|
if (args.compilerOptions.urlPatterns === undefined) {
|
|
11
|
+
defaultUrlPatternUsed = true;
|
|
10
12
|
urlPatterns.push({
|
|
11
13
|
pattern: `:protocol://:domain(.*)::port?/:locale(${args.locales.filter((l) => l !== args.baseLocale).join("|")})?/:path(.*)?`,
|
|
12
14
|
deLocalizedNamedGroups: { locale: null },
|
|
@@ -17,18 +19,19 @@ export function createRuntimeFile(args) {
|
|
|
17
19
|
});
|
|
18
20
|
}
|
|
19
21
|
const code = `
|
|
20
|
-
import "@inlang/paraglide-js/urlpattern-polyfill"
|
|
22
|
+
${defaultUrlPatternUsed ? "/** @type {any} */\nconst URLPattern = {}" : `import "@inlang/paraglide-js/urlpattern-polyfill";`}
|
|
21
23
|
|
|
22
24
|
${injectCode("./variables.js")
|
|
23
25
|
.replace(`export const baseLocale = "en";`, `export const baseLocale = "${args.baseLocale}";`)
|
|
24
26
|
.replace(`export const locales = /** @type {const} */ (["en", "de"]);`, `export const locales = /** @type {const} */ (["${args.locales.join('", "')}"]);`)
|
|
25
|
-
.replace(`export const strategy = ["globalVariable"];`, `export const strategy =
|
|
27
|
+
.replace(`export const strategy = ["globalVariable"];`, `export const strategy = ${JSON.stringify(args.compilerOptions.strategy, null, 2)};`)
|
|
26
28
|
.replace(`<cookie-name>`, `${args.compilerOptions.cookieName}`)
|
|
27
29
|
.replace(`export const TREE_SHAKE_COOKIE_STRATEGY_USED = false;`, `const TREE_SHAKE_COOKIE_STRATEGY_USED = ${args.compilerOptions.strategy.includes("cookie")};`)
|
|
28
30
|
.replace(`export const TREE_SHAKE_URL_STRATEGY_USED = false;`, `const TREE_SHAKE_URL_STRATEGY_USED = ${args.compilerOptions.strategy.includes("url")};`)
|
|
29
31
|
.replace(`export const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = false;`, `const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = ${args.compilerOptions.strategy.includes("globalVariable")};`)
|
|
30
32
|
.replace(`export const TREE_SHAKE_PREFERRED_LANGUAGE_STRATEGY_USED = false;`, `const TREE_SHAKE_PREFERRED_LANGUAGE_STRATEGY_USED = ${args.compilerOptions.strategy.includes("preferredLanguage")};`)
|
|
31
|
-
.replace(`export const urlPatterns = [];`, `export const urlPatterns = ${JSON.stringify(urlPatterns, null, 2)};`)
|
|
33
|
+
.replace(`export const urlPatterns = [];`, `export const urlPatterns = ${JSON.stringify(urlPatterns, null, 2)};`)
|
|
34
|
+
.replace(`export const TREE_SHAKE_DEFAULT_URL_PATTERN_USED = false;`, `const TREE_SHAKE_DEFAULT_URL_PATTERN_USED = ${defaultUrlPatternUsed};`)}
|
|
32
35
|
|
|
33
36
|
${injectCode("./get-locale.js")}
|
|
34
37
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Extracts the locale from a given URL using native URLPattern.
|
|
3
3
|
*
|
|
4
|
-
* @param {string} url - The full URL from which to extract the locale.
|
|
4
|
+
* @param {URL|string} url - The full URL from which to extract the locale.
|
|
5
5
|
* @returns {Locale|undefined} The extracted locale, or undefined if no locale is found.
|
|
6
6
|
*/
|
|
7
|
-
export function extractLocaleFromUrl(url: string): Locale | undefined;
|
|
7
|
+
export function extractLocaleFromUrl(url: URL | string): Locale | undefined;
|
|
8
8
|
//# sourceMappingURL=extract-locale-from-url.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-locale-from-url.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/extract-locale-from-url.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extract-locale-from-url.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/extract-locale-from-url.js"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,0CAHW,GAAG,GAAC,MAAM,GACR,MAAM,GAAC,SAAS,CAkD5B"}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { assertIsLocale } from "./assert-is-locale.js";
|
|
2
|
+
import { isLocale } from "./is-locale.js";
|
|
2
3
|
import { aggregateGroups } from "./localize-url.js";
|
|
3
|
-
import { urlPatterns } from "./variables.js";
|
|
4
|
+
import { baseLocale, TREE_SHAKE_DEFAULT_URL_PATTERN_USED, urlPatterns, } from "./variables.js";
|
|
4
5
|
/**
|
|
5
6
|
* Extracts the locale from a given URL using native URLPattern.
|
|
6
7
|
*
|
|
7
|
-
* @param {string} url - The full URL from which to extract the locale.
|
|
8
|
+
* @param {URL|string} url - The full URL from which to extract the locale.
|
|
8
9
|
* @returns {Locale|undefined} The extracted locale, or undefined if no locale is found.
|
|
9
10
|
*/
|
|
10
11
|
export function extractLocaleFromUrl(url) {
|
|
12
|
+
if (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {
|
|
13
|
+
return defaultUrlPatternExtractLocale(url);
|
|
14
|
+
}
|
|
11
15
|
for (const element of urlPatterns) {
|
|
12
16
|
const pattern = new URLPattern(element.pattern);
|
|
13
17
|
const match = pattern.exec(url);
|
|
@@ -46,3 +50,21 @@ export function extractLocaleFromUrl(url) {
|
|
|
46
50
|
}
|
|
47
51
|
return undefined;
|
|
48
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* https://github.com/opral/inlang-paraglide-js/issues/381
|
|
55
|
+
*
|
|
56
|
+
* @param {URL|string} url - The full URL from which to extract the locale.
|
|
57
|
+
* @returns {Locale|undefined} The extracted locale, or undefined if no locale is found.
|
|
58
|
+
*/
|
|
59
|
+
function defaultUrlPatternExtractLocale(url) {
|
|
60
|
+
const urlObj = new URL(url, "http://dummy.com");
|
|
61
|
+
const pathSegments = urlObj.pathname.split("/").filter(Boolean);
|
|
62
|
+
if (pathSegments.length > 0) {
|
|
63
|
+
const potentialLocale = pathSegments[0];
|
|
64
|
+
if (isLocale(potentialLocale)) {
|
|
65
|
+
return potentialLocale;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// everything else has to be the base locale
|
|
69
|
+
return baseLocale;
|
|
70
|
+
}
|
|
@@ -87,3 +87,15 @@ test("regex works", async () => {
|
|
|
87
87
|
expect(extractLocaleFromUrl(`https://example.com/de/subpage`)).toBe("de");
|
|
88
88
|
expect(extractLocaleFromUrl(`https://example.com/subpage`)).toBe("en");
|
|
89
89
|
});
|
|
90
|
+
test("default url pattern", async () => {
|
|
91
|
+
const r = await createRuntimeForTesting({
|
|
92
|
+
baseLocale: "en",
|
|
93
|
+
locales: ["en", "de"],
|
|
94
|
+
});
|
|
95
|
+
expect(r.extractLocaleFromUrl("https://example.com/")).toBe("en");
|
|
96
|
+
expect(r.extractLocaleFromUrl("https://example.com/de")).toBe("de");
|
|
97
|
+
// anyhing other than a valid locale must be the base locale
|
|
98
|
+
expect(r.extractLocaleFromUrl("https://example.com/fr")).toBe("en");
|
|
99
|
+
expect(r.extractLocaleFromUrl("https://example.com/optional-subpage")).toBe("en");
|
|
100
|
+
expect(r.extractLocaleFromUrl("https://example.com/de/optional-subpage")).toBe("de");
|
|
101
|
+
});
|
|
@@ -1,46 +1,82 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* High-level URL localization function optimized for client-side UI usage.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* This is a convenience wrapper around `localizeUrl()` that provides features
|
|
5
|
+
* needed in UI:
|
|
6
|
+
*
|
|
7
|
+
* - Accepts relative paths (e.g., "/about")
|
|
8
|
+
* - Returns relative paths when possible
|
|
9
|
+
* - Automatically detects current locale if not specified
|
|
10
|
+
* - Handles string input/output instead of URL objects
|
|
7
11
|
*
|
|
8
12
|
* @example
|
|
9
|
-
*
|
|
10
|
-
*
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // In a React/Vue/Svelte component
|
|
15
|
+
* const NavLink = ({ href }) => {
|
|
16
|
+
* // Automatically uses current locale, keeps path relative
|
|
17
|
+
* return <a href={localizeHref(href)}>...</a>;
|
|
18
|
+
* };
|
|
19
|
+
*
|
|
20
|
+
* // Examples:
|
|
21
|
+
* localizeHref("/about")
|
|
22
|
+
* // => "/de/about" (if current locale is "de")
|
|
23
|
+
* localizeHref("/store", { locale: "fr" })
|
|
24
|
+
* // => "/fr/store" (explicit locale)
|
|
11
25
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
26
|
+
* // Cross-origin links remain absolute
|
|
27
|
+
* localizeHref("https://other-site.com/about")
|
|
28
|
+
* // => "https://other-site.com/de/about"
|
|
29
|
+
* ```
|
|
15
30
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
31
|
+
* For server-side URL localization (e.g., in middleware), use `localizeUrl()`
|
|
32
|
+
* which provides more precise control over URL handling.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} href - The href to localize (can be relative or absolute)
|
|
35
|
+
* @param {Object} [options] - Options for localization
|
|
36
|
+
* @param {string} [options.locale] - Target locale. If not provided, uses `getLocale()`
|
|
37
|
+
* @returns {string} The localized href, relative if input was relative
|
|
19
38
|
*/
|
|
20
39
|
export function localizeHref(href: string, options?: {
|
|
21
40
|
locale?: string | undefined;
|
|
22
41
|
}): string;
|
|
23
42
|
/**
|
|
24
|
-
*
|
|
43
|
+
* High-level URL de-localization function optimized for client-side UI usage.
|
|
44
|
+
*
|
|
45
|
+
* This is a convenience wrapper around `deLocalizeUrl()` that provides features
|
|
46
|
+
* needed in the UI:
|
|
25
47
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
48
|
+
* - Accepts relative paths (e.g., "/de/about")
|
|
49
|
+
* - Returns relative paths when possible
|
|
50
|
+
* - Handles string input/output instead of URL objects
|
|
29
51
|
*
|
|
30
52
|
* @example
|
|
31
|
-
*
|
|
32
|
-
*
|
|
53
|
+
* ```typescript
|
|
54
|
+
* // In a React/Vue/Svelte component
|
|
55
|
+
* const LocaleSwitcher = ({ href }) => {
|
|
56
|
+
* // Remove locale prefix before switching
|
|
57
|
+
* const baseHref = deLocalizeHref(href);
|
|
58
|
+
* return locales.map(locale =>
|
|
59
|
+
* <a href={localizeHref(baseHref, { locale })}>
|
|
60
|
+
* Switch to {locale}
|
|
61
|
+
* </a>
|
|
62
|
+
* );
|
|
63
|
+
* };
|
|
33
64
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
65
|
+
* // Examples:
|
|
66
|
+
* deLocalizeHref("/de/about") // => "/about"
|
|
67
|
+
* deLocalizeHref("/fr/store") // => "/store"
|
|
37
68
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
69
|
+
* // Cross-origin links remain absolute
|
|
70
|
+
* deLocalizeHref("https://example.com/de/about")
|
|
71
|
+
* // => "https://example.com/about"
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* For server-side URL de-localization (e.g., in middleware), use `deLocalizeUrl()`
|
|
75
|
+
* which provides more precise control over URL handling.
|
|
76
|
+
*
|
|
77
|
+
* @param {string} href - The href to de-localize (can be relative or absolute)
|
|
78
|
+
* @returns {string} The de-localized href, relative if input was relative
|
|
79
|
+
* @see deLocalizeUrl - For low-level URL de-localization in server contexts
|
|
40
80
|
*/
|
|
41
81
|
export function deLocalizeHref(href: string): string;
|
|
42
|
-
export function localizePath(href: string, options?: {
|
|
43
|
-
locale?: string;
|
|
44
|
-
}): string;
|
|
45
|
-
export function deLocalizePath(href: string): string;
|
|
46
82
|
//# sourceMappingURL=localize-href.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localize-href.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-href.js"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"localize-href.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-href.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,mCALW,MAAM,YAEd;IAAyB,MAAM;CAC/B,GAAU,MAAM,CAsBlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qCAJW,MAAM,GACJ,MAAM,CAelB"}
|
|
@@ -2,28 +2,47 @@ import { getLocale } from "./get-locale.js";
|
|
|
2
2
|
import { getUrlOrigin } from "./get-url-origin.js";
|
|
3
3
|
import { deLocalizeUrl, localizeUrl } from "./localize-url.js";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* High-level URL localization function optimized for client-side UI usage.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* This is a convenience wrapper around `localizeUrl()` that provides features
|
|
8
|
+
* needed in UI:
|
|
9
|
+
*
|
|
10
|
+
* - Accepts relative paths (e.g., "/about")
|
|
11
|
+
* - Returns relative paths when possible
|
|
12
|
+
* - Automatically detects current locale if not specified
|
|
13
|
+
* - Handles string input/output instead of URL objects
|
|
10
14
|
*
|
|
11
15
|
* @example
|
|
12
|
-
*
|
|
13
|
-
*
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // In a React/Vue/Svelte component
|
|
18
|
+
* const NavLink = ({ href }) => {
|
|
19
|
+
* // Automatically uses current locale, keeps path relative
|
|
20
|
+
* return <a href={localizeHref(href)}>...</a>;
|
|
21
|
+
* };
|
|
22
|
+
*
|
|
23
|
+
* // Examples:
|
|
24
|
+
* localizeHref("/about")
|
|
25
|
+
* // => "/de/about" (if current locale is "de")
|
|
26
|
+
* localizeHref("/store", { locale: "fr" })
|
|
27
|
+
* // => "/fr/store" (explicit locale)
|
|
28
|
+
*
|
|
29
|
+
* // Cross-origin links remain absolute
|
|
30
|
+
* localizeHref("https://other-site.com/about")
|
|
31
|
+
* // => "https://other-site.com/de/about"
|
|
32
|
+
* ```
|
|
14
33
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* // => "http://example.com/de/about"
|
|
34
|
+
* For server-side URL localization (e.g., in middleware), use `localizeUrl()`
|
|
35
|
+
* which provides more precise control over URL handling.
|
|
18
36
|
*
|
|
19
|
-
* @param {string} href
|
|
20
|
-
* @param {Object} [options] - Options
|
|
21
|
-
* @param {string} [options.locale] -
|
|
37
|
+
* @param {string} href - The href to localize (can be relative or absolute)
|
|
38
|
+
* @param {Object} [options] - Options for localization
|
|
39
|
+
* @param {string} [options.locale] - Target locale. If not provided, uses `getLocale()`
|
|
40
|
+
* @returns {string} The localized href, relative if input was relative
|
|
22
41
|
*/
|
|
23
42
|
export function localizeHref(href, options) {
|
|
24
43
|
const locale = options?.locale ?? getLocale();
|
|
25
44
|
const url = new URL(href, getUrlOrigin());
|
|
26
|
-
const localized = localizeUrl(url,
|
|
45
|
+
const localized = localizeUrl(url, options);
|
|
27
46
|
// if the origin is identical and the href is relative,
|
|
28
47
|
// return the relative path
|
|
29
48
|
if (href.startsWith("/") && url.origin === localized.origin) {
|
|
@@ -39,22 +58,43 @@ export function localizeHref(href, options) {
|
|
|
39
58
|
return localized.href;
|
|
40
59
|
}
|
|
41
60
|
/**
|
|
42
|
-
*
|
|
61
|
+
* High-level URL de-localization function optimized for client-side UI usage.
|
|
43
62
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
63
|
+
* This is a convenience wrapper around `deLocalizeUrl()` that provides features
|
|
64
|
+
* needed in the UI:
|
|
65
|
+
*
|
|
66
|
+
* - Accepts relative paths (e.g., "/de/about")
|
|
67
|
+
* - Returns relative paths when possible
|
|
68
|
+
* - Handles string input/output instead of URL objects
|
|
47
69
|
*
|
|
48
70
|
* @example
|
|
49
|
-
*
|
|
50
|
-
*
|
|
71
|
+
* ```typescript
|
|
72
|
+
* // In a React/Vue/Svelte component
|
|
73
|
+
* const LocaleSwitcher = ({ href }) => {
|
|
74
|
+
* // Remove locale prefix before switching
|
|
75
|
+
* const baseHref = deLocalizeHref(href);
|
|
76
|
+
* return locales.map(locale =>
|
|
77
|
+
* <a href={localizeHref(baseHref, { locale })}>
|
|
78
|
+
* Switch to {locale}
|
|
79
|
+
* </a>
|
|
80
|
+
* );
|
|
81
|
+
* };
|
|
82
|
+
*
|
|
83
|
+
* // Examples:
|
|
84
|
+
* deLocalizeHref("/de/about") // => "/about"
|
|
85
|
+
* deLocalizeHref("/fr/store") // => "/store"
|
|
86
|
+
*
|
|
87
|
+
* // Cross-origin links remain absolute
|
|
88
|
+
* deLocalizeHref("https://example.com/de/about")
|
|
89
|
+
* // => "https://example.com/about"
|
|
90
|
+
* ```
|
|
51
91
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* // => "http://example.com/about"
|
|
92
|
+
* For server-side URL de-localization (e.g., in middleware), use `deLocalizeUrl()`
|
|
93
|
+
* which provides more precise control over URL handling.
|
|
55
94
|
*
|
|
56
|
-
* @param {string} href
|
|
57
|
-
* @returns {string}
|
|
95
|
+
* @param {string} href - The href to de-localize (can be relative or absolute)
|
|
96
|
+
* @returns {string} The de-localized href, relative if input was relative
|
|
97
|
+
* @see deLocalizeUrl - For low-level URL de-localization in server contexts
|
|
58
98
|
*/
|
|
59
99
|
export function deLocalizeHref(href) {
|
|
60
100
|
const url = new URL(href, getUrlOrigin());
|
|
@@ -66,17 +106,3 @@ export function deLocalizeHref(href) {
|
|
|
66
106
|
}
|
|
67
107
|
return deLocalized.href;
|
|
68
108
|
}
|
|
69
|
-
/**
|
|
70
|
-
* @deprecated use `localizeHref` instead and give feedback on here https://github.com/opral/inlang-paraglide-js/issues/380
|
|
71
|
-
* @type {(href: string, options?: { locale?: string }) => string}
|
|
72
|
-
*/
|
|
73
|
-
export function localizePath(href, options) {
|
|
74
|
-
return localizeHref(href, options);
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* @deprecated use `deLocalizeHref` instead and give feedback on here https://github.com/opral/inlang-paraglide-js/issues/380
|
|
78
|
-
* @type {(href: string) => string}
|
|
79
|
-
*/
|
|
80
|
-
export function deLocalizePath(href) {
|
|
81
|
-
return deLocalizeHref(href);
|
|
82
|
-
}
|
|
@@ -1,13 +1,85 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Lower-level URL localization function, primarily used in server contexts.
|
|
3
|
+
*
|
|
4
|
+
* This function is designed for server-side usage where you need precise control
|
|
5
|
+
* over URL localization, such as in middleware or request handlers. It works with
|
|
6
|
+
* URL objects and always returns absolute URLs.
|
|
7
|
+
*
|
|
8
|
+
* For client-side UI components, use `localizeHref()` instead, which provides
|
|
9
|
+
* a more convenient API with relative paths and automatic locale detection.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Server middleware example
|
|
14
|
+
* app.use((req, res, next) => {
|
|
15
|
+
* const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);
|
|
16
|
+
* const localized = localizeUrl(url, { locale: "de" });
|
|
17
|
+
*
|
|
18
|
+
* if (localized.href !== url.href) {
|
|
19
|
+
* return res.redirect(localized.href);
|
|
20
|
+
* }
|
|
21
|
+
* next();
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Using with URL patterns
|
|
28
|
+
* const url = new URL("https://example.com/about");
|
|
29
|
+
* localizeUrl(url, { locale: "de" });
|
|
30
|
+
* // => URL("https://example.com/de/about")
|
|
31
|
+
*
|
|
32
|
+
* // Using with domain-based localization
|
|
33
|
+
* const url = new URL("https://example.com/store");
|
|
34
|
+
* localizeUrl(url, { locale: "de" });
|
|
35
|
+
* // => URL("https://de.example.com/store")
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @param {string | URL} url - The URL to localize. If string, must be absolute.
|
|
39
|
+
* @param {Object} [options] - Options for localization
|
|
40
|
+
* @param {string} [options.locale] - Target locale. If not provided, uses getLocale()
|
|
41
|
+
* @returns {URL} The localized URL, always absolute
|
|
7
42
|
*/
|
|
8
|
-
export function localizeUrl(url: string | URL, options
|
|
9
|
-
locale
|
|
43
|
+
export function localizeUrl(url: string | URL, options?: {
|
|
44
|
+
locale?: string | undefined;
|
|
10
45
|
}): URL;
|
|
46
|
+
/**
|
|
47
|
+
* Low-level URL de-localization function, primarily used in server contexts.
|
|
48
|
+
*
|
|
49
|
+
* This function is designed for server-side usage where you need precise control
|
|
50
|
+
* over URL de-localization, such as in middleware or request handlers. It works with
|
|
51
|
+
* URL objects and always returns absolute URLs.
|
|
52
|
+
*
|
|
53
|
+
* For client-side UI components, use `deLocalizeHref()` instead, which provides
|
|
54
|
+
* a more convenient API with relative paths.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Server middleware example
|
|
59
|
+
* app.use((req, res, next) => {
|
|
60
|
+
* const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);
|
|
61
|
+
* const baseUrl = deLocalizeUrl(url);
|
|
62
|
+
*
|
|
63
|
+
* // Store the base URL for later use
|
|
64
|
+
* req.baseUrl = baseUrl;
|
|
65
|
+
* next();
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Using with URL patterns
|
|
72
|
+
* const url = new URL("https://example.com/de/about");
|
|
73
|
+
* deLocalizeUrl(url); // => URL("https://example.com/about")
|
|
74
|
+
*
|
|
75
|
+
* // Using with domain-based localization
|
|
76
|
+
* const url = new URL("https://de.example.com/store");
|
|
77
|
+
* deLocalizeUrl(url); // => URL("https://example.com/store")
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @param {string | URL} url - The URL to de-localize. If string, must be absolute.
|
|
81
|
+
* @returns {URL} The de-localized URL, always absolute
|
|
82
|
+
*/
|
|
11
83
|
export function deLocalizeUrl(url: string | URL): URL;
|
|
12
|
-
export function aggregateGroups(match:
|
|
84
|
+
export function aggregateGroups(match: any): Record<string, string | null | undefined>;
|
|
13
85
|
//# sourceMappingURL=localize-url.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localize-url.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-url.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"localize-url.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/localize-url.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,iCALW,MAAM,GAAG,GAAG,YAEpB;IAAyB,MAAM;CAC/B,GAAU,GAAG,CAoCf;AAuCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,mCAHW,MAAM,GAAG,GAAG,GACV,GAAG,CAkCf;AAmFS,uCAAQ,GAAG,GAAK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA"}
|