@intlayer/core 7.3.15 → 7.4.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.
- package/dist/cjs/dist/esm/getStorageAttributes.cjs +134 -0
- package/dist/cjs/dist/esm/getStorageAttributes.cjs.map +1 -0
- package/dist/cjs/dist/esm/localization/localeResolver.cjs +28 -0
- package/dist/cjs/dist/esm/localization/localeResolver.cjs.map +1 -0
- package/dist/cjs/dist/esm/utils/getCookie.cjs +32 -0
- package/dist/cjs/dist/esm/utils/getCookie.cjs.map +1 -0
- package/dist/cjs/dist/esm/utils/localeStorage.cjs +61 -0
- package/dist/cjs/dist/esm/utils/localeStorage.cjs.map +1 -0
- package/dist/cjs/index.cjs +3 -1
- package/dist/cjs/localization/getLocale.cjs +4 -3
- package/dist/cjs/localization/getLocale.cjs.map +1 -1
- package/dist/cjs/localization/getLocalizedUrl.cjs +6 -1
- package/dist/cjs/localization/getLocalizedUrl.cjs.map +1 -1
- package/dist/cjs/localization/getMultilingualUrls.cjs +7 -1
- package/dist/cjs/localization/getMultilingualUrls.cjs.map +1 -1
- package/dist/cjs/localization/getPrefix.cjs +8 -2
- package/dist/cjs/localization/getPrefix.cjs.map +1 -1
- package/dist/cjs/localization/index.cjs +3 -1
- package/dist/cjs/localization/isValidLocale.cjs +54 -0
- package/dist/cjs/localization/isValidLocale.cjs.map +1 -0
- package/dist/cjs/localization/validatePrefix.cjs +54 -0
- package/dist/cjs/localization/validatePrefix.cjs.map +1 -0
- package/dist/esm/dist/esm/getStorageAttributes.mjs +133 -0
- package/dist/esm/dist/esm/getStorageAttributes.mjs.map +1 -0
- package/dist/esm/dist/esm/localization/localeResolver.mjs +26 -0
- package/dist/esm/dist/esm/localization/localeResolver.mjs.map +1 -0
- package/dist/esm/dist/esm/utils/getCookie.mjs +31 -0
- package/dist/esm/dist/esm/utils/getCookie.mjs.map +1 -0
- package/dist/esm/dist/esm/utils/localeStorage.mjs +59 -0
- package/dist/esm/dist/esm/utils/localeStorage.mjs.map +1 -0
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/localization/getLocale.mjs +2 -1
- package/dist/esm/localization/getLocale.mjs.map +1 -1
- package/dist/esm/localization/getLocalizedUrl.mjs +6 -1
- package/dist/esm/localization/getLocalizedUrl.mjs.map +1 -1
- package/dist/esm/localization/getMultilingualUrls.mjs +7 -1
- package/dist/esm/localization/getMultilingualUrls.mjs.map +1 -1
- package/dist/esm/localization/getPrefix.mjs +8 -2
- package/dist/esm/localization/getPrefix.mjs.map +1 -1
- package/dist/esm/localization/index.mjs +2 -1
- package/dist/esm/localization/isValidLocale.mjs +52 -0
- package/dist/esm/localization/isValidLocale.mjs.map +1 -0
- package/dist/esm/localization/validatePrefix.mjs +52 -0
- package/dist/esm/localization/validatePrefix.mjs.map +1 -0
- package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +7 -7
- package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts.map +1 -1
- package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +7 -7
- package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +7 -7
- package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts.map +1 -1
- package/dist/types/dictionaryManipulator/orderDictionaries.d.ts +2 -2
- package/dist/types/dictionaryManipulator/orderDictionaries.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
- package/dist/types/localization/getMultilingualUrls.d.ts.map +1 -1
- package/dist/types/localization/getPrefix.d.ts +2 -1
- package/dist/types/localization/getPrefix.d.ts.map +1 -1
- package/dist/types/localization/index.d.ts +2 -1
- package/dist/types/localization/isValidLocale.d.ts +35 -0
- package/dist/types/localization/isValidLocale.d.ts.map +1 -0
- package/dist/types/localization/validatePrefix.d.ts +38 -0
- package/dist/types/localization/validatePrefix.d.ts.map +1 -0
- package/dist/types/transpiler/enumeration/enumeration.d.ts.map +1 -1
- package/dist/types/transpiler/translation/translation.d.ts +1 -1
- package/dist/types/transpiler/translation/translation.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_localization_getPrefix = require('./getPrefix.cjs');
|
|
3
|
+
let __intlayer_config_client = require("@intlayer/config/client");
|
|
4
|
+
let __intlayer_config_built = require("@intlayer/config/built");
|
|
5
|
+
__intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
|
|
6
|
+
|
|
7
|
+
//#region src/localization/validatePrefix.ts
|
|
8
|
+
/**
|
|
9
|
+
* Checks whether a given locale is valid based on the configured locales.
|
|
10
|
+
*
|
|
11
|
+
* @param locale - The locale value to validate. Can be `undefined` or `null`.
|
|
12
|
+
* @param options - Optional configuration to override default settings.
|
|
13
|
+
* @param options.locales - Array of valid locales. Defaults to the configured internationalization locales.
|
|
14
|
+
* @param options.defaultLocale - The default locale to use as fallback. Defaults to the configured default locale.
|
|
15
|
+
* @param options.mode - The routing mode (`'prefix'`, `'prefix-all'`, or `'no-prefix'`). Defaults to the configured routing mode.
|
|
16
|
+
* @returns An object containing the validation result and the locale prefix.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // Check if 'en' is a valid locale
|
|
20
|
+
* const { isValid, localePrefix } = validatePrefix('en');
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Check with custom options
|
|
24
|
+
* const { isValid, localePrefix } = validatePrefix('fr', {
|
|
25
|
+
* locales: ['en', 'fr', 'es'],
|
|
26
|
+
* defaultLocale: 'en',
|
|
27
|
+
* mode: 'prefix-all',
|
|
28
|
+
* });
|
|
29
|
+
*/
|
|
30
|
+
const validatePrefix = (locale, options) => {
|
|
31
|
+
const { defaultLocale, mode, locales } = {
|
|
32
|
+
defaultLocale: __intlayer_config_built.default?.internationalization?.defaultLocale ?? __intlayer_config_client.DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
33
|
+
mode: __intlayer_config_built.default?.routing?.mode ?? __intlayer_config_client.DefaultValues.Routing.ROUTING_MODE,
|
|
34
|
+
locales: __intlayer_config_built.default?.internationalization?.locales ?? __intlayer_config_client.DefaultValues.Internationalization.LOCALES,
|
|
35
|
+
...options
|
|
36
|
+
};
|
|
37
|
+
const { localePrefix } = require_localization_getPrefix.getPrefix(locale || defaultLocale, {
|
|
38
|
+
mode,
|
|
39
|
+
locales,
|
|
40
|
+
defaultLocale
|
|
41
|
+
});
|
|
42
|
+
if (localePrefix === locale && locale === void 0) return {
|
|
43
|
+
isValid: true,
|
|
44
|
+
localePrefix: void 0
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
isValid: locales.some((localeEl) => localeEl === locale),
|
|
48
|
+
localePrefix
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
exports.validatePrefix = validatePrefix;
|
|
54
|
+
//# sourceMappingURL=validatePrefix.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validatePrefix.cjs","names":["configuration","DefaultValues","getPrefix"],"sources":["../../../src/localization/validatePrefix.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues } from '@intlayer/types';\nimport { getPrefix } from './getPrefix';\n\nexport type ValidatePrefixResult = {\n isValid: boolean;\n localePrefix: string | undefined;\n};\n\n/**\n * Checks whether a given locale is valid based on the configured locales.\n *\n * @param locale - The locale value to validate. Can be `undefined` or `null`.\n * @param options - Optional configuration to override default settings.\n * @param options.locales - Array of valid locales. Defaults to the configured internationalization locales.\n * @param options.defaultLocale - The default locale to use as fallback. Defaults to the configured default locale.\n * @param options.mode - The routing mode (`'prefix'`, `'prefix-all'`, or `'no-prefix'`). Defaults to the configured routing mode.\n * @returns An object containing the validation result and the locale prefix.\n *\n * @example\n * // Check if 'en' is a valid locale\n * const { isValid, localePrefix } = validatePrefix('en');\n *\n * @example\n * // Check with custom options\n * const { isValid, localePrefix } = validatePrefix('fr', {\n * locales: ['en', 'fr', 'es'],\n * defaultLocale: 'en',\n * mode: 'prefix-all',\n * });\n */\nexport const validatePrefix = (\n locale: LocalesValues | undefined | null,\n options?: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: typeof configuration.routing.mode;\n }\n): ValidatePrefixResult => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n // If no locale provided (optional param), will use default\n // In `routing.mode = 'prefix-all'`, the locale is required to be a valid locale\n const { localePrefix } = getPrefix(locale || defaultLocale, {\n mode,\n locales,\n defaultLocale,\n });\n\n if (localePrefix === locale && locale === undefined) {\n return { isValid: true, localePrefix: undefined };\n }\n\n // Check if the provided locale is valid\n const isValid: boolean = locales.some((localeEl) => localeEl === locale);\n\n return { isValid: isValid, localePrefix };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,kBACX,QACA,YAKyB;CACzB,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACEA,iCAAe,sBAAsB,iBACrCC,uCAAc,qBAAqB;EACrC,MAAMD,iCAAe,SAAS,QAAQC,uCAAc,QAAQ;EAC5D,SACED,iCAAe,sBAAsB,WACrCC,uCAAc,qBAAqB;EACrC,GAAG;EACJ;CAID,MAAM,EAAE,iBAAiBC,yCAAU,UAAU,eAAe;EAC1D;EACA;EACA;EACD,CAAC;AAEF,KAAI,iBAAiB,UAAU,WAAW,OACxC,QAAO;EAAE,SAAS;EAAM,cAAc;EAAW;AAMnD,QAAO;EAAE,SAFgB,QAAQ,MAAM,aAAa,aAAa,OAAO;EAE7C;EAAc"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { DefaultValues } from "@intlayer/config/client";
|
|
2
|
+
|
|
3
|
+
//#region dist/esm/getStorageAttributes.mjs
|
|
4
|
+
/**
|
|
5
|
+
* Creates a cookie entry with default values for missing attributes
|
|
6
|
+
*/
|
|
7
|
+
const createCookieEntry = (options) => {
|
|
8
|
+
const { name, path, expires, domain, secure, sameSite, httpOnly } = options ?? {};
|
|
9
|
+
return {
|
|
10
|
+
name: name ?? DefaultValues.Routing.COOKIE_NAME,
|
|
11
|
+
attributes: {
|
|
12
|
+
path,
|
|
13
|
+
expires,
|
|
14
|
+
domain,
|
|
15
|
+
secure,
|
|
16
|
+
sameSite,
|
|
17
|
+
httpOnly
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Creates a web storage entry (localStorage or sessionStorage) with default name
|
|
23
|
+
*/
|
|
24
|
+
const createWebStorageEntry = (options) => {
|
|
25
|
+
const { name } = options ?? {};
|
|
26
|
+
return { name: name ?? DefaultValues.Routing.LOCALE_STORAGE_NAME };
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Creates a header entry with default name
|
|
30
|
+
*/
|
|
31
|
+
const createHeaderEntry = (options) => {
|
|
32
|
+
const { name } = options ?? {};
|
|
33
|
+
return { name: name ?? DefaultValues.Routing.HEADER_NAME };
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Determines if a storage entry is a cookie based on its properties
|
|
37
|
+
*/
|
|
38
|
+
const isCookieEntry = (entry) => {
|
|
39
|
+
return entry.type === "cookie" || "sameSite" in entry || "httpOnly" in entry || "secure" in entry;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Determines the storage type from a string literal
|
|
43
|
+
*/
|
|
44
|
+
const isStorageType = (value) => {
|
|
45
|
+
return value === "cookie" || value === "localStorage" || value === "sessionStorage" || value === "header";
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Processes a single storage entry and returns the appropriate storage attributes
|
|
49
|
+
*/
|
|
50
|
+
const processStorageEntry = (entry) => {
|
|
51
|
+
if (typeof entry === "string") {
|
|
52
|
+
if (!isStorageType(entry)) return {
|
|
53
|
+
cookies: [],
|
|
54
|
+
localStorage: [],
|
|
55
|
+
sessionStorage: [],
|
|
56
|
+
headers: []
|
|
57
|
+
};
|
|
58
|
+
if (entry === "cookie") return { cookies: [createCookieEntry()] };
|
|
59
|
+
if (entry === "localStorage") return { localStorage: [createWebStorageEntry()] };
|
|
60
|
+
if (entry === "sessionStorage") return { sessionStorage: [createWebStorageEntry()] };
|
|
61
|
+
if (entry === "header") return { headers: [createHeaderEntry()] };
|
|
62
|
+
}
|
|
63
|
+
if (typeof entry === "object" && entry !== null) {
|
|
64
|
+
const typedEntry = entry;
|
|
65
|
+
if (isCookieEntry(typedEntry)) return { cookies: [createCookieEntry(typedEntry)] };
|
|
66
|
+
if ("type" in typedEntry && typedEntry.type === "localStorage") {
|
|
67
|
+
const { name: name$1, ...rest$1 } = typedEntry;
|
|
68
|
+
return { localStorage: [createWebStorageEntry({
|
|
69
|
+
name: name$1,
|
|
70
|
+
...rest$1
|
|
71
|
+
})] };
|
|
72
|
+
}
|
|
73
|
+
if ("type" in typedEntry && typedEntry.type === "sessionStorage") {
|
|
74
|
+
const { name: name$1, ...rest$1 } = typedEntry;
|
|
75
|
+
return { sessionStorage: [createWebStorageEntry({
|
|
76
|
+
name: name$1,
|
|
77
|
+
...rest$1
|
|
78
|
+
})] };
|
|
79
|
+
}
|
|
80
|
+
if ("type" in typedEntry && typedEntry.type === "header") {
|
|
81
|
+
const { name: name$1, ...rest$1 } = typedEntry;
|
|
82
|
+
return { headers: [createHeaderEntry({
|
|
83
|
+
name: name$1,
|
|
84
|
+
...rest$1
|
|
85
|
+
})] };
|
|
86
|
+
}
|
|
87
|
+
const { name, ...rest } = typedEntry;
|
|
88
|
+
return { localStorage: [createWebStorageEntry({
|
|
89
|
+
name,
|
|
90
|
+
...rest
|
|
91
|
+
})] };
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
cookies: [],
|
|
95
|
+
localStorage: [],
|
|
96
|
+
sessionStorage: [],
|
|
97
|
+
headers: []
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Merges multiple partial storage attributes into a single result
|
|
102
|
+
*/
|
|
103
|
+
const mergeStorageAttributes = (accumulated, partial) => {
|
|
104
|
+
return {
|
|
105
|
+
cookies: [...accumulated.cookies, ...partial.cookies ?? []],
|
|
106
|
+
localStorage: [...accumulated.localStorage, ...partial.localStorage ?? []],
|
|
107
|
+
sessionStorage: [...accumulated.sessionStorage, ...partial.sessionStorage ?? []],
|
|
108
|
+
headers: [...accumulated.headers, ...partial.headers ?? []]
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Extracts and normalizes storage configuration into separate arrays for each storage type
|
|
113
|
+
*
|
|
114
|
+
* @param options - The storage configuration from IntlayerConfig
|
|
115
|
+
* @returns An object containing arrays for cookies, localStorage, and sessionStorage
|
|
116
|
+
*/
|
|
117
|
+
const getStorageAttributes = (options) => {
|
|
118
|
+
const emptyResult = {
|
|
119
|
+
cookies: [],
|
|
120
|
+
localStorage: [],
|
|
121
|
+
sessionStorage: [],
|
|
122
|
+
headers: []
|
|
123
|
+
};
|
|
124
|
+
if (options === false || options === void 0) return emptyResult;
|
|
125
|
+
if (Array.isArray(options)) return options.reduce((acc, entry) => {
|
|
126
|
+
return mergeStorageAttributes(acc, processStorageEntry(entry));
|
|
127
|
+
}, emptyResult);
|
|
128
|
+
return mergeStorageAttributes(emptyResult, processStorageEntry(options));
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
//#endregion
|
|
132
|
+
export { getStorageAttributes };
|
|
133
|
+
//# sourceMappingURL=getStorageAttributes.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getStorageAttributes.mjs","names":[],"sources":["../../getStorageAttributes.mjs"],"sourcesContent":["import { DefaultValues } from \"@intlayer/config/client\";\n\n//#region src/getStorageAttributes.ts\n/**\n* Creates a cookie entry with default values for missing attributes\n*/\nconst createCookieEntry = (options) => {\n\tconst { name, path, expires, domain, secure, sameSite, httpOnly } = options ?? {};\n\treturn {\n\t\tname: name ?? DefaultValues.Routing.COOKIE_NAME,\n\t\tattributes: {\n\t\t\tpath,\n\t\t\texpires,\n\t\t\tdomain,\n\t\t\tsecure,\n\t\t\tsameSite,\n\t\t\thttpOnly\n\t\t}\n\t};\n};\n/**\n* Creates a web storage entry (localStorage or sessionStorage) with default name\n*/\nconst createWebStorageEntry = (options) => {\n\tconst { name } = options ?? {};\n\treturn { name: name ?? DefaultValues.Routing.LOCALE_STORAGE_NAME };\n};\n/**\n* Creates a header entry with default name\n*/\nconst createHeaderEntry = (options) => {\n\tconst { name } = options ?? {};\n\treturn { name: name ?? DefaultValues.Routing.HEADER_NAME };\n};\n/**\n* Determines if a storage entry is a cookie based on its properties\n*/\nconst isCookieEntry = (entry) => {\n\treturn entry.type === \"cookie\" || \"sameSite\" in entry || \"httpOnly\" in entry || \"secure\" in entry;\n};\n/**\n* Determines the storage type from a string literal\n*/\nconst isStorageType = (value) => {\n\treturn value === \"cookie\" || value === \"localStorage\" || value === \"sessionStorage\" || value === \"header\";\n};\n/**\n* Processes a single storage entry and returns the appropriate storage attributes\n*/\nconst processStorageEntry = (entry) => {\n\tif (typeof entry === \"string\") {\n\t\tif (!isStorageType(entry)) return {\n\t\t\tcookies: [],\n\t\t\tlocalStorage: [],\n\t\t\tsessionStorage: [],\n\t\t\theaders: []\n\t\t};\n\t\tif (entry === \"cookie\") return { cookies: [createCookieEntry()] };\n\t\tif (entry === \"localStorage\") return { localStorage: [createWebStorageEntry()] };\n\t\tif (entry === \"sessionStorage\") return { sessionStorage: [createWebStorageEntry()] };\n\t\tif (entry === \"header\") return { headers: [createHeaderEntry()] };\n\t}\n\tif (typeof entry === \"object\" && entry !== null) {\n\t\tconst typedEntry = entry;\n\t\tif (isCookieEntry(typedEntry)) return { cookies: [createCookieEntry(typedEntry)] };\n\t\tif (\"type\" in typedEntry && typedEntry.type === \"localStorage\") {\n\t\t\tconst { name: name$1, ...rest$1 } = typedEntry;\n\t\t\treturn { localStorage: [createWebStorageEntry({\n\t\t\t\tname: name$1,\n\t\t\t\t...rest$1\n\t\t\t})] };\n\t\t}\n\t\tif (\"type\" in typedEntry && typedEntry.type === \"sessionStorage\") {\n\t\t\tconst { name: name$1, ...rest$1 } = typedEntry;\n\t\t\treturn { sessionStorage: [createWebStorageEntry({\n\t\t\t\tname: name$1,\n\t\t\t\t...rest$1\n\t\t\t})] };\n\t\t}\n\t\tif (\"type\" in typedEntry && typedEntry.type === \"header\") {\n\t\t\tconst { name: name$1, ...rest$1 } = typedEntry;\n\t\t\treturn { headers: [createHeaderEntry({\n\t\t\t\tname: name$1,\n\t\t\t\t...rest$1\n\t\t\t})] };\n\t\t}\n\t\tconst { name, ...rest } = typedEntry;\n\t\treturn { localStorage: [createWebStorageEntry({\n\t\t\tname,\n\t\t\t...rest\n\t\t})] };\n\t}\n\treturn {\n\t\tcookies: [],\n\t\tlocalStorage: [],\n\t\tsessionStorage: [],\n\t\theaders: []\n\t};\n};\n/**\n* Merges multiple partial storage attributes into a single result\n*/\nconst mergeStorageAttributes = (accumulated, partial) => {\n\treturn {\n\t\tcookies: [...accumulated.cookies, ...partial.cookies ?? []],\n\t\tlocalStorage: [...accumulated.localStorage, ...partial.localStorage ?? []],\n\t\tsessionStorage: [...accumulated.sessionStorage, ...partial.sessionStorage ?? []],\n\t\theaders: [...accumulated.headers, ...partial.headers ?? []]\n\t};\n};\n/**\n* Extracts and normalizes storage configuration into separate arrays for each storage type\n*\n* @param options - The storage configuration from IntlayerConfig\n* @returns An object containing arrays for cookies, localStorage, and sessionStorage\n*/\nconst getStorageAttributes = (options) => {\n\tconst emptyResult = {\n\t\tcookies: [],\n\t\tlocalStorage: [],\n\t\tsessionStorage: [],\n\t\theaders: []\n\t};\n\tif (options === false || options === void 0) return emptyResult;\n\tif (Array.isArray(options)) return options.reduce((acc, entry) => {\n\t\treturn mergeStorageAttributes(acc, processStorageEntry(entry));\n\t}, emptyResult);\n\treturn mergeStorageAttributes(emptyResult, processStorageEntry(options));\n};\n\n//#endregion\nexport { getStorageAttributes };\n//# sourceMappingURL=getStorageAttributes.mjs.map"],"mappings":";;;;;;AAMA,MAAM,qBAAqB,YAAY;CACtC,MAAM,EAAE,MAAM,MAAM,SAAS,QAAQ,QAAQ,UAAU,aAAa,WAAW,EAAE;AACjF,QAAO;EACN,MAAM,QAAQ,cAAc,QAAQ;EACpC,YAAY;GACX;GACA;GACA;GACA;GACA;GACA;GACA;EACD;;;;;AAKF,MAAM,yBAAyB,YAAY;CAC1C,MAAM,EAAE,SAAS,WAAW,EAAE;AAC9B,QAAO,EAAE,MAAM,QAAQ,cAAc,QAAQ,qBAAqB;;;;;AAKnE,MAAM,qBAAqB,YAAY;CACtC,MAAM,EAAE,SAAS,WAAW,EAAE;AAC9B,QAAO,EAAE,MAAM,QAAQ,cAAc,QAAQ,aAAa;;;;;AAK3D,MAAM,iBAAiB,UAAU;AAChC,QAAO,MAAM,SAAS,YAAY,cAAc,SAAS,cAAc,SAAS,YAAY;;;;;AAK7F,MAAM,iBAAiB,UAAU;AAChC,QAAO,UAAU,YAAY,UAAU,kBAAkB,UAAU,oBAAoB,UAAU;;;;;AAKlG,MAAM,uBAAuB,UAAU;AACtC,KAAI,OAAO,UAAU,UAAU;AAC9B,MAAI,CAAC,cAAc,MAAM,CAAE,QAAO;GACjC,SAAS,EAAE;GACX,cAAc,EAAE;GAChB,gBAAgB,EAAE;GAClB,SAAS,EAAE;GACX;AACD,MAAI,UAAU,SAAU,QAAO,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE;AACjE,MAAI,UAAU,eAAgB,QAAO,EAAE,cAAc,CAAC,uBAAuB,CAAC,EAAE;AAChF,MAAI,UAAU,iBAAkB,QAAO,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,EAAE;AACpF,MAAI,UAAU,SAAU,QAAO,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE;;AAElE,KAAI,OAAO,UAAU,YAAY,UAAU,MAAM;EAChD,MAAM,aAAa;AACnB,MAAI,cAAc,WAAW,CAAE,QAAO,EAAE,SAAS,CAAC,kBAAkB,WAAW,CAAC,EAAE;AAClF,MAAI,UAAU,cAAc,WAAW,SAAS,gBAAgB;GAC/D,MAAM,EAAE,MAAM,QAAQ,GAAG,WAAW;AACpC,UAAO,EAAE,cAAc,CAAC,sBAAsB;IAC7C,MAAM;IACN,GAAG;IACH,CAAC,CAAC,EAAE;;AAEN,MAAI,UAAU,cAAc,WAAW,SAAS,kBAAkB;GACjE,MAAM,EAAE,MAAM,QAAQ,GAAG,WAAW;AACpC,UAAO,EAAE,gBAAgB,CAAC,sBAAsB;IAC/C,MAAM;IACN,GAAG;IACH,CAAC,CAAC,EAAE;;AAEN,MAAI,UAAU,cAAc,WAAW,SAAS,UAAU;GACzD,MAAM,EAAE,MAAM,QAAQ,GAAG,WAAW;AACpC,UAAO,EAAE,SAAS,CAAC,kBAAkB;IACpC,MAAM;IACN,GAAG;IACH,CAAC,CAAC,EAAE;;EAEN,MAAM,EAAE,MAAM,GAAG,SAAS;AAC1B,SAAO,EAAE,cAAc,CAAC,sBAAsB;GAC7C;GACA,GAAG;GACH,CAAC,CAAC,EAAE;;AAEN,QAAO;EACN,SAAS,EAAE;EACX,cAAc,EAAE;EAChB,gBAAgB,EAAE;EAClB,SAAS,EAAE;EACX;;;;;AAKF,MAAM,0BAA0B,aAAa,YAAY;AACxD,QAAO;EACN,SAAS,CAAC,GAAG,YAAY,SAAS,GAAG,QAAQ,WAAW,EAAE,CAAC;EAC3D,cAAc,CAAC,GAAG,YAAY,cAAc,GAAG,QAAQ,gBAAgB,EAAE,CAAC;EAC1E,gBAAgB,CAAC,GAAG,YAAY,gBAAgB,GAAG,QAAQ,kBAAkB,EAAE,CAAC;EAChF,SAAS,CAAC,GAAG,YAAY,SAAS,GAAG,QAAQ,WAAW,EAAE,CAAC;EAC3D;;;;;;;;AAQF,MAAM,wBAAwB,YAAY;CACzC,MAAM,cAAc;EACnB,SAAS,EAAE;EACX,cAAc,EAAE;EAChB,gBAAgB,EAAE;EAClB,SAAS,EAAE;EACX;AACD,KAAI,YAAY,SAAS,YAAY,KAAK,EAAG,QAAO;AACpD,KAAI,MAAM,QAAQ,QAAQ,CAAE,QAAO,QAAQ,QAAQ,KAAK,UAAU;AACjE,SAAO,uBAAuB,KAAK,oBAAoB,MAAM,CAAC;IAC5D,YAAY;AACf,QAAO,uBAAuB,aAAa,oBAAoB,QAAQ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import configuration from "@intlayer/config/built";
|
|
2
|
+
|
|
3
|
+
//#region dist/esm/localization/localeResolver.mjs
|
|
4
|
+
/**
|
|
5
|
+
* Resolves the most specific locale from a user-provided list,
|
|
6
|
+
* or falls back to the default locale if no match is found.
|
|
7
|
+
*/
|
|
8
|
+
const localeResolver = (selectedLocale, locales = configuration?.internationalization?.locales, defaultLocale = configuration?.internationalization?.defaultLocale) => {
|
|
9
|
+
const requestedLocales = [selectedLocale].flat();
|
|
10
|
+
const normalize = (locale) => locale.trim().toLowerCase();
|
|
11
|
+
try {
|
|
12
|
+
for (const requested of requestedLocales) {
|
|
13
|
+
const normalizedRequested = normalize(requested);
|
|
14
|
+
const exactMatch = locales.find((loc) => normalize(loc) === normalizedRequested);
|
|
15
|
+
if (exactMatch) return exactMatch;
|
|
16
|
+
const [requestedLang] = normalizedRequested.split("-");
|
|
17
|
+
const partialMatch = locales.find((loc) => normalize(loc).split("-")[0] === requestedLang);
|
|
18
|
+
if (partialMatch) return partialMatch;
|
|
19
|
+
}
|
|
20
|
+
} catch (_error) {}
|
|
21
|
+
return defaultLocale;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
export { localeResolver };
|
|
26
|
+
//# sourceMappingURL=localeResolver.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localeResolver.mjs","names":[],"sources":["../../../localization/localeResolver.mjs"],"sourcesContent":["import configuration from \"@intlayer/config/built\";\n\n//#region src/localization/localeResolver.ts\n/**\n* Resolves the most specific locale from a user-provided list,\n* or falls back to the default locale if no match is found.\n*/\nconst localeResolver = (selectedLocale, locales = configuration?.internationalization?.locales, defaultLocale = configuration?.internationalization?.defaultLocale) => {\n\tconst requestedLocales = [selectedLocale].flat();\n\tconst normalize = (locale) => locale.trim().toLowerCase();\n\ttry {\n\t\tfor (const requested of requestedLocales) {\n\t\t\tconst normalizedRequested = normalize(requested);\n\t\t\tconst exactMatch = locales.find((loc) => normalize(loc) === normalizedRequested);\n\t\t\tif (exactMatch) return exactMatch;\n\t\t\tconst [requestedLang] = normalizedRequested.split(\"-\");\n\t\t\tconst partialMatch = locales.find((loc) => normalize(loc).split(\"-\")[0] === requestedLang);\n\t\t\tif (partialMatch) return partialMatch;\n\t\t}\n\t} catch (_error) {}\n\treturn defaultLocale;\n};\n\n//#endregion\nexport { localeResolver };\n//# sourceMappingURL=localeResolver.mjs.map"],"mappings":";;;;;;;AAOA,MAAM,kBAAkB,gBAAgB,UAAU,eAAe,sBAAsB,SAAS,gBAAgB,eAAe,sBAAsB,kBAAkB;CACtK,MAAM,mBAAmB,CAAC,eAAe,CAAC,MAAM;CAChD,MAAM,aAAa,WAAW,OAAO,MAAM,CAAC,aAAa;AACzD,KAAI;AACH,OAAK,MAAM,aAAa,kBAAkB;GACzC,MAAM,sBAAsB,UAAU,UAAU;GAChD,MAAM,aAAa,QAAQ,MAAM,QAAQ,UAAU,IAAI,KAAK,oBAAoB;AAChF,OAAI,WAAY,QAAO;GACvB,MAAM,CAAC,iBAAiB,oBAAoB,MAAM,IAAI;GACtD,MAAM,eAAe,QAAQ,MAAM,QAAQ,UAAU,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,cAAc;AAC1F,OAAI,aAAc,QAAO;;UAElB,QAAQ;AACjB,QAAO"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region dist/esm/utils/getCookie.mjs
|
|
2
|
+
/**
|
|
3
|
+
* Retrieves a cookie by name from a cookie string or document.cookie
|
|
4
|
+
* @param name - The name of the cookie to retrieve
|
|
5
|
+
* @param cookieString - Optional cookie string to parse (defaults to document.cookie in browser)
|
|
6
|
+
* @returns The cookie value or undefined if not found
|
|
7
|
+
*/
|
|
8
|
+
const getCookie = (name, cookieString) => {
|
|
9
|
+
try {
|
|
10
|
+
const str = cookieString ?? (typeof document !== "undefined" ? document.cookie : "");
|
|
11
|
+
if (!str) return void 0;
|
|
12
|
+
const pairs = str.split(";");
|
|
13
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
14
|
+
const part = pairs[i].trim();
|
|
15
|
+
if (!part) continue;
|
|
16
|
+
const equalIndex = part.indexOf("=");
|
|
17
|
+
if ((equalIndex >= 0 ? part.substring(0, equalIndex) : part) === name) {
|
|
18
|
+
const rawValue = equalIndex >= 0 ? part.substring(equalIndex + 1) : "";
|
|
19
|
+
try {
|
|
20
|
+
return decodeURIComponent(rawValue);
|
|
21
|
+
} catch {
|
|
22
|
+
return rawValue;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
} catch {}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
export { getCookie };
|
|
31
|
+
//# sourceMappingURL=getCookie.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getCookie.mjs","names":[],"sources":["../../../utils/getCookie.mjs"],"sourcesContent":["//#region src/utils/getCookie.ts\n/**\n* Retrieves a cookie by name from a cookie string or document.cookie\n* @param name - The name of the cookie to retrieve\n* @param cookieString - Optional cookie string to parse (defaults to document.cookie in browser)\n* @returns The cookie value or undefined if not found\n*/\nconst getCookie = (name, cookieString) => {\n\ttry {\n\t\tconst str = cookieString ?? (typeof document !== \"undefined\" ? document.cookie : \"\");\n\t\tif (!str) return void 0;\n\t\tconst pairs = str.split(\";\");\n\t\tfor (let i = 0; i < pairs.length; i++) {\n\t\t\tconst part = pairs[i].trim();\n\t\t\tif (!part) continue;\n\t\t\tconst equalIndex = part.indexOf(\"=\");\n\t\t\tif ((equalIndex >= 0 ? part.substring(0, equalIndex) : part) === name) {\n\t\t\t\tconst rawValue = equalIndex >= 0 ? part.substring(equalIndex + 1) : \"\";\n\t\t\t\ttry {\n\t\t\t\t\treturn decodeURIComponent(rawValue);\n\t\t\t\t} catch {\n\t\t\t\t\treturn rawValue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {}\n};\n\n//#endregion\nexport { getCookie };\n//# sourceMappingURL=getCookie.mjs.map"],"mappings":";;;;;;;AAOA,MAAM,aAAa,MAAM,iBAAiB;AACzC,KAAI;EACH,MAAM,MAAM,iBAAiB,OAAO,aAAa,cAAc,SAAS,SAAS;AACjF,MAAI,CAAC,IAAK,QAAO,KAAK;EACtB,MAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACtC,MAAM,OAAO,MAAM,GAAG,MAAM;AAC5B,OAAI,CAAC,KAAM;GACX,MAAM,aAAa,KAAK,QAAQ,IAAI;AACpC,QAAK,cAAc,IAAI,KAAK,UAAU,GAAG,WAAW,GAAG,UAAU,MAAM;IACtE,MAAM,WAAW,cAAc,IAAI,KAAK,UAAU,aAAa,EAAE,GAAG;AACpE,QAAI;AACH,YAAO,mBAAmB,SAAS;YAC5B;AACP,YAAO;;;;SAIH"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getStorageAttributes } from "../getStorageAttributes.mjs";
|
|
2
|
+
import { getCookie } from "./getCookie.mjs";
|
|
3
|
+
import configuration from "@intlayer/config/built";
|
|
4
|
+
|
|
5
|
+
//#region dist/esm/utils/localeStorage.mjs
|
|
6
|
+
/**
|
|
7
|
+
* Retrieves the locale from various storage mechanisms (cookies, localStorage, sessionStorage, headers).
|
|
8
|
+
* The function checks storage locations in order of priority as defined in the configuration.
|
|
9
|
+
*
|
|
10
|
+
* @returns The locale if found in any storage, or undefined if not found
|
|
11
|
+
*/
|
|
12
|
+
const getLocaleFromStorage = (options) => {
|
|
13
|
+
const { routing, internationalization } = configuration;
|
|
14
|
+
const { locales } = internationalization;
|
|
15
|
+
const { storage } = routing;
|
|
16
|
+
if (storage === false || options?.isCookieEnabled === false) return void 0;
|
|
17
|
+
const storageAttributes = getStorageAttributes(storage);
|
|
18
|
+
const isValidLocale = (value) => {
|
|
19
|
+
if (!value) return false;
|
|
20
|
+
return locales.includes(value);
|
|
21
|
+
};
|
|
22
|
+
const readCookie = (name) => {
|
|
23
|
+
try {
|
|
24
|
+
const fromOption = options?.getCookie?.(name);
|
|
25
|
+
if (fromOption !== null && fromOption !== void 0) return fromOption;
|
|
26
|
+
} catch {}
|
|
27
|
+
return getCookie(name);
|
|
28
|
+
};
|
|
29
|
+
for (let i = 0; i < storageAttributes.cookies.length; i++) {
|
|
30
|
+
const { name } = storageAttributes.cookies[i];
|
|
31
|
+
const value = readCookie(name);
|
|
32
|
+
if (isValidLocale(value)) return value;
|
|
33
|
+
}
|
|
34
|
+
for (let i = 0; i < storageAttributes.localStorage.length; i++) {
|
|
35
|
+
const { name } = storageAttributes.localStorage[i];
|
|
36
|
+
try {
|
|
37
|
+
const value = options?.getLocaleStorage?.(name);
|
|
38
|
+
if (isValidLocale(value)) return value;
|
|
39
|
+
} catch {}
|
|
40
|
+
}
|
|
41
|
+
for (let i = 0; i < storageAttributes.sessionStorage.length; i++) {
|
|
42
|
+
const { name } = storageAttributes.sessionStorage[i];
|
|
43
|
+
try {
|
|
44
|
+
const value = options?.getSessionStorage?.(name);
|
|
45
|
+
if (isValidLocale(value)) return value;
|
|
46
|
+
} catch {}
|
|
47
|
+
}
|
|
48
|
+
for (let i = 0; i < storageAttributes.headers.length; i++) {
|
|
49
|
+
const { name } = storageAttributes.headers[i];
|
|
50
|
+
try {
|
|
51
|
+
const value = options?.getHeader?.(name);
|
|
52
|
+
if (isValidLocale(value)) return value;
|
|
53
|
+
} catch {}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
export { getLocaleFromStorage };
|
|
59
|
+
//# sourceMappingURL=localeStorage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localeStorage.mjs","names":[],"sources":["../../../utils/localeStorage.mjs"],"sourcesContent":["import { getStorageAttributes } from \"../getStorageAttributes.mjs\";\nimport { getCookie } from \"./getCookie.mjs\";\nimport configuration from \"@intlayer/config/built\";\n\n//#region src/utils/localeStorage.ts\nconst buildCookieString = (name, value, attributes) => {\n\tconst parts = [`${name}=${encodeURIComponent(value)}`];\n\tif (attributes.path) parts.push(`Path=${attributes.path}`);\n\tif (attributes.domain) parts.push(`Domain=${attributes.domain}`);\n\tif (attributes.expires instanceof Date) parts.push(`Expires=${attributes.expires.toUTCString()}`);\n\tif (attributes.secure) parts.push(\"Secure\");\n\tif (attributes.sameSite) parts.push(`SameSite=${attributes.sameSite}`);\n\treturn parts.join(\"; \");\n};\n/**\n* Retrieves the locale from various storage mechanisms (cookies, localStorage, sessionStorage, headers).\n* The function checks storage locations in order of priority as defined in the configuration.\n*\n* @returns The locale if found in any storage, or undefined if not found\n*/\nconst getLocaleFromStorage = (options) => {\n\tconst { routing, internationalization } = configuration;\n\tconst { locales } = internationalization;\n\tconst { storage } = routing;\n\tif (storage === false || options?.isCookieEnabled === false) return void 0;\n\tconst storageAttributes = getStorageAttributes(storage);\n\tconst isValidLocale = (value) => {\n\t\tif (!value) return false;\n\t\treturn locales.includes(value);\n\t};\n\tconst readCookie = (name) => {\n\t\ttry {\n\t\t\tconst fromOption = options?.getCookie?.(name);\n\t\t\tif (fromOption !== null && fromOption !== void 0) return fromOption;\n\t\t} catch {}\n\t\treturn getCookie(name);\n\t};\n\tfor (let i = 0; i < storageAttributes.cookies.length; i++) {\n\t\tconst { name } = storageAttributes.cookies[i];\n\t\tconst value = readCookie(name);\n\t\tif (isValidLocale(value)) return value;\n\t}\n\tfor (let i = 0; i < storageAttributes.localStorage.length; i++) {\n\t\tconst { name } = storageAttributes.localStorage[i];\n\t\ttry {\n\t\t\tconst value = options?.getLocaleStorage?.(name);\n\t\t\tif (isValidLocale(value)) return value;\n\t\t} catch {}\n\t}\n\tfor (let i = 0; i < storageAttributes.sessionStorage.length; i++) {\n\t\tconst { name } = storageAttributes.sessionStorage[i];\n\t\ttry {\n\t\t\tconst value = options?.getSessionStorage?.(name);\n\t\t\tif (isValidLocale(value)) return value;\n\t\t} catch {}\n\t}\n\tfor (let i = 0; i < storageAttributes.headers.length; i++) {\n\t\tconst { name } = storageAttributes.headers[i];\n\t\ttry {\n\t\t\tconst value = options?.getHeader?.(name);\n\t\t\tif (isValidLocale(value)) return value;\n\t\t} catch {}\n\t}\n};\n/**\n* Stores the locale in various storage mechanisms (cookies, localStorage, sessionStorage, headers).\n* The function writes to all configured storage locations according to their attributes.\n* Respects overwrite flags for localStorage and sessionStorage.\n*\n* @param locale - The locale to store\n*/\nconst setLocaleInStorage = (locale, options) => {\n\tif (configuration.routing.storage === false || options?.isCookieEnabled === false) return;\n\tconst storageAttributes = getStorageAttributes(configuration.routing.storage);\n\tfor (let i = 0; i < storageAttributes.cookies.length; i++) {\n\t\tconst { name, attributes } = storageAttributes.cookies[i];\n\t\ttry {\n\t\t\tif (options?.setCookieStore) options?.setCookieStore?.(name, locale, {\n\t\t\t\t...attributes,\n\t\t\t\texpires: attributes.expires instanceof Date ? attributes.expires.getTime() : attributes.expires\n\t\t\t});\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\tif (options?.setCookieString) {\n\t\t\t\t\tconst cookieString = buildCookieString(name, locale, attributes);\n\t\t\t\t\toptions?.setCookieString?.(name, cookieString);\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t}\n\tif (options?.setLocaleStorage) for (let i = 0; i < storageAttributes.localStorage.length; i++) {\n\t\tconst { name } = storageAttributes.localStorage[i];\n\t\ttry {\n\t\t\tif (!(options?.overwrite ?? true) && options?.getLocaleStorage) {\n\t\t\t\tif (options?.getLocaleStorage?.(name)) continue;\n\t\t\t}\n\t\t\toptions?.setLocaleStorage?.(name, locale);\n\t\t} catch {}\n\t}\n\tif (options?.setSessionStorage) for (let i = 0; i < storageAttributes.sessionStorage.length; i++) {\n\t\tconst { name } = storageAttributes.sessionStorage[i];\n\t\ttry {\n\t\t\tif (!(options?.overwrite ?? true) && options?.getSessionStorage) {\n\t\t\t\tif (options?.getSessionStorage?.(name)) continue;\n\t\t\t}\n\t\t\toptions?.setSessionStorage?.(name, locale);\n\t\t} catch {}\n\t}\n\tif (options?.setHeader) for (let i = 0; i < storageAttributes.headers.length; i++) {\n\t\tconst { name } = storageAttributes.headers[i];\n\t\ttry {\n\t\t\toptions?.setHeader?.(name, locale);\n\t\t} catch {}\n\t}\n};\n/**\n* Utility object to get and set the locale in the storage by considering the configuration\n*\n* @property getLocale - Retrieves the locale from various storage mechanisms (cookies, localStorage, sessionStorage, headers).\n* Retrieves the locale from various storage mechanisms (cookies, localStorage, sessionStorage, headers).\n* The function checks storage locations in order of priority as defined in the configuration.\n*\n* @property setLocale - Stores the locale in various storage mechanisms (cookies, localStorage, sessionStorage, headers).\n* The function writes to all configured storage locations according to their attributes.\n* Respects overwrite flags for localStorage and sessionStorage.\n*\n* @returns The locale if found in any storage, or undefined if not found\n*/\nconst LocaleStorage = (options) => ({\n\tgetLocale: () => getLocaleFromStorage(options),\n\tsetLocale: (locale) => setLocaleInStorage(locale, options)\n});\n\n//#endregion\nexport { LocaleStorage, getLocaleFromStorage, setLocaleInStorage };\n//# sourceMappingURL=localeStorage.mjs.map"],"mappings":";;;;;;;;;;;AAoBA,MAAM,wBAAwB,YAAY;CACzC,MAAM,EAAE,SAAS,yBAAyB;CAC1C,MAAM,EAAE,YAAY;CACpB,MAAM,EAAE,YAAY;AACpB,KAAI,YAAY,SAAS,SAAS,oBAAoB,MAAO,QAAO,KAAK;CACzE,MAAM,oBAAoB,qBAAqB,QAAQ;CACvD,MAAM,iBAAiB,UAAU;AAChC,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,QAAQ,SAAS,MAAM;;CAE/B,MAAM,cAAc,SAAS;AAC5B,MAAI;GACH,MAAM,aAAa,SAAS,YAAY,KAAK;AAC7C,OAAI,eAAe,QAAQ,eAAe,KAAK,EAAG,QAAO;UAClD;AACR,SAAO,UAAU,KAAK;;AAEvB,MAAK,IAAI,IAAI,GAAG,IAAI,kBAAkB,QAAQ,QAAQ,KAAK;EAC1D,MAAM,EAAE,SAAS,kBAAkB,QAAQ;EAC3C,MAAM,QAAQ,WAAW,KAAK;AAC9B,MAAI,cAAc,MAAM,CAAE,QAAO;;AAElC,MAAK,IAAI,IAAI,GAAG,IAAI,kBAAkB,aAAa,QAAQ,KAAK;EAC/D,MAAM,EAAE,SAAS,kBAAkB,aAAa;AAChD,MAAI;GACH,MAAM,QAAQ,SAAS,mBAAmB,KAAK;AAC/C,OAAI,cAAc,MAAM,CAAE,QAAO;UAC1B;;AAET,MAAK,IAAI,IAAI,GAAG,IAAI,kBAAkB,eAAe,QAAQ,KAAK;EACjE,MAAM,EAAE,SAAS,kBAAkB,eAAe;AAClD,MAAI;GACH,MAAM,QAAQ,SAAS,oBAAoB,KAAK;AAChD,OAAI,cAAc,MAAM,CAAE,QAAO;UAC1B;;AAET,MAAK,IAAI,IAAI,GAAG,IAAI,kBAAkB,QAAQ,QAAQ,KAAK;EAC1D,MAAM,EAAE,SAAS,kBAAkB,QAAQ;AAC3C,MAAI;GACH,MAAM,QAAQ,SAAS,YAAY,KAAK;AACxC,OAAI,cAAc,MAAM,CAAE,QAAO;UAC1B"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -66,6 +66,7 @@ import { getPrefix } from "./localization/getPrefix.mjs";
|
|
|
66
66
|
import { getLocalizedUrl } from "./localization/getLocalizedUrl.mjs";
|
|
67
67
|
import { getMultilingualUrls } from "./localization/getMultilingualUrls.mjs";
|
|
68
68
|
import { localeFlatMap, localeMap, localeRecord } from "./localization/localeMapper.mjs";
|
|
69
|
+
import { validatePrefix } from "./localization/validatePrefix.mjs";
|
|
69
70
|
import { isSameKeyPath } from "./utils/isSameKeyPath.mjs";
|
|
70
71
|
|
|
71
|
-
export { CachedIntl, CachedIntl as Intl, LocaleStorage, buildMaskPlugin, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, condition as cond, conditionPlugin, createCachedIntl, currency, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, gender, genderPlugin, getBrowserLocale, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getHTMLTextDir, getInsertionValues, getIntlayer, getLocale, getLocaleFromPath, getLocaleFromStorage, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPrefix, getReplacedValuesContent, getSplittedContent, getSplittedDictionaryContent, getStorageAttributes, getTranslation, insertion as insert, insertContentInDictionary, insertionPlugin, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, nesting as nest, nestedPlugin, normalizeDictionaries, normalizeDictionary, number, orderDictionaries, parseYaml, percentage, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, setLocaleInStorage, translation as t, translationPlugin, units, updateNodeChildren };
|
|
72
|
+
export { CachedIntl, CachedIntl as Intl, LocaleStorage, buildMaskPlugin, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, condition as cond, conditionPlugin, createCachedIntl, currency, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, gender, genderPlugin, getBrowserLocale, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getHTMLTextDir, getInsertionValues, getIntlayer, getLocale, getLocaleFromPath, getLocaleFromStorage, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPrefix, getReplacedValuesContent, getSplittedContent, getSplittedDictionaryContent, getStorageAttributes, getTranslation, insertion as insert, insertContentInDictionary, insertionPlugin, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, nesting as nest, nestedPlugin, normalizeDictionaries, normalizeDictionary, number, orderDictionaries, parseYaml, percentage, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, setLocaleInStorage, translation as t, translationPlugin, units, updateNodeChildren, validatePrefix };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { localeResolver } from "../dist/esm/localization/localeResolver.mjs";
|
|
2
|
+
import { getLocaleFromStorage } from "../dist/esm/utils/localeStorage.mjs";
|
|
1
3
|
import { getPreferredLanguages } from "./localeDetector.mjs";
|
|
2
4
|
import { DefaultValues } from "@intlayer/config/client";
|
|
3
5
|
import configuration from "@intlayer/config/built";
|
|
4
|
-
import { getLocaleFromStorage, localeResolver } from "@intlayer/core";
|
|
5
6
|
|
|
6
7
|
//#region src/localization/getLocale.ts
|
|
7
8
|
const getLocale = async (ctx = {}) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocale.mjs","names":[],"sources":["../../../src/localization/getLocale.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport { getLocaleFromStorage, localeResolver } from '@intlayer/core';\nimport type { Locale } from '@intlayer/types';\nimport { getPreferredLanguages } from './localeDetector';\n\nexport type RequestContext = {\n getHeader?: (name: string) => string | null | undefined;\n getCookie?: (name: string) => string | null | undefined;\n};\n\nexport const getLocale = async (ctx: RequestContext = {}): Promise<Locale> => {\n const defaultLocale =\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE;\n const availableLocales =\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES;\n\n // Try locale from storage (cookie or header)\n const storedLocale = getLocaleFromStorage({\n getCookie: ctx.getCookie,\n getHeader: ctx.getHeader,\n });\n\n if (storedLocale) {\n return storedLocale;\n }\n\n // Fallback to Accept-Language negotiation\n const acceptLanguageHeader = ctx.getHeader?.('accept-language');\n\n if (!acceptLanguageHeader) {\n return defaultLocale;\n }\n\n const preferredLocaleStrings = getPreferredLanguages(\n acceptLanguageHeader,\n availableLocales\n );\n\n const userFallbackLocale = localeResolver(\n preferredLocaleStrings,\n availableLocales,\n defaultLocale\n );\n\n if (userFallbackLocale) {\n return userFallbackLocale;\n }\n\n // Default locale\n return defaultLocale;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"getLocale.mjs","names":[],"sources":["../../../src/localization/getLocale.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport { getLocaleFromStorage, localeResolver } from '@intlayer/core';\nimport type { Locale } from '@intlayer/types';\nimport { getPreferredLanguages } from './localeDetector';\n\nexport type RequestContext = {\n getHeader?: (name: string) => string | null | undefined;\n getCookie?: (name: string) => string | null | undefined;\n};\n\nexport const getLocale = async (ctx: RequestContext = {}): Promise<Locale> => {\n const defaultLocale =\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE;\n const availableLocales =\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES;\n\n // Try locale from storage (cookie or header)\n const storedLocale = getLocaleFromStorage({\n getCookie: ctx.getCookie,\n getHeader: ctx.getHeader,\n });\n\n if (storedLocale) {\n return storedLocale;\n }\n\n // Fallback to Accept-Language negotiation\n const acceptLanguageHeader = ctx.getHeader?.('accept-language');\n\n if (!acceptLanguageHeader) {\n return defaultLocale;\n }\n\n const preferredLocaleStrings = getPreferredLanguages(\n acceptLanguageHeader,\n availableLocales\n );\n\n const userFallbackLocale = localeResolver(\n preferredLocaleStrings,\n availableLocales,\n defaultLocale\n );\n\n if (userFallbackLocale) {\n return userFallbackLocale;\n }\n\n // Default locale\n return defaultLocale;\n};\n"],"mappings":";;;;;;;AAWA,MAAa,YAAY,OAAO,MAAsB,EAAE,KAAsB;CAC5E,MAAM,gBACJ,eAAe,sBAAsB,iBACrC,cAAc,qBAAqB;CACrC,MAAM,mBACJ,eAAe,sBAAsB,WACrC,cAAc,qBAAqB;CAGrC,MAAM,eAAe,qBAAqB;EACxC,WAAW,IAAI;EACf,WAAW,IAAI;EAChB,CAAC;AAEF,KAAI,aACF,QAAO;CAIT,MAAM,uBAAuB,IAAI,YAAY,kBAAkB;AAE/D,KAAI,CAAC,qBACH,QAAO;CAQT,MAAM,qBAAqB,eALI,sBAC7B,sBACA,iBACD,EAIC,kBACA,cACD;AAED,KAAI,mBACF,QAAO;AAIT,QAAO"}
|
|
@@ -42,7 +42,12 @@ import configuration from "@intlayer/config/built";
|
|
|
42
42
|
* @returns The localized URL for the current locale.
|
|
43
43
|
*/
|
|
44
44
|
const getLocalizedUrl = (url, currentLocale, options = {}) => {
|
|
45
|
-
const {
|
|
45
|
+
const { defaultLocale, mode, locales } = {
|
|
46
|
+
defaultLocale: configuration?.internationalization?.defaultLocale ?? DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
47
|
+
mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,
|
|
48
|
+
locales: configuration?.internationalization?.locales ?? DefaultValues.Internationalization.LOCALES,
|
|
49
|
+
...options
|
|
50
|
+
};
|
|
46
51
|
const urlWithoutLocale = getPathWithoutLocale(url, locales);
|
|
47
52
|
if (mode === "no-prefix") return urlWithoutLocale;
|
|
48
53
|
const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocalizedUrl.mjs","names":[],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues } from '@intlayer/types';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport { getPrefix } from './getPrefix';\n\n/**\n * Generate URL by prefixing the given URL with the referenced locale or adding search parameters\n * based on the routing mode. Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });\n * // Returns '/fr/about' for the French locale\n * // Returns '/about' for the English locale (default)\n *\n * // prefix-all mode\n * getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });\n * // Returns '/en/about' for the English locale\n * // Returns '/fr/about' for the French locale\n *\n * // search-params mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });\n * // Returns '/about?locale=fr' for the French locale\n *\n * // no-prefix mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });\n * // Returns '/about' for any locale\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param currentLocale - The current locale.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns The localized URL for the current locale.\n */\nexport const getLocalizedUrl = (\n url: string,\n currentLocale: LocalesValues,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): string => {\n const {
|
|
1
|
+
{"version":3,"file":"getLocalizedUrl.mjs","names":[],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues } from '@intlayer/types';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport { getPrefix } from './getPrefix';\n\n/**\n * Generate URL by prefixing the given URL with the referenced locale or adding search parameters\n * based on the routing mode. Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });\n * // Returns '/fr/about' for the French locale\n * // Returns '/about' for the English locale (default)\n *\n * // prefix-all mode\n * getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });\n * // Returns '/en/about' for the English locale\n * // Returns '/fr/about' for the French locale\n *\n * // search-params mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });\n * // Returns '/about?locale=fr' for the French locale\n *\n * // no-prefix mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });\n * // Returns '/about' for any locale\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param currentLocale - The current locale.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns The localized URL for the current locale.\n */\nexport const getLocalizedUrl = (\n url: string,\n currentLocale: LocalesValues,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): string => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n // Remove any existing locale segment from the URL\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n\n if (mode === 'no-prefix') {\n // No locale prefixing\n return urlWithoutLocale;\n }\n\n // Determine if the original URL is absolute (includes protocol)\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n\n // Initialize a URL object if the URL is absolute\n // For relative URLs, use a dummy base to leverage the URL API\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n // Prepare the base URL (protocol + host) if it's absolute\n const baseUrl = isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n\n if (mode === 'search-params') {\n // Use search parameters for locale handling\n const searchParams = new URLSearchParams(parsedUrl.search);\n searchParams.set('locale', currentLocale.toString());\n\n const queryString = searchParams.toString();\n const pathWithQuery = queryString\n ? `${parsedUrl.pathname}?${queryString}`\n : parsedUrl.pathname;\n\n if (isAbsoluteUrl) {\n return `${baseUrl}${pathWithQuery}${parsedUrl.hash}`;\n }\n\n return `${pathWithQuery}${parsedUrl.hash}`;\n }\n\n const { prefix } = getPrefix(currentLocale, {\n defaultLocale,\n mode,\n });\n\n // Construct the new pathname with or without the locale prefix\n let localizedPath = `/${prefix}${parsedUrl.pathname}`;\n\n // Remove double slashes\n localizedPath = localizedPath.replaceAll(/\\/+/g, '/');\n\n // Remove trailing slash for non-root paths\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n // Combine with the base URL if the original URL was absolute\n if (isAbsoluteUrl) {\n return `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n }\n\n return `${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAa,mBACX,KACA,eACA,UAII,EAAE,KACK;CACX,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACE,eAAe,sBAAsB,iBACrC,cAAc,qBAAqB;EACrC,MAAM,eAAe,SAAS,QAAQ,cAAc,QAAQ;EAC5D,SACE,eAAe,sBAAsB,WACrC,cAAc,qBAAqB;EACrC,GAAG;EACJ;CAGD,MAAM,mBAAmB,qBAAqB,KAAK,QAAQ;AAE3D,KAAI,SAAS,YAEX,QAAO;CAIT,MAAM,gBAAgB,mBAAmB,iBAAiB;CAI1D,MAAM,YAAY,gBACd,IAAI,IAAI,iBAAiB,GACzB,IAAI,IAAI,kBAAkB,qBAAqB;CAGnD,MAAM,UAAU,gBACZ,GAAG,UAAU,SAAS,IAAI,UAAU,SACpC;AAEJ,KAAI,SAAS,iBAAiB;EAE5B,MAAM,eAAe,IAAI,gBAAgB,UAAU,OAAO;AAC1D,eAAa,IAAI,UAAU,cAAc,UAAU,CAAC;EAEpD,MAAM,cAAc,aAAa,UAAU;EAC3C,MAAM,gBAAgB,cAClB,GAAG,UAAU,SAAS,GAAG,gBACzB,UAAU;AAEd,MAAI,cACF,QAAO,GAAG,UAAU,gBAAgB,UAAU;AAGhD,SAAO,GAAG,gBAAgB,UAAU;;CAGtC,MAAM,EAAE,WAAW,UAAU,eAAe;EAC1C;EACA;EACD,CAAC;CAGF,IAAI,gBAAgB,IAAI,SAAS,UAAU;AAG3C,iBAAgB,cAAc,WAAW,QAAQ,IAAI;AAGrD,KAAI,cAAc,SAAS,KAAK,cAAc,SAAS,IAAI,CACzD,iBAAgB,cAAc,MAAM,GAAG,GAAG;AAI5C,KAAI,cACF,QAAO,GAAG,UAAU,gBAAgB,UAAU,SAAS,UAAU;AAGnE,QAAO,GAAG,gBAAgB,UAAU,SAAS,UAAU"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getLocalizedUrl } from "./getLocalizedUrl.mjs";
|
|
2
|
+
import { DefaultValues } from "@intlayer/config/client";
|
|
2
3
|
import configuration from "@intlayer/config/built";
|
|
3
4
|
|
|
4
5
|
//#region src/localization/getMultilingualUrls.ts
|
|
@@ -37,7 +38,12 @@ import configuration from "@intlayer/config/built";
|
|
|
37
38
|
* @returns An object mapping each locale to its corresponding multilingual URL.
|
|
38
39
|
*/
|
|
39
40
|
const getMultilingualUrls = (url, options = {}) => {
|
|
40
|
-
const {
|
|
41
|
+
const { defaultLocale, mode, locales } = {
|
|
42
|
+
defaultLocale: configuration?.internationalization?.defaultLocale ?? DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
43
|
+
mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,
|
|
44
|
+
locales: configuration?.internationalization?.locales ?? DefaultValues.Internationalization.LOCALES,
|
|
45
|
+
...options
|
|
46
|
+
};
|
|
41
47
|
return (locales ?? []).reduce((acc, locale) => {
|
|
42
48
|
acc[locale] = getLocalizedUrl(url, locale, {
|
|
43
49
|
locales,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getMultilingualUrls.mjs","names":[],"sources":["../../../src/localization/getMultilingualUrls.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\nimport { getLocalizedUrl } from './getLocalizedUrl';\n\n/**\n * Generates multilingual URLs by prefixing the given URL with each supported locale\n * or adding search parameters based on the routing mode.\n * Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { en: '/dashboard', fr: '/fr/dashboard' }\n *\n * // prefix-all mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { en: '/en/dashboard', fr: '/fr/dashboard' }\n *\n * // search-params mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' })\n * // Returns { en: '/dashboard?locale=en', fr: '/dashboard?locale=fr' }\n *\n * // no-prefix mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { en: '/dashboard', fr: '/dashboard' }\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object mapping each locale to its corresponding multilingual URL.\n */\nexport const getMultilingualUrls = (\n url: string,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): StrictModeLocaleMap<string> => {\n const {
|
|
1
|
+
{"version":3,"file":"getMultilingualUrls.mjs","names":[],"sources":["../../../src/localization/getMultilingualUrls.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\nimport { getLocalizedUrl } from './getLocalizedUrl';\n\n/**\n * Generates multilingual URLs by prefixing the given URL with each supported locale\n * or adding search parameters based on the routing mode.\n * Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { en: '/dashboard', fr: '/fr/dashboard' }\n *\n * // prefix-all mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { en: '/en/dashboard', fr: '/fr/dashboard' }\n *\n * // search-params mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' })\n * // Returns { en: '/dashboard?locale=en', fr: '/dashboard?locale=fr' }\n *\n * // no-prefix mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { en: '/dashboard', fr: '/dashboard' }\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object mapping each locale to its corresponding multilingual URL.\n */\nexport const getMultilingualUrls = (\n url: string,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): StrictModeLocaleMap<string> => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n // Generate multilingual URLs by iterating over each locale and calling getLocalizedUrl\n const multilingualUrls = (locales ?? []).reduce<StrictModeLocaleMap<string>>(\n (acc, locale) => {\n // Get the localized URL for this locale\n const localizedUrl = getLocalizedUrl(url, locale, {\n locales,\n defaultLocale,\n mode,\n });\n\n // Assign the constructed URL to the corresponding locale key\n acc[locale as unknown as keyof typeof acc] = localizedUrl;\n\n return acc;\n },\n {} as StrictModeLocaleMap<string>\n );\n\n return multilingualUrls;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAa,uBACX,KACA,UAII,EAAE,KAC0B;CAChC,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACE,eAAe,sBAAsB,iBACrC,cAAc,qBAAqB;EACrC,MAAM,eAAe,SAAS,QAAQ,cAAc,QAAQ;EAC5D,SACE,eAAe,sBAAsB,WACrC,cAAc,qBAAqB;EACrC,GAAG;EACJ;AAoBD,SAjB0B,WAAW,EAAE,EAAE,QACtC,KAAK,WAAW;AASf,MAAI,UAPiB,gBAAgB,KAAK,QAAQ;GAChD;GACA;GACA;GACD,CAAC;AAKF,SAAO;IAET,EAAE,CACH"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DefaultValues } from "@intlayer/config/client";
|
|
1
2
|
import configuration from "@intlayer/config/built";
|
|
2
3
|
|
|
3
4
|
//#region src/localization/getPrefix.ts
|
|
@@ -35,8 +36,13 @@ import configuration from "@intlayer/config/built";
|
|
|
35
36
|
* @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.
|
|
36
37
|
*/
|
|
37
38
|
const getPrefix = (locale, options = {}) => {
|
|
38
|
-
const { defaultLocale
|
|
39
|
-
|
|
39
|
+
const { defaultLocale, mode, locales } = {
|
|
40
|
+
defaultLocale: configuration?.internationalization?.defaultLocale ?? DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
41
|
+
mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,
|
|
42
|
+
locales: configuration?.internationalization?.locales ?? DefaultValues.Internationalization.LOCALES,
|
|
43
|
+
...options
|
|
44
|
+
};
|
|
45
|
+
if (!locale || !locales.includes(locale)) return {
|
|
40
46
|
prefix: "",
|
|
41
47
|
localePrefix: void 0
|
|
42
48
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPrefix.mjs","names":[],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { Locale, LocalesValues } from '@intlayer/types';\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n};\n\nexport type GetPrefixResult = {\n /**\n * The complete base URL path with leading and trailing slashes.\n *\n * @example\n * // https://example.com/fr/about -> '/fr'\n * // https://example.com/about -> ''\n */\n prefix: string;\n /**\n * The locale identifier without slashes.\n *\n * @example\n * // https://example.com/fr/about -> 'fr'\n * // https://example.com/about -> undefined\n */\n localePrefix: Locale | undefined;\n};\n\n/**\n * Determines the URL prefix for a given locale based on the routing mode configuration.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode with default locale\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // prefix-no-default mode with non-default locale\n * getPrefix('fr', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '/fr', localePrefix: 'fr' }\n *\n * // prefix-all mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { prefix: '/en', localePrefix: locale }\n *\n * // search-params mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'search-params' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // no-prefix mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { prefix: '', localePrefix: undefined }\n * ```\n *\n * @param locale - The locale to check for prefix. If not provided, uses configured default locale.\n * @param options - Configuration options\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.\n */\nexport const getPrefix = (\n locale: LocalesValues,\n options: {\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): GetPrefixResult => {\n const {\n defaultLocale
|
|
1
|
+
{"version":3,"file":"getPrefix.mjs","names":[],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { Locale, LocalesValues } from '@intlayer/types';\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n};\n\nexport type GetPrefixResult = {\n /**\n * The complete base URL path with leading and trailing slashes.\n *\n * @example\n * // https://example.com/fr/about -> '/fr'\n * // https://example.com/about -> ''\n */\n prefix: string;\n /**\n * The locale identifier without slashes.\n *\n * @example\n * // https://example.com/fr/about -> 'fr'\n * // https://example.com/about -> undefined\n */\n localePrefix: Locale | undefined;\n};\n\n/**\n * Determines the URL prefix for a given locale based on the routing mode configuration.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode with default locale\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // prefix-no-default mode with non-default locale\n * getPrefix('fr', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '/fr', localePrefix: 'fr' }\n *\n * // prefix-all mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { prefix: '/en', localePrefix: locale }\n *\n * // search-params mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'search-params' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // no-prefix mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { prefix: '', localePrefix: undefined }\n * ```\n *\n * @param locale - The locale to check for prefix. If not provided, uses configured default locale.\n * @param options - Configuration options\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.\n */\nexport const getPrefix = (\n locale: LocalesValues | undefined,\n options: {\n defaultLocale?: LocalesValues;\n locales?: LocalesValues[];\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): GetPrefixResult => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n if (!locale || !locales.includes(locale)) {\n return {\n prefix: '',\n localePrefix: undefined,\n };\n }\n\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n mode === 'prefix-all' ||\n (mode === 'prefix-no-default' && defaultLocale !== locale);\n\n if (shouldPrefix) {\n return {\n prefix: `${locale}/`,\n localePrefix: locale as Locale,\n };\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,MAAa,aACX,QACA,UAII,EAAE,KACc;CACpB,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACE,eAAe,sBAAsB,iBACrC,cAAc,qBAAqB;EACrC,MAAM,eAAe,SAAS,QAAQ,cAAc,QAAQ;EAC5D,SACE,eAAe,sBAAsB,WACrC,cAAc,qBAAqB;EACrC,GAAG;EACJ;AAED,KAAI,CAAC,UAAU,CAAC,QAAQ,SAAS,OAAO,CACtC,QAAO;EACL,QAAQ;EACR,cAAc;EACf;AAQH,KAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,OAGnD,QAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;EACf;AAGH,QAAO;EACL,QAAQ;EACR,cAAc;EACf"}
|
|
@@ -10,5 +10,6 @@ import { getPrefix } from "./getPrefix.mjs";
|
|
|
10
10
|
import { getLocalizedUrl } from "./getLocalizedUrl.mjs";
|
|
11
11
|
import { getMultilingualUrls } from "./getMultilingualUrls.mjs";
|
|
12
12
|
import { localeFlatMap, localeMap, localeRecord } from "./localeMapper.mjs";
|
|
13
|
+
import { validatePrefix } from "./validatePrefix.mjs";
|
|
13
14
|
|
|
14
|
-
export { getBrowserLocale, getHTMLTextDir, getLocaleFromPath, getLocaleLang, getLocaleName, getLocalizedUrl, getMultilingualUrls, getPathWithoutLocale, getPrefix, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions };
|
|
15
|
+
export { getBrowserLocale, getHTMLTextDir, getLocaleFromPath, getLocaleLang, getLocaleName, getLocalizedUrl, getMultilingualUrls, getPathWithoutLocale, getPrefix, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, validatePrefix };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getPrefix } from "./getPrefix.mjs";
|
|
2
|
+
import { DefaultValues } from "@intlayer/config/client";
|
|
3
|
+
import configuration from "@intlayer/config/built";
|
|
4
|
+
|
|
5
|
+
//#region src/localization/isValidLocale.ts
|
|
6
|
+
/**
|
|
7
|
+
* Checks whether a given locale is valid based on the configured locales.
|
|
8
|
+
*
|
|
9
|
+
* @param locale - The locale value to validate. Can be `undefined` or `null`.
|
|
10
|
+
* @param options - Optional configuration to override default settings.
|
|
11
|
+
* @param options.locales - Array of valid locales. Defaults to the configured internationalization locales.
|
|
12
|
+
* @param options.defaultLocale - The default locale to use as fallback. Defaults to the configured default locale.
|
|
13
|
+
* @param options.mode - The routing mode (`'prefix'`, `'prefix-all'`, or `'no-prefix'`). Defaults to the configured routing mode.
|
|
14
|
+
* @returns `true` if the locale is valid or if no locale is provided and the routing mode allows it; `false` otherwise.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Check if 'en' is a valid locale
|
|
18
|
+
* const isValid = validatePrefix('en');
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Check with custom options
|
|
22
|
+
* const isValid = validatePrefix('fr', {
|
|
23
|
+
* locales: ['en', 'fr', 'es'],
|
|
24
|
+
* defaultLocale: 'en',
|
|
25
|
+
* mode: 'prefix-all',
|
|
26
|
+
* });
|
|
27
|
+
*/
|
|
28
|
+
const validatePrefix = (locale, options) => {
|
|
29
|
+
const { defaultLocale, mode, locales } = {
|
|
30
|
+
defaultLocale: configuration?.internationalization?.defaultLocale ?? DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
31
|
+
mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,
|
|
32
|
+
locales: configuration?.internationalization?.locales ?? DefaultValues.Internationalization.LOCALES,
|
|
33
|
+
...options
|
|
34
|
+
};
|
|
35
|
+
const { localePrefix } = getPrefix(locale || defaultLocale, {
|
|
36
|
+
mode,
|
|
37
|
+
locales,
|
|
38
|
+
defaultLocale
|
|
39
|
+
});
|
|
40
|
+
if (localePrefix === locale && locale === void 0) return {
|
|
41
|
+
isValid: true,
|
|
42
|
+
localePrefix: void 0
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
isValid: locales.some((localeEl) => localeEl === locale),
|
|
46
|
+
localePrefix
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { validatePrefix };
|
|
52
|
+
//# sourceMappingURL=isValidLocale.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isValidLocale.mjs","names":[],"sources":["../../../src/localization/isValidLocale.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues } from '@intlayer/types';\nimport { getPrefix } from './getPrefix';\n\n/**\n * Checks whether a given locale is valid based on the configured locales.\n *\n * @param locale - The locale value to validate. Can be `undefined` or `null`.\n * @param options - Optional configuration to override default settings.\n * @param options.locales - Array of valid locales. Defaults to the configured internationalization locales.\n * @param options.defaultLocale - The default locale to use as fallback. Defaults to the configured default locale.\n * @param options.mode - The routing mode (`'prefix'`, `'prefix-all'`, or `'no-prefix'`). Defaults to the configured routing mode.\n * @returns `true` if the locale is valid or if no locale is provided and the routing mode allows it; `false` otherwise.\n *\n * @example\n * // Check if 'en' is a valid locale\n * const isValid = validatePrefix('en');\n *\n * @example\n * // Check with custom options\n * const isValid = validatePrefix('fr', {\n * locales: ['en', 'fr', 'es'],\n * defaultLocale: 'en',\n * mode: 'prefix-all',\n * });\n */\nexport const validatePrefix = (\n locale: LocalesValues | undefined | null,\n options?: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: typeof configuration.routing.mode;\n }\n): boolean => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n // If no locale provided (optional param), will use default\n // In `routing.mode = 'prefix-all'`, the locale is required to be a valid locale\n const { localePrefix } = getPrefix(locale || defaultLocale, {\n mode,\n locales,\n defaultLocale,\n });\n\n if (localePrefix === locale && locale === undefined) {\n return { isValid: true, localePrefix: undefined };\n }\n\n // Check if the provided locale is valid\n const isValidLocale: boolean = locales.some(\n (localeEl) => localeEl === locale\n );\n\n return { isValid: isValidLocale, localePrefix: localePrefix };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,MAAa,kBACX,QACA,YAKY;CACZ,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACE,eAAe,sBAAsB,iBACrC,cAAc,qBAAqB;EACrC,MAAM,eAAe,SAAS,QAAQ,cAAc,QAAQ;EAC5D,SACE,eAAe,sBAAsB,WACrC,cAAc,qBAAqB;EACrC,GAAG;EACJ;CAID,MAAM,EAAE,iBAAiB,UAAU,UAAU,eAAe;EAC1D;EACA;EACA;EACD,CAAC;AAEF,KAAI,iBAAiB,UAAU,WAAW,OACxC,QAAO;EAAE,SAAS;EAAM,cAAc;EAAW;AAQnD,QAAO;EAAE,SAJsB,QAAQ,MACpC,aAAa,aAAa,OAC5B;EAE8C;EAAc"}
|