@intlayer/core 9.5.9 → 9.5.11
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/dictionaryManipulator/qualifiedDictionary.cjs.map +1 -1
- package/dist/cjs/index.cjs +4 -0
- package/dist/cjs/interpreter/getContent/deepTransform.cjs +17 -22
- package/dist/cjs/interpreter/getContent/deepTransform.cjs.map +1 -1
- package/dist/cjs/interpreter/getContent/getContent.cjs +1 -1
- package/dist/cjs/interpreter/getContent/getContent.cjs.map +1 -1
- package/dist/cjs/interpreter/getContent/plugins.cjs +29 -30
- package/dist/cjs/interpreter/getContent/plugins.cjs.map +1 -1
- package/dist/cjs/interpreter/getDictionary.cjs +20 -5
- package/dist/cjs/interpreter/getDictionary.cjs.map +1 -1
- package/dist/cjs/interpreter/getTranslation.cjs +31 -27
- package/dist/cjs/interpreter/getTranslation.cjs.map +1 -1
- package/dist/cjs/localization/getPathWithoutLocale.cjs.map +1 -1
- package/dist/cjs/localization/localeResolver.cjs +1 -0
- package/dist/cjs/localization/localeResolver.cjs.map +1 -1
- package/dist/cjs/markdown/compiler.cjs +12 -3
- package/dist/cjs/markdown/compiler.cjs.map +1 -1
- package/dist/cjs/markdown/constants.cjs +3 -0
- package/dist/cjs/markdown/constants.cjs.map +1 -1
- package/dist/cjs/markdown/index.cjs +1 -0
- package/dist/cjs/markdown/utils.cjs +1 -1
- package/dist/cjs/markdown/utils.cjs.map +1 -1
- package/dist/cjs/messageFormat/ICU.cjs +10 -10
- package/dist/cjs/messageFormat/ICU.cjs.map +1 -1
- package/dist/cjs/messageFormat/i18next.cjs +7 -7
- package/dist/cjs/messageFormat/i18next.cjs.map +1 -1
- package/dist/cjs/messageFormat/po.cjs +1 -1
- package/dist/cjs/messageFormat/po.cjs.map +1 -1
- package/dist/cjs/messageFormat/resolveMessage.cjs +2 -2
- package/dist/cjs/messageFormat/resolveMessage.cjs.map +1 -1
- package/dist/cjs/messageFormat/verify-icu-format.cjs +4 -4
- package/dist/cjs/messageFormat/verify-icu-format.cjs.map +1 -1
- package/dist/cjs/messageFormat/vue-i18n.cjs +4 -4
- package/dist/cjs/messageFormat/vue-i18n.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +3 -0
- package/dist/cjs/utils/intlayerNodePrototype.cjs +66 -0
- package/dist/cjs/utils/intlayerNodePrototype.cjs.map +1 -0
- package/dist/cjs/utils/localeStorage.cjs +20 -0
- package/dist/cjs/utils/localeStorage.cjs.map +1 -1
- package/dist/esm/dictionaryManipulator/qualifiedDictionary.mjs.map +1 -1
- package/dist/esm/index.mjs +4 -3
- package/dist/esm/interpreter/getContent/deepTransform.mjs +17 -22
- package/dist/esm/interpreter/getContent/deepTransform.mjs.map +1 -1
- package/dist/esm/interpreter/getContent/getContent.mjs +2 -2
- package/dist/esm/interpreter/getContent/getContent.mjs.map +1 -1
- package/dist/esm/interpreter/getContent/plugins.mjs +29 -30
- package/dist/esm/interpreter/getContent/plugins.mjs.map +1 -1
- package/dist/esm/interpreter/getDictionary.mjs +20 -5
- package/dist/esm/interpreter/getDictionary.mjs.map +1 -1
- package/dist/esm/interpreter/getTranslation.mjs +31 -27
- package/dist/esm/interpreter/getTranslation.mjs.map +1 -1
- package/dist/esm/localization/getPathWithoutLocale.mjs.map +1 -1
- package/dist/esm/localization/localeResolver.mjs +1 -0
- package/dist/esm/localization/localeResolver.mjs.map +1 -1
- package/dist/esm/markdown/compiler.mjs +13 -4
- package/dist/esm/markdown/compiler.mjs.map +1 -1
- package/dist/esm/markdown/constants.mjs +3 -1
- package/dist/esm/markdown/constants.mjs.map +1 -1
- package/dist/esm/markdown/index.mjs +2 -2
- package/dist/esm/markdown/utils.mjs +1 -1
- package/dist/esm/markdown/utils.mjs.map +1 -1
- package/dist/esm/messageFormat/ICU.mjs +10 -10
- package/dist/esm/messageFormat/ICU.mjs.map +1 -1
- package/dist/esm/messageFormat/i18next.mjs +7 -7
- package/dist/esm/messageFormat/i18next.mjs.map +1 -1
- package/dist/esm/messageFormat/po.mjs +1 -1
- package/dist/esm/messageFormat/po.mjs.map +1 -1
- package/dist/esm/messageFormat/resolveMessage.mjs +2 -2
- package/dist/esm/messageFormat/resolveMessage.mjs.map +1 -1
- package/dist/esm/messageFormat/verify-icu-format.mjs +4 -4
- package/dist/esm/messageFormat/verify-icu-format.mjs.map +1 -1
- package/dist/esm/messageFormat/vue-i18n.mjs +4 -4
- package/dist/esm/messageFormat/vue-i18n.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +3 -2
- package/dist/esm/utils/intlayerNodePrototype.mjs +65 -0
- package/dist/esm/utils/intlayerNodePrototype.mjs.map +1 -0
- package/dist/esm/utils/localeStorage.mjs +20 -1
- package/dist/esm/utils/localeStorage.mjs.map +1 -1
- package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +1 -1
- package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +1 -1
- package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +1 -1
- package/dist/types/index.d.ts +4 -3
- package/dist/types/interpreter/getContent/deepTransform.d.ts.map +1 -1
- package/dist/types/interpreter/getContent/getContent.d.ts.map +1 -1
- package/dist/types/interpreter/getContent/plugins.d.ts +3 -1
- package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
- package/dist/types/interpreter/getDictionary.d.ts.map +1 -1
- package/dist/types/interpreter/getTranslation.d.ts.map +1 -1
- package/dist/types/markdown/compiler.d.ts +1 -0
- package/dist/types/markdown/compiler.d.ts.map +1 -1
- package/dist/types/markdown/constants.d.ts +2 -0
- package/dist/types/markdown/constants.d.ts.map +1 -1
- package/dist/types/markdown/index.d.ts +2 -2
- package/dist/types/messageFormat/ICU.d.ts.map +1 -1
- package/dist/types/messageFormat/i18next.d.ts.map +1 -1
- package/dist/types/messageFormat/vue-i18n.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +3 -2
- package/dist/types/utils/intlayerNodePrototype.d.ts +15 -0
- package/dist/types/utils/intlayerNodePrototype.d.ts.map +1 -0
- package/dist/types/utils/localeStorage.d.ts +9 -0
- package/dist/types/utils/localeStorage.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -14,20 +14,26 @@ const isPlainObject = (value) => {
|
|
|
14
14
|
/**
|
|
15
15
|
* Recursively merges two objects, skipping undefined source values.
|
|
16
16
|
* First argument takes precedence. Arrays replace rather than merge.
|
|
17
|
+
*
|
|
18
|
+
* Copy-on-write: an object the source adds nothing to is returned as-is, so a
|
|
19
|
+
* complete translation costs a read-only walk instead of a full copy.
|
|
17
20
|
*/
|
|
18
21
|
const deepMerge = (target, source) => {
|
|
19
22
|
if (target === void 0) return source;
|
|
20
23
|
if (source === void 0) return target;
|
|
21
24
|
if (Array.isArray(target)) return target;
|
|
22
|
-
if (isPlainObject(target)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
if (!isPlainObject(target) || !isPlainObject(source)) return target;
|
|
26
|
+
let result = target;
|
|
27
|
+
for (const key of Object.keys(source)) {
|
|
28
|
+
const sourceValue = source[key];
|
|
29
|
+
if (key === "__proto__" || key === "constructor" || sourceValue === void 0) continue;
|
|
30
|
+
const targetValue = target[key];
|
|
31
|
+
const merged = targetValue === void 0 ? sourceValue : typeof targetValue === "object" ? deepMerge(targetValue, sourceValue) : targetValue;
|
|
32
|
+
if (merged === targetValue) continue;
|
|
33
|
+
if (result === target) result = { ...target };
|
|
34
|
+
result[key] = merged;
|
|
29
35
|
}
|
|
30
|
-
return
|
|
36
|
+
return result;
|
|
31
37
|
};
|
|
32
38
|
/**
|
|
33
39
|
* Picks the appropriate content from a locale map based on the provided locale.
|
|
@@ -53,28 +59,26 @@ const deepMerge = (target, source) => {
|
|
|
53
59
|
* ```
|
|
54
60
|
*/
|
|
55
61
|
const getTranslation = (languageContent, locale, fallback) => {
|
|
56
|
-
const get = (
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
addLocale(locale);
|
|
66
|
-
if (locale.includes("-")) addLocale(locale.split("-")[0]);
|
|
67
|
-
addLocale(fallback);
|
|
68
|
-
if (fallback?.includes("-")) addLocale(fallback.split("-")[0]);
|
|
62
|
+
const get = (localeEl) => languageContent[localeEl];
|
|
63
|
+
const exactMatch = get(locale);
|
|
64
|
+
if (typeof exactMatch === "string") return exactMatch;
|
|
65
|
+
const candidates = [
|
|
66
|
+
locale,
|
|
67
|
+
locale.split("-")[0],
|
|
68
|
+
fallback,
|
|
69
|
+
fallback?.split("-")[0]
|
|
70
|
+
];
|
|
69
71
|
const results = [];
|
|
70
|
-
for (
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
for (let index = 0; index < candidates.length; index++) {
|
|
73
|
+
const candidate = candidates[index];
|
|
74
|
+
if (!candidate || candidates.indexOf(candidate) < index) continue;
|
|
75
|
+
const value = get(candidate);
|
|
76
|
+
if (value === void 0) continue;
|
|
77
|
+
if (typeof value === "string") {
|
|
78
|
+
if (results.length === 0) return value;
|
|
75
79
|
continue;
|
|
76
80
|
}
|
|
77
|
-
results.push(
|
|
81
|
+
results.push(value);
|
|
78
82
|
}
|
|
79
83
|
if (results.length === 0) return void 0;
|
|
80
84
|
if (results.length === 1) return results[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTranslation.cjs","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type {\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Check if a value is a plain object that can be safely merged.\n * Returns false for Promises, React elements, class instances, etc.\n */\nconst isPlainObject = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object') return false;\n if (typeof (value as any).then === 'function') return false;\n if (\n (value as any).$$typeof !== undefined ||\n (value as any).__v_isVNode !== undefined ||\n (value as any)._isVNode !== undefined ||\n (value as any).isJSX !== undefined\n ) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null || Array.isArray(value);\n};\n\n/**\n * Recursively merges two objects, skipping undefined source values.\n * First argument takes precedence. Arrays replace rather than merge.\n */\nconst deepMerge = (target: any, source: any): any => {\n if (target === undefined) return source;\n if (source === undefined) return target;\n if (Array.isArray(target)) return target;\n if (isPlainObject(target)
|
|
1
|
+
{"version":3,"file":"getTranslation.cjs","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type {\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Check if a value is a plain object that can be safely merged.\n * Returns false for Promises, React elements, class instances, etc.\n */\nconst isPlainObject = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object') return false;\n if (typeof (value as any).then === 'function') return false;\n if (\n (value as any).$$typeof !== undefined ||\n (value as any).__v_isVNode !== undefined ||\n (value as any)._isVNode !== undefined ||\n (value as any).isJSX !== undefined\n ) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null || Array.isArray(value);\n};\n\n/**\n * Recursively merges two objects, skipping undefined source values.\n * First argument takes precedence. Arrays replace rather than merge.\n *\n * Copy-on-write: an object the source adds nothing to is returned as-is, so a\n * complete translation costs a read-only walk instead of a full copy.\n */\nconst deepMerge = (target: any, source: any): any => {\n if (target === undefined) return source;\n if (source === undefined) return target;\n if (Array.isArray(target)) return target;\n if (!isPlainObject(target) || !isPlainObject(source)) return target;\n\n let result = target;\n\n for (const key of Object.keys(source)) {\n const sourceValue = source[key];\n\n if (\n key === '__proto__' ||\n key === 'constructor' ||\n sourceValue === undefined\n )\n continue;\n\n const targetValue = target[key];\n\n // Only objects need a recursive merge: a primitive the target holds wins\n const merged =\n targetValue === undefined\n ? sourceValue\n : typeof targetValue === 'object'\n ? deepMerge(targetValue, sourceValue)\n : targetValue;\n\n if (merged === targetValue) continue;\n\n if (result === target) result = { ...target };\n result[key] = merged;\n }\n\n return result;\n};\n\n/**\n * Picks the appropriate content from a locale map based on the provided locale.\n *\n * It handles:\n * 1. Exact locale match (e.g., 'en-US').\n * 2. Generic locale fallback (e.g., 'en' if 'en-US' is not found).\n * 3. Explicit fallback locale.\n * 4. Deep merging of objects to ensure partial translations are complemented by fallbacks.\n *\n * @param languageContent - A map of locales to content.\n * @param locale - The target locale to retrieve.\n * @param fallback - Optional fallback locale if the target is not found.\n * @returns The translated content.\n *\n * @example\n * ```ts\n * const content = getTranslation({\n * en: 'Hello',\n * fr: 'Bonjour',\n * }, 'fr');\n * // 'Bonjour'\n * ```\n */\nexport const getTranslation = <const Content = string>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues,\n fallback?: LocalesValues\n): Content => {\n const get = (localeEl: string): Content | undefined =>\n languageContent[localeEl as keyof typeof languageContent];\n\n // Fast path for the common case: a string for the exact locale always wins,\n // so the candidate chain below would return it anyway.\n const exactMatch = get(locale);\n if (typeof exactMatch === 'string') return exactMatch;\n\n // Priority-ordered locale candidates, most specific first\n const candidates = [\n locale,\n locale.split('-')[0],\n fallback,\n fallback?.split('-')[0],\n ];\n\n // Strings exit early (unless a higher-priority object was found), objects\n // are accumulated for deep merging\n const results: Content[] = [];\n\n for (let index = 0; index < candidates.length; index++) {\n const candidate = candidates[index];\n\n // Skip empty and repeated candidates\n if (!candidate || candidates.indexOf(candidate) < index) continue;\n\n const value = get(candidate);\n\n if (value === undefined) continue;\n if (typeof value === 'string') {\n if (results.length === 0) return value;\n continue; // an object at higher priority takes precedence\n }\n\n results.push(value);\n }\n\n if (results.length === 0) return undefined as Content;\n if (results.length === 1) return results[0]!;\n if (Array.isArray(results[0])) return results[0];\n\n // Merge objects: first result (most specific) takes precedence\n return (results as object[]).reduce((acc, curr) =>\n deepMerge(acc, curr)\n ) as Content;\n};\n"],"mappings":";;;;;;AASA,MAAM,iBAAiB,UAA4B;CACjD,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO;CACxD,IAAI,OAAQ,MAAc,SAAS,YAAY,OAAO;CACtD,IACG,MAAc,aAAa,UAC3B,MAAc,gBAAgB,UAC9B,MAAc,aAAa,UAC3B,MAAc,UAAU,QAEzB,OAAO;CAET,MAAM,QAAQ,OAAO,eAAe,KAAK;CACzC,OAAO,UAAU,OAAO,aAAa,UAAU,QAAQ,MAAM,QAAQ,KAAK;AAC5E;;;;;;;;AASA,MAAM,aAAa,QAAa,WAAqB;CACnD,IAAI,WAAW,QAAW,OAAO;CACjC,IAAI,WAAW,QAAW,OAAO;CACjC,IAAI,MAAM,QAAQ,MAAM,GAAG,OAAO;CAClC,IAAI,CAAC,cAAc,MAAM,KAAK,CAAC,cAAc,MAAM,GAAG,OAAO;CAE7D,IAAI,SAAS;CAEb,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG;EACrC,MAAM,cAAc,OAAO;EAE3B,IACE,QAAQ,eACR,QAAQ,iBACR,gBAAgB,QAEhB;EAEF,MAAM,cAAc,OAAO;EAG3B,MAAM,SACJ,gBAAgB,SACZ,cACA,OAAO,gBAAgB,WACrB,UAAU,aAAa,WAAW,IAClC;EAER,IAAI,WAAW,aAAa;EAE5B,IAAI,WAAW,QAAQ,SAAS,EAAE,GAAG,OAAO;EAC5C,OAAO,OAAO;CAChB;CAEA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,kBACX,iBACA,QACA,aACY;CACZ,MAAM,OAAO,aACX,gBAAgB;CAIlB,MAAM,aAAa,IAAI,MAAM;CAC7B,IAAI,OAAO,eAAe,UAAU,OAAO;CAG3C,MAAM,aAAa;EACjB;EACA,OAAO,MAAM,GAAG,CAAC,CAAC;EAClB;EACA,UAAU,MAAM,GAAG,CAAC,CAAC;CACvB;CAIA,MAAM,UAAqB,CAAC;CAE5B,KAAK,IAAI,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS;EACtD,MAAM,YAAY,WAAW;EAG7B,IAAI,CAAC,aAAa,WAAW,QAAQ,SAAS,IAAI,OAAO;EAEzD,MAAM,QAAQ,IAAI,SAAS;EAE3B,IAAI,UAAU,QAAW;EACzB,IAAI,OAAO,UAAU,UAAU;GAC7B,IAAI,QAAQ,WAAW,GAAG,OAAO;GACjC;EACF;EAEA,QAAQ,KAAK,KAAK;CACpB;CAEA,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,IAAI,QAAQ,WAAW,GAAG,OAAO,QAAQ;CACzC,IAAI,MAAM,QAAQ,QAAQ,EAAE,GAAG,OAAO,QAAQ;CAG9C,OAAQ,QAAqB,QAAQ,KAAK,SACxC,UAAU,KAAK,IAAI,CACrB;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPathWithoutLocale.cjs","names":["internationalization","checkIsURLAbsolute"],"sources":["../../../src/localization/getPathWithoutLocale.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\n/**\n * True when the build-time routing mode is known and is not a prefix-based\n * mode (neither 'prefix-all' nor 'prefix-no-default').\n */\nconst TREE_SHAKE_PREFIX_MODES =\n process.env.INTLAYER_ROUTING_MODE &&\n process.env.INTLAYER_ROUTING_MODE !== 'prefix-all' &&\n process.env.INTLAYER_ROUTING_MODE !== 'prefix-no-default';\n\n/**\n * True when the build-time routing mode is known and is NOT 'search-params'.\n */\nconst TREE_SHAKE_SEARCH_PARAMS =\n process.env.INTLAYER_ROUTING_MODE &&\n process.env.INTLAYER_ROUTING_MODE !== 'search-params';\n\nimport type {\n DeclaredLocales,\n LocalesValues,\n PathWithoutLocale,\n} from '@intlayer/types/module_augmentation';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\n\n/**\n * Removes the locale segment from the given URL or pathname if present.\n * Also removes locale from search parameters if present.\n *\n * This function get the locales from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * getPathWithoutLocale('/en/dashboard') // Returns '/dashboard'\n * getPathWithoutLocale('/fr/dashboard') // Returns '/dashboard'\n * getPathWithoutLocale('/dashboard') // Returns '/dashboard'\n * getPathWithoutLocale('dashboard') // Returns 'dashboard'\n * getPathWithoutLocale('/dashboard?locale=fr') // Returns '/dashboard'\n * getPathWithoutLocale('https://example.com/en/dashboard') // Returns 'https://example.com/dashboard'\n * getPathWithoutLocale('https://example.com/fr/dashboard') // Returns 'https://example.com/dashboard'\n * getPathWithoutLocale('https://example.com/dashboard') // Returns 'https://example.com/dashboard'\n * getPathWithoutLocale('https://example.com/dashboard?locale=fr') // Returns 'https://example.com/dashboard'\n * ```\n *\n * @param inputUrl - The complete URL string or pathname to process.\n * @param locales - Optional array of supported locales. Defaults to `localesDefault`.\n * @returns The URL string or pathname without the locale segment or locale search parameter.\n */\n/**\n * The return type is narrowed to a template-literal type when both `inputUrl`\n * and `locales` are string literals known at compile time. Absolute URLs fall\n * back to `string`.\n */\nexport const getPathWithoutLocale = <\n const T extends string,\n const L extends LocalesValues = DeclaredLocales,\n>(\n inputUrl: T,\n locales: L[] = internationalization?.locales as L[]\n): PathWithoutLocale<T, L> => {\n // Determine if the original URL is absolute (includes protocol)\n const isAbsoluteUrl = checkIsURLAbsolute(inputUrl);\n\n let fixedInputUrl = inputUrl;\n\n if (inputUrl?.endsWith('/')) {\n fixedInputUrl = inputUrl.slice(0, -1);\n }\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 url = isAbsoluteUrl\n ? new URL(fixedInputUrl)\n : new URL(fixedInputUrl, 'http://e.com');\n\n const pathname = url.pathname;\n\n // Ensure the pathname starts with '/'\n if (!pathname.startsWith('/')) {\n // If not, return the URL as is\n url.pathname = `/${pathname}`;\n }\n\n // Only strip locale path prefix in prefix-based routing modes\n if (!TREE_SHAKE_PREFIX_MODES) {\n // Split the pathname to extract the first segment\n const pathSegments = pathname.split('/');\n const firstSegment = pathSegments[1]; // The segment after the first '/'\n\n // Check if the first segment is a supported locale\n if (locales?.includes(firstSegment as L)) {\n // Remove the locale segment from the pathname\n pathSegments.splice(1, 1); // Remove the first segment\n\n // Reconstruct the pathname\n const newPathname = pathSegments.join('/') ?? '/';\n url.pathname = newPathname;\n }\n }\n\n // Only strip locale from search parameters in search-params routing mode\n if (!TREE_SHAKE_SEARCH_PARAMS) {\n const searchParams = new URLSearchParams(url.search);\n if (searchParams.has('locale')) {\n searchParams.delete('locale');\n url.search = searchParams.toString();\n }\n }\n\n if (isAbsoluteUrl) {\n return url.toString() as PathWithoutLocale<T, L>;\n }\n\n return url.toString().replace('http://e.com', '') as PathWithoutLocale<T, L>;\n};\n"],"mappings":";;;;;;;;;AAUA,MAAM,0BACJ,QAAQ,IAAI,yBACZ,QAAQ,IAAI,0BAA0B,gBACtC,QAAQ,IAAI,0BAA0B;;;;AAKxC,MAAM,2BACJ,QAAQ,IAAI,yBACZ,QAAQ,IAAI,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCxC,MAAa,wBAIX,UACA,UAAeA,6CAAsB,YACT;CAE5B,MAAM,gBAAgBC,oDAAmB,QAAQ;CAEjD,IAAI,
|
|
1
|
+
{"version":3,"file":"getPathWithoutLocale.cjs","names":["internationalization","checkIsURLAbsolute"],"sources":["../../../src/localization/getPathWithoutLocale.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\n/**\n * True when the build-time routing mode is known and is not a prefix-based\n * mode (neither 'prefix-all' nor 'prefix-no-default').\n */\nconst TREE_SHAKE_PREFIX_MODES =\n process.env.INTLAYER_ROUTING_MODE &&\n process.env.INTLAYER_ROUTING_MODE !== 'prefix-all' &&\n process.env.INTLAYER_ROUTING_MODE !== 'prefix-no-default';\n\n/**\n * True when the build-time routing mode is known and is NOT 'search-params'.\n */\nconst TREE_SHAKE_SEARCH_PARAMS =\n process.env.INTLAYER_ROUTING_MODE &&\n process.env.INTLAYER_ROUTING_MODE !== 'search-params';\n\nimport type {\n DeclaredLocales,\n LocalesValues,\n PathWithoutLocale,\n} from '@intlayer/types/module_augmentation';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\n\n/**\n * Removes the locale segment from the given URL or pathname if present.\n * Also removes locale from search parameters if present.\n *\n * This function get the locales from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * getPathWithoutLocale('/en/dashboard') // Returns '/dashboard'\n * getPathWithoutLocale('/fr/dashboard') // Returns '/dashboard'\n * getPathWithoutLocale('/dashboard') // Returns '/dashboard'\n * getPathWithoutLocale('dashboard') // Returns 'dashboard'\n * getPathWithoutLocale('/dashboard?locale=fr') // Returns '/dashboard'\n * getPathWithoutLocale('https://example.com/en/dashboard') // Returns 'https://example.com/dashboard'\n * getPathWithoutLocale('https://example.com/fr/dashboard') // Returns 'https://example.com/dashboard'\n * getPathWithoutLocale('https://example.com/dashboard') // Returns 'https://example.com/dashboard'\n * getPathWithoutLocale('https://example.com/dashboard?locale=fr') // Returns 'https://example.com/dashboard'\n * ```\n *\n * @param inputUrl - The complete URL string or pathname to process.\n * @param locales - Optional array of supported locales. Defaults to `localesDefault`.\n * @returns The URL string or pathname without the locale segment or locale search parameter.\n */\n/**\n * The return type is narrowed to a template-literal type when both `inputUrl`\n * and `locales` are string literals known at compile time. Absolute URLs fall\n * back to `string`.\n */\nexport const getPathWithoutLocale = <\n const T extends string,\n const L extends LocalesValues = DeclaredLocales,\n>(\n inputUrl: T,\n locales: L[] = internationalization?.locales as L[]\n): PathWithoutLocale<T, L> => {\n // Determine if the original URL is absolute (includes protocol)\n const isAbsoluteUrl = checkIsURLAbsolute(inputUrl);\n\n let fixedInputUrl: string = inputUrl;\n\n if (inputUrl?.endsWith('/')) {\n fixedInputUrl = inputUrl.slice(0, -1);\n }\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 url = isAbsoluteUrl\n ? new URL(fixedInputUrl)\n : new URL(fixedInputUrl, 'http://e.com');\n\n const pathname = url.pathname;\n\n // Ensure the pathname starts with '/'\n if (!pathname.startsWith('/')) {\n // If not, return the URL as is\n url.pathname = `/${pathname}`;\n }\n\n // Only strip locale path prefix in prefix-based routing modes\n if (!TREE_SHAKE_PREFIX_MODES) {\n // Split the pathname to extract the first segment\n const pathSegments = pathname.split('/');\n const firstSegment = pathSegments[1]; // The segment after the first '/'\n\n // Check if the first segment is a supported locale\n if (locales?.includes(firstSegment as L)) {\n // Remove the locale segment from the pathname\n pathSegments.splice(1, 1); // Remove the first segment\n\n // Reconstruct the pathname\n const newPathname = pathSegments.join('/') ?? '/';\n url.pathname = newPathname;\n }\n }\n\n // Only strip locale from search parameters in search-params routing mode\n if (!TREE_SHAKE_SEARCH_PARAMS) {\n const searchParams = new URLSearchParams(url.search);\n if (searchParams.has('locale')) {\n searchParams.delete('locale');\n url.search = searchParams.toString();\n }\n }\n\n if (isAbsoluteUrl) {\n return url.toString() as PathWithoutLocale<T, L>;\n }\n\n return url.toString().replace('http://e.com', '') as PathWithoutLocale<T, L>;\n};\n"],"mappings":";;;;;;;;;AAUA,MAAM,0BACJ,QAAQ,IAAI,yBACZ,QAAQ,IAAI,0BAA0B,gBACtC,QAAQ,IAAI,0BAA0B;;;;AAKxC,MAAM,2BACJ,QAAQ,IAAI,yBACZ,QAAQ,IAAI,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCxC,MAAa,wBAIX,UACA,UAAeA,6CAAsB,YACT;CAE5B,MAAM,gBAAgBC,oDAAmB,QAAQ;CAEjD,IAAI,gBAAwB;CAE5B,IAAI,UAAU,SAAS,GAAG,GACxB,gBAAgB,SAAS,MAAM,GAAG,EAAE;CAKtC,MAAM,MAAM,gBACR,IAAI,IAAI,aAAa,IACrB,IAAI,IAAI,eAAe,cAAc;CAEzC,MAAM,WAAW,IAAI;CAGrB,IAAI,CAAC,SAAS,WAAW,GAAG,GAE1B,IAAI,WAAW,IAAI;CAIrB,IAAI,CAAC,yBAAyB;EAE5B,MAAM,eAAe,SAAS,MAAM,GAAG;EACvC,MAAM,eAAe,aAAa;EAGlC,IAAI,SAAS,SAAS,YAAiB,GAAG;GAExC,aAAa,OAAO,GAAG,CAAC;GAIxB,IAAI,WADgB,aAAa,KAAK,GAAG,KAAK;EAEhD;CACF;CAGA,IAAI,CAAC,0BAA0B;EAC7B,MAAM,eAAe,IAAI,gBAAgB,IAAI,MAAM;EACnD,IAAI,aAAa,IAAI,QAAQ,GAAG;GAC9B,aAAa,OAAO,QAAQ;GAC5B,IAAI,SAAS,aAAa,SAAS;EACrC;CACF;CAEA,IAAI,eACF,OAAO,IAAI,SAAS;CAGtB,OAAO,IAAI,SAAS,CAAC,CAAC,QAAQ,gBAAgB,EAAE;AAClD"}
|
|
@@ -7,6 +7,7 @@ let _intlayer_config_built = require("@intlayer/config/built");
|
|
|
7
7
|
* or falls back to the default locale if no match is found.
|
|
8
8
|
*/
|
|
9
9
|
const localeResolver = (selectedLocale, locales = _intlayer_config_built.internationalization?.locales, defaultLocale = _intlayer_config_built.internationalization?.defaultLocale) => {
|
|
10
|
+
if (locales?.includes(selectedLocale)) return selectedLocale;
|
|
10
11
|
const requestedLocales = [selectedLocale].flat();
|
|
11
12
|
const normalize = (locale) => locale.trim().toLowerCase();
|
|
12
13
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localeResolver.cjs","names":["internationalization"],"sources":["../../../src/localization/localeResolver.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\n\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 */\nexport const localeResolver = (\n selectedLocale: LocalesValues | LocalesValues[],\n locales: LocalesValues[] = internationalization?.locales,\n defaultLocale: LocalesValues = internationalization?.defaultLocale\n): DeclaredLocales => {\n // Ensure we can handle both a single locale or an array of locales uniformly\n const requestedLocales = [selectedLocale].flat();\n\n // Simple helper to normalize locale strings (e.g. \"en-US\" => \"en-us\")\n const normalize = (locale: string): string => locale.trim().toLowerCase();\n\n try {\n // Check each requested locale in order\n for (const requested of requestedLocales) {\n const normalizedRequested = normalize(requested);\n\n // Attempt exact match\n const exactMatch = locales.find(\n (locale) => normalize(locale) === normalizedRequested\n );\n if (exactMatch) {\n return exactMatch as DeclaredLocales;\n }\n\n // Attempt partial match on language subtag\n // e.g. if requested is \"en-US\" and not found,\n // see if \"en\" is available among locales\n const [requestedLang] = normalizedRequested.split('-');\n const partialMatch = locales.find(\n (locale) => normalize(locale).split('-')[0] === requestedLang\n );\n if (partialMatch) {\n return partialMatch as DeclaredLocales;\n }\n }\n } catch {\n // If anything unexpected happened, fall back to default\n }\n\n // If no match was found, return the default\n return defaultLocale as DeclaredLocales;\n};\n"],"mappings":";;;;;;;;AAUA,MAAa,kBACX,gBACA,UAA2BA,6CAAsB,SACjD,gBAA+BA,6CAAsB,kBACjC;CAEpB,MAAM,mBAAmB,CAAC,cAAc,CAAC,CAAC,KAAK;CAG/C,MAAM,aAAa,WAA2B,OAAO,KAAK,CAAC,CAAC,YAAY;CAExE,IAAI;EAEF,KAAK,MAAM,aAAa,kBAAkB;GACxC,MAAM,sBAAsB,UAAU,SAAS;GAG/C,MAAM,aAAa,QAAQ,MACxB,WAAW,UAAU,MAAM,MAAM,mBACpC;GACA,IAAI,YACF,OAAO;GAMT,MAAM,CAAC,iBAAiB,oBAAoB,MAAM,GAAG;GACrD,MAAM,eAAe,QAAQ,MAC1B,WAAW,UAAU,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,aAClD;GACA,IAAI,cACF,OAAO;EAEX;CACF,QAAQ,CAER;CAGA,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"localeResolver.cjs","names":["internationalization"],"sources":["../../../src/localization/localeResolver.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\n\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 */\nexport const localeResolver = (\n selectedLocale: LocalesValues | LocalesValues[],\n locales: LocalesValues[] = internationalization?.locales,\n defaultLocale: LocalesValues = internationalization?.defaultLocale\n): DeclaredLocales => {\n // Fast path: an already-declared locale needs no normalization\n if (locales?.includes(selectedLocale as LocalesValues)) {\n return selectedLocale as DeclaredLocales;\n }\n\n // Ensure we can handle both a single locale or an array of locales uniformly\n const requestedLocales = [selectedLocale].flat();\n\n // Simple helper to normalize locale strings (e.g. \"en-US\" => \"en-us\")\n const normalize = (locale: string): string => locale.trim().toLowerCase();\n\n try {\n // Check each requested locale in order\n for (const requested of requestedLocales) {\n const normalizedRequested = normalize(requested);\n\n // Attempt exact match\n const exactMatch = locales.find(\n (locale) => normalize(locale) === normalizedRequested\n );\n if (exactMatch) {\n return exactMatch as DeclaredLocales;\n }\n\n // Attempt partial match on language subtag\n // e.g. if requested is \"en-US\" and not found,\n // see if \"en\" is available among locales\n const [requestedLang] = normalizedRequested.split('-');\n const partialMatch = locales.find(\n (locale) => normalize(locale).split('-')[0] === requestedLang\n );\n if (partialMatch) {\n return partialMatch as DeclaredLocales;\n }\n }\n } catch {\n // If anything unexpected happened, fall back to default\n }\n\n // If no match was found, return the default\n return defaultLocale as DeclaredLocales;\n};\n"],"mappings":";;;;;;;;AAUA,MAAa,kBACX,gBACA,UAA2BA,6CAAsB,SACjD,gBAA+BA,6CAAsB,kBACjC;CAEpB,IAAI,SAAS,SAAS,cAA+B,GACnD,OAAO;CAIT,MAAM,mBAAmB,CAAC,cAAc,CAAC,CAAC,KAAK;CAG/C,MAAM,aAAa,WAA2B,OAAO,KAAK,CAAC,CAAC,YAAY;CAExE,IAAI;EAEF,KAAK,MAAM,aAAa,kBAAkB;GACxC,MAAM,sBAAsB,UAAU,SAAS;GAG/C,MAAM,aAAa,QAAQ,MACxB,WAAW,UAAU,MAAM,MAAM,mBACpC;GACA,IAAI,YACF,OAAO;GAMT,MAAM,CAAC,iBAAiB,oBAAoB,MAAM,GAAG;GACrD,MAAM,eAAe,QAAQ,MAC1B,WAAW,UAAU,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,aAClD;GACA,IAAI,cACF,OAAO;EAEX;CACF,QAAQ,CAER;CAGA,OAAO;AACT"}
|
|
@@ -107,7 +107,8 @@ const createElementFactory = (ctx, options) => {
|
|
|
107
107
|
};
|
|
108
108
|
const createDocumentScope = () => ({
|
|
109
109
|
footnotes: [],
|
|
110
|
-
references: {}
|
|
110
|
+
references: {},
|
|
111
|
+
slugCounts: /* @__PURE__ */ new Map()
|
|
111
112
|
});
|
|
112
113
|
/**
|
|
113
114
|
* Small enough to scan linearly, large enough that an app mixing a few option
|
|
@@ -522,9 +523,17 @@ const createRules = (createElement, ctx, options, scope, attrStringToMap, contai
|
|
|
522
523
|
_order: require_markdown_constants.Priority.HIGH,
|
|
523
524
|
_parse(capture, parse, state) {
|
|
524
525
|
const text = capture[2] ?? "";
|
|
526
|
+
const baseSlug = slug(text) || "section";
|
|
527
|
+
const counts = scope.current.slugCounts;
|
|
528
|
+
let id = baseSlug;
|
|
529
|
+
if (counts) {
|
|
530
|
+
const count = counts.get(baseSlug) ?? 0;
|
|
531
|
+
counts.set(baseSlug, count + 1);
|
|
532
|
+
if (count > 0) id = `${baseSlug}-${count}`;
|
|
533
|
+
}
|
|
525
534
|
return {
|
|
526
535
|
children: require_markdown_utils.parseInline(parse, text, state),
|
|
527
|
-
id
|
|
536
|
+
id,
|
|
528
537
|
level: capture[1]?.length ?? 1
|
|
529
538
|
};
|
|
530
539
|
},
|
|
@@ -981,7 +990,7 @@ const createDocumentRules = (createElement, ctx, options, scope) => {
|
|
|
981
990
|
if (mappedKey === "ref") return map;
|
|
982
991
|
map[mappedKey] = require_markdown_utils.attributeValueToNodePropValue(tag, key, value, ctx.sanitizer ?? require_markdown_utils.sanitizer);
|
|
983
992
|
if (typeof map[mappedKey] === "string" && require_markdown_elementScanner.startsWithElement(map[mappedKey])) map[mappedKey] = parseMarkdown(map[mappedKey].trim(), ctx, options).ast;
|
|
984
|
-
} else if (raw !== "style") map[require_markdown_constants.ATTRIBUTE_TO_NODE_PROP_MAP[raw] ?? raw] = true;
|
|
993
|
+
} else if (raw !== "style" && require_markdown_constants.ATTRIBUTE_NAME_START_R.test(raw)) map[require_markdown_constants.ATTRIBUTE_TO_NODE_PROP_MAP[raw] ?? raw] = true;
|
|
985
994
|
return map;
|
|
986
995
|
}, {});
|
|
987
996
|
};
|