@intlayer/core 8.6.3 → 8.6.5
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/deepTransformPlugins/getFilterMissingTranslationsContent.cjs +1 -2
- package/dist/cjs/deepTransformPlugins/getFilterMissingTranslationsContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getFilterTranslationsOnlyContent.cjs +2 -3
- package/dist/cjs/deepTransformPlugins/getFilterTranslationsOnlyContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getMissingLocalesContent.cjs +2 -3
- package/dist/cjs/deepTransformPlugins/getMissingLocalesContent.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs +1 -2
- package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/orderDictionaries.cjs +2 -4
- package/dist/cjs/dictionaryManipulator/orderDictionaries.cjs.map +1 -1
- package/dist/cjs/formatters/compact.cjs +1 -2
- package/dist/cjs/formatters/compact.cjs.map +1 -1
- package/dist/cjs/formatters/currency.cjs +1 -2
- package/dist/cjs/formatters/currency.cjs.map +1 -1
- package/dist/cjs/formatters/date.cjs +1 -2
- package/dist/cjs/formatters/date.cjs.map +1 -1
- package/dist/cjs/formatters/list.cjs +1 -2
- package/dist/cjs/formatters/list.cjs.map +1 -1
- package/dist/cjs/formatters/number.cjs +1 -2
- package/dist/cjs/formatters/number.cjs.map +1 -1
- package/dist/cjs/formatters/percentage.cjs +1 -2
- package/dist/cjs/formatters/percentage.cjs.map +1 -1
- package/dist/cjs/formatters/relativeTime.cjs +1 -2
- package/dist/cjs/formatters/relativeTime.cjs.map +1 -1
- package/dist/cjs/formatters/units.cjs +1 -2
- package/dist/cjs/formatters/units.cjs.map +1 -1
- package/dist/cjs/interpreter/getContent/getContent.cjs +2 -3
- package/dist/cjs/interpreter/getContent/getContent.cjs.map +1 -1
- package/dist/cjs/interpreter/getIntlayer.cjs +1 -2
- package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
- package/dist/cjs/localization/getBrowserLocale.cjs +4 -8
- package/dist/cjs/localization/getBrowserLocale.cjs.map +1 -1
- package/dist/cjs/localization/getLocale.cjs +2 -3
- package/dist/cjs/localization/getLocale.cjs.map +1 -1
- package/dist/cjs/localization/getLocalizedUrl.cjs +1 -2
- package/dist/cjs/localization/getLocalizedUrl.cjs.map +1 -1
- package/dist/cjs/localization/getPathWithoutLocale.cjs +1 -2
- package/dist/cjs/localization/getPathWithoutLocale.cjs.map +1 -1
- package/dist/cjs/localization/getPrefix.cjs +7 -11
- package/dist/cjs/localization/getPrefix.cjs.map +1 -1
- package/dist/cjs/localization/localeMapper.cjs +3 -4
- package/dist/cjs/localization/localeMapper.cjs.map +1 -1
- package/dist/cjs/localization/localeResolver.cjs +1 -2
- package/dist/cjs/localization/localeResolver.cjs.map +1 -1
- package/dist/cjs/utils/intl.cjs +1 -2
- package/dist/cjs/utils/intl.cjs.map +1 -1
- package/dist/cjs/utils/localeStorage.cjs +27 -34
- package/dist/cjs/utils/localeStorage.cjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getFilterMissingTranslationsContent.mjs +2 -2
- package/dist/esm/deepTransformPlugins/getFilterMissingTranslationsContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getFilterTranslationsOnlyContent.mjs +3 -3
- package/dist/esm/deepTransformPlugins/getFilterTranslationsOnlyContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getMissingLocalesContent.mjs +3 -3
- package/dist/esm/deepTransformPlugins/getMissingLocalesContent.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs +2 -2
- package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/orderDictionaries.mjs +2 -3
- package/dist/esm/dictionaryManipulator/orderDictionaries.mjs.map +1 -1
- package/dist/esm/formatters/compact.mjs +2 -2
- package/dist/esm/formatters/compact.mjs.map +1 -1
- package/dist/esm/formatters/currency.mjs +2 -2
- package/dist/esm/formatters/currency.mjs.map +1 -1
- package/dist/esm/formatters/date.mjs +2 -2
- package/dist/esm/formatters/date.mjs.map +1 -1
- package/dist/esm/formatters/list.mjs +2 -2
- package/dist/esm/formatters/list.mjs.map +1 -1
- package/dist/esm/formatters/number.mjs +2 -2
- package/dist/esm/formatters/number.mjs.map +1 -1
- package/dist/esm/formatters/percentage.mjs +2 -2
- package/dist/esm/formatters/percentage.mjs.map +1 -1
- package/dist/esm/formatters/relativeTime.mjs +2 -2
- package/dist/esm/formatters/relativeTime.mjs.map +1 -1
- package/dist/esm/formatters/units.mjs +2 -2
- package/dist/esm/formatters/units.mjs.map +1 -1
- package/dist/esm/interpreter/getContent/getContent.mjs +3 -3
- package/dist/esm/interpreter/getContent/getContent.mjs.map +1 -1
- package/dist/esm/interpreter/getIntlayer.mjs +2 -2
- package/dist/esm/interpreter/getIntlayer.mjs.map +1 -1
- package/dist/esm/localization/getBrowserLocale.mjs +1 -4
- package/dist/esm/localization/getBrowserLocale.mjs.map +1 -1
- package/dist/esm/localization/getLocale.mjs +3 -3
- package/dist/esm/localization/getLocale.mjs.map +1 -1
- package/dist/esm/localization/getLocalizedUrl.mjs +2 -2
- package/dist/esm/localization/getLocalizedUrl.mjs.map +1 -1
- package/dist/esm/localization/getPathWithoutLocale.mjs +2 -2
- package/dist/esm/localization/getPathWithoutLocale.mjs.map +1 -1
- package/dist/esm/localization/getPrefix.mjs +8 -11
- package/dist/esm/localization/getPrefix.mjs.map +1 -1
- package/dist/esm/localization/localeMapper.mjs +4 -4
- package/dist/esm/localization/localeMapper.mjs.map +1 -1
- package/dist/esm/localization/localeResolver.mjs +2 -2
- package/dist/esm/localization/localeResolver.mjs.map +1 -1
- package/dist/esm/utils/intl.mjs +2 -2
- package/dist/esm/utils/intl.mjs.map +1 -1
- package/dist/esm/utils/localeStorage.mjs +19 -25
- package/dist/esm/utils/localeStorage.mjs.map +1 -1
- package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts.map +1 -1
- package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts.map +1 -1
- package/dist/types/deepTransformPlugins/getMissingLocalesContent.d.ts.map +1 -1
- package/dist/types/dictionaryManipulator/mergeDictionaries.d.ts.map +1 -1
- package/dist/types/dictionaryManipulator/orderDictionaries.d.ts +1 -2
- package/dist/types/dictionaryManipulator/orderDictionaries.d.ts.map +1 -1
- package/dist/types/localization/getBrowserLocale.d.ts.map +1 -1
- package/dist/types/localization/getLocalizedUrl.d.ts.map +1 -1
- package/dist/types/localization/getPathWithoutLocale.d.ts.map +1 -1
- package/dist/types/localization/getPrefix.d.ts.map +1 -1
- package/dist/types/localization/localeResolver.d.ts.map +1 -1
- package/dist/types/utils/intl.d.ts.map +1 -1
- package/dist/types/utils/localeStorage.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { editor } from "@intlayer/config/built";
|
|
2
2
|
|
|
3
3
|
//#region src/dictionaryManipulator/orderDictionaries.ts
|
|
4
4
|
/**
|
|
@@ -8,8 +8,7 @@ import configuration from "@intlayer/config/built";
|
|
|
8
8
|
* @param priorityStrategy - The priority strategy ('local_first' or 'distant_first')
|
|
9
9
|
* @returns Ordered array of dictionaries
|
|
10
10
|
*/
|
|
11
|
-
const orderDictionaries = (dictionaries
|
|
12
|
-
const { editor } = configuration$1;
|
|
11
|
+
const orderDictionaries = (dictionaries) => {
|
|
13
12
|
const { dictionaryPriorityStrategy } = editor;
|
|
14
13
|
if (dictionaries.length <= 1) return dictionaries;
|
|
15
14
|
const withIndex = dictionaries.map((dictionary, index) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderDictionaries.mjs","names":[
|
|
1
|
+
{"version":3,"file":"orderDictionaries.mjs","names":[],"sources":["../../../src/dictionaryManipulator/orderDictionaries.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\n/**\n * Orders dictionaries based on the dictionary priority strategy.\n *\n * @param dictionaries - Array of dictionaries to order\n * @param priorityStrategy - The priority strategy ('local_first' or 'distant_first')\n * @returns Ordered array of dictionaries\n */\nexport const orderDictionaries = (dictionaries: Dictionary[]): Dictionary[] => {\n const { dictionaryPriorityStrategy } = editor;\n\n if (dictionaries.length <= 1) {\n return dictionaries;\n }\n\n // Stabilize original indices to preserve relative order for complete ties\n const withIndex = dictionaries.map((dictionary, index) => ({\n dictionary,\n index,\n }));\n\n const getPriority = (dictionary: Dictionary): number => {\n const p = dictionary.priority ?? 0;\n\n return Number.isFinite(p) ? p : 0;\n };\n\n const getLocationWeight = (d: Dictionary): number => {\n const location = d.location;\n\n // undefined location should always be last\n if (location === undefined) {\n return 2;\n }\n\n if (dictionaryPriorityStrategy === 'distant_first') {\n // distant should come first\n return location === 'remote' ? 0 : 1;\n }\n // default: local_first\n return location === 'local' ? 0 : 1;\n };\n\n withIndex.sort((a, b) => {\n // 1) Non-autoFilled before autoFilled (autoFilled have lower precedence)\n const aAuto = a.dictionary.filled ? 1 : 0;\n const bAuto = b.dictionary.filled ? 1 : 0;\n if (aAuto !== bAuto) return aAuto - bAuto; // 0 before 1\n\n // 2) Higher priority first (larger number wins)\n const aP = getPriority(a.dictionary);\n const bP = getPriority(b.dictionary);\n if (aP !== bP) return bP - aP; // descending\n\n // 3) Location according to strategy\n const aLocation = getLocationWeight(a.dictionary);\n const bLocation = getLocationWeight(b.dictionary);\n if (aLocation !== bLocation) return aLocation - bLocation;\n\n // 4) Stable fallback by original index\n return a.index - b.index;\n });\n\n return withIndex.map(({ dictionary }) => dictionary);\n};\n"],"mappings":";;;;;;;;;;AAUA,MAAa,qBAAqB,iBAA6C;CAC7E,MAAM,EAAE,+BAA+B;AAEvC,KAAI,aAAa,UAAU,EACzB,QAAO;CAIT,MAAM,YAAY,aAAa,KAAK,YAAY,WAAW;EACzD;EACA;EACD,EAAE;CAEH,MAAM,eAAe,eAAmC;EACtD,MAAM,IAAI,WAAW,YAAY;AAEjC,SAAO,OAAO,SAAS,EAAE,GAAG,IAAI;;CAGlC,MAAM,qBAAqB,MAA0B;EACnD,MAAM,WAAW,EAAE;AAGnB,MAAI,aAAa,OACf,QAAO;AAGT,MAAI,+BAA+B,gBAEjC,QAAO,aAAa,WAAW,IAAI;AAGrC,SAAO,aAAa,UAAU,IAAI;;AAGpC,WAAU,MAAM,GAAG,MAAM;EAEvB,MAAM,QAAQ,EAAE,WAAW,SAAS,IAAI;EACxC,MAAM,QAAQ,EAAE,WAAW,SAAS,IAAI;AACxC,MAAI,UAAU,MAAO,QAAO,QAAQ;EAGpC,MAAM,KAAK,YAAY,EAAE,WAAW;EACpC,MAAM,KAAK,YAAY,EAAE,WAAW;AACpC,MAAI,OAAO,GAAI,QAAO,KAAK;EAG3B,MAAM,YAAY,kBAAkB,EAAE,WAAW;EACjD,MAAM,YAAY,kBAAkB,EAAE,WAAW;AACjD,MAAI,cAAc,UAAW,QAAO,YAAY;AAGhD,SAAO,EAAE,QAAQ,EAAE;GACnB;AAEF,QAAO,UAAU,KAAK,EAAE,iBAAiB,WAAW"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCachedIntl } from "../utils/intl.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/formatters/compact.ts
|
|
5
5
|
/**
|
|
@@ -13,7 +13,7 @@ import configuration from "@intlayer/config/built";
|
|
|
13
13
|
* compact("1000000", { locale: Locales.FRENCH, compactDisplay: "long" });
|
|
14
14
|
* // "1 million"
|
|
15
15
|
*/
|
|
16
|
-
const compact = (value, options) => getCachedIntl(Intl.NumberFormat, options?.locale ??
|
|
16
|
+
const compact = (value, options) => getCachedIntl(Intl.NumberFormat, options?.locale ?? internationalization?.defaultLocale, {
|
|
17
17
|
...options,
|
|
18
18
|
notation: "compact"
|
|
19
19
|
}).format(Number(value));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compact.mjs","names":[],"sources":["../../../src/formatters/compact.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"compact.mjs","names":[],"sources":["../../../src/formatters/compact.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\n/**\n * Formats a numeric value using compact notation (e.g., 1K, 1M, 1B)\n * based on locale and formatting options.\n *\n * @example\n * compact(1200); // \"1.2K\"\n *\n * @example\n * compact(\"1000000\", { locale: Locales.FRENCH, compactDisplay: \"long\" });\n * // \"1 million\"\n */\nexport const compact = (\n value: string | number,\n options?: Intl.NumberFormatOptions & { locale?: LocalesValues }\n): string =>\n getCachedIntl(\n Intl.NumberFormat,\n options?.locale ?? internationalization?.defaultLocale,\n\n {\n ...options,\n notation: 'compact',\n }\n ).format(Number(value));\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,WACX,OACA,YAEA,cACE,KAAK,cACL,SAAS,UAAU,sBAAsB,eAEzC;CACE,GAAG;CACH,UAAU;CACX,CACF,CAAC,OAAO,OAAO,MAAM,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCachedIntl } from "../utils/intl.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/formatters/currency.ts
|
|
5
5
|
/**
|
|
@@ -13,7 +13,7 @@ import configuration from "@intlayer/config/built";
|
|
|
13
13
|
* currency("5000", { locale: Locales.FRENCH, currency: "CAD", currencyDisplay: "code" });
|
|
14
14
|
* // "5 000,00 CAD"
|
|
15
15
|
*/
|
|
16
|
-
const currency = (value, options) => getCachedIntl(Intl.NumberFormat, options?.locale ??
|
|
16
|
+
const currency = (value, options) => getCachedIntl(Intl.NumberFormat, options?.locale ?? internationalization?.defaultLocale, {
|
|
17
17
|
style: "currency",
|
|
18
18
|
currency: options?.currency ?? "USD",
|
|
19
19
|
currencyDisplay: options?.currencyDisplay ?? "symbol",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"currency.mjs","names":[],"sources":["../../../src/formatters/currency.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"currency.mjs","names":[],"sources":["../../../src/formatters/currency.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\n/**\n * Formats a numeric or string value into a localized currency string using the Intl API.\n *\n * @example\n * currency(1234.5, { currency: 'EUR' });\n * // \"€1,234.50\"\n *\n * @example\n * currency(\"5000\", { locale: Locales.FRENCH, currency: \"CAD\", currencyDisplay: \"code\" });\n * // \"5 000,00 CAD\"\n */\nexport const currency = (\n value: string | number,\n options?: Intl.NumberFormatOptions & { locale?: LocalesValues }\n): string =>\n getCachedIntl(\n Intl.NumberFormat,\n options?.locale ?? internationalization?.defaultLocale,\n\n {\n style: 'currency',\n currency: options?.currency ?? 'USD',\n currencyDisplay: options?.currencyDisplay ?? 'symbol',\n minimumFractionDigits: options?.minimumFractionDigits ?? 2,\n maximumFractionDigits: options?.maximumFractionDigits ?? 2,\n ...options,\n }\n ).format(Number(value));\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,YACX,OACA,YAEA,cACE,KAAK,cACL,SAAS,UAAU,sBAAsB,eAEzC;CACE,OAAO;CACP,UAAU,SAAS,YAAY;CAC/B,iBAAiB,SAAS,mBAAmB;CAC7C,uBAAuB,SAAS,yBAAyB;CACzD,uBAAuB,SAAS,yBAAyB;CACzD,GAAG;CACJ,CACF,CAAC,OAAO,OAAO,MAAM,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCachedIntl } from "../utils/intl.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/formatters/date.ts
|
|
5
5
|
const presets = {
|
|
@@ -50,7 +50,7 @@ const presets = {
|
|
|
50
50
|
const date = (date, options) => {
|
|
51
51
|
const dateTime = new Date(date);
|
|
52
52
|
const resolvedOptions = typeof options === "string" ? presets[options] ?? {} : options;
|
|
53
|
-
const locale = (typeof options === "object" ? options?.locale : void 0) ??
|
|
53
|
+
const locale = (typeof options === "object" ? options?.locale : void 0) ?? internationalization?.defaultLocale;
|
|
54
54
|
return getCachedIntl(Intl.DateTimeFormat, locale, resolvedOptions).format(dateTime);
|
|
55
55
|
};
|
|
56
56
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date.mjs","names":[],"sources":["../../../src/formatters/date.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"date.mjs","names":[],"sources":["../../../src/formatters/date.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\nexport type DateTimePreset =\n | 'short'\n | 'long'\n | 'dateOnly'\n | 'timeOnly'\n | 'full';\n\nexport const presets: Record<DateTimePreset, Intl.DateTimeFormatOptions> = {\n short: {\n year: '2-digit',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n },\n long: {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n },\n full: {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n hour12: false,\n },\n dateOnly: {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n },\n timeOnly: {\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n },\n};\n\n/**\n * Formats a date/time value into a localized string using Intl.DateTimeFormat.\n *\n * @example\n * date(new Date('2025-08-02T14:30:00Z'), { year: '2-digit', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });\n * // \"08/02/25, 14:30\"\n *\n * @example\n * date(\"2025-08-02T14:30:00Z\", { locale: Locales.FRENCH, month: \"long\", day: \"numeric\" });\n * // \"2 août\"\n */\nexport const date = (\n date: Date | string | number,\n options?:\n | (Intl.DateTimeFormatOptions & { locale?: LocalesValues })\n | DateTimePreset\n): string => {\n const dateTime = new Date(date);\n\n const resolvedOptions =\n typeof options === 'string' ? (presets[options] ?? {}) : options;\n\n const locale =\n (typeof options === 'object' ? options?.locale : undefined) ??\n internationalization?.defaultLocale;\n\n const formatter = getCachedIntl(Intl.DateTimeFormat, locale, resolvedOptions);\n\n return formatter.format(dateTime);\n};\n"],"mappings":";;;;AAWA,MAAa,UAA8D;CACzE,OAAO;EACL,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT;CACD,MAAM;EACJ,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT;CACD,MAAM;EACJ,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACR,QAAQ;EACT;CACD,UAAU;EACR,MAAM;EACN,OAAO;EACP,KAAK;EACN;CACD,UAAU;EACR,MAAM;EACN,QAAQ;EACR,QAAQ;EACT;CACF;;;;;;;;;;;;AAaD,MAAa,QACX,MACA,YAGW;CACX,MAAM,WAAW,IAAI,KAAK,KAAK;CAE/B,MAAM,kBACJ,OAAO,YAAY,WAAY,QAAQ,YAAY,EAAE,GAAI;CAE3D,MAAM,UACH,OAAO,YAAY,WAAW,SAAS,SAAS,WACjD,sBAAsB;AAIxB,QAFkB,cAAc,KAAK,gBAAgB,QAAQ,gBAAgB,CAE5D,OAAO,SAAS"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCachedIntl } from "../utils/intl.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/formatters/list.ts
|
|
5
5
|
/**
|
|
@@ -17,7 +17,7 @@ import configuration from "@intlayer/config/built";
|
|
|
17
17
|
* list([1, 2, 3], { type: 'unit' });
|
|
18
18
|
* // "1, 2, 3"
|
|
19
19
|
*/
|
|
20
|
-
const list = (values, options) => getCachedIntl(Intl.ListFormat, options?.locale ??
|
|
20
|
+
const list = (values, options) => getCachedIntl(Intl.ListFormat, options?.locale ?? internationalization?.defaultLocale, {
|
|
21
21
|
type: options?.type ?? "conjunction",
|
|
22
22
|
style: options?.style ?? "long",
|
|
23
23
|
...options
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.mjs","names":[],"sources":["../../../src/formatters/list.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"list.mjs","names":[],"sources":["../../../src/formatters/list.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\n/** Locally defined subset of Intl.ListFormatOptions so consumers don't need ES2021.Intl in their lib. */\ntype ListFormatOptions = {\n localeMatcher?: 'lookup' | 'best fit';\n type?: 'conjunction' | 'disjunction' | 'unit';\n style?: 'long' | 'short' | 'narrow';\n};\n\n/**\n * Formats an array of values into a localized list string using the Intl API.\n *\n * @example\n * list(['apple', 'banana', 'orange']);\n * // \"apple, banana, and orange\"\n *\n * @example\n * list(['red', 'green', 'blue'], { locale: Locales.FRENCH, type: 'disjunction' });\n * // \"rouge, vert ou bleu\"\n *\n * @example\n * list([1, 2, 3], { type: 'unit' });\n * // \"1, 2, 3\"\n */\nexport const list = (\n values: (string | number)[],\n options?: ListFormatOptions & { locale?: LocalesValues }\n): string =>\n getCachedIntl(\n (Intl as any).ListFormat,\n options?.locale ?? internationalization?.defaultLocale,\n\n {\n type: options?.type ?? 'conjunction',\n style: options?.style ?? 'long',\n ...options,\n }\n ).format(values.map(String));\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA0BA,MAAa,QACX,QACA,YAEA,cACG,KAAa,YACd,SAAS,UAAU,sBAAsB,eAEzC;CACE,MAAM,SAAS,QAAQ;CACvB,OAAO,SAAS,SAAS;CACzB,GAAG;CACJ,CACF,CAAC,OAAO,OAAO,IAAI,OAAO,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCachedIntl } from "../utils/intl.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/formatters/number.ts
|
|
5
5
|
/**
|
|
@@ -11,7 +11,7 @@ import configuration from "@intlayer/config/built";
|
|
|
11
11
|
* @example
|
|
12
12
|
* number("1000000", { locale: Locales.FRENCH }); // "1 000 000"
|
|
13
13
|
*/
|
|
14
|
-
const number = (value, { locale, ...options } = {}) => getCachedIntl(Intl.NumberFormat, locale ??
|
|
14
|
+
const number = (value, { locale, ...options } = {}) => getCachedIntl(Intl.NumberFormat, locale ?? internationalization?.defaultLocale, options).format(Number(value));
|
|
15
15
|
|
|
16
16
|
//#endregion
|
|
17
17
|
export { number };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"number.mjs","names":[],"sources":["../../../src/formatters/number.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"number.mjs","names":[],"sources":["../../../src/formatters/number.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\n/**\n * Formats a numeric value using locale-aware formatting.\n *\n * @example\n * number(123456.789); // \"123,456.789\"\n *\n * @example\n * number(\"1000000\", { locale: Locales.FRENCH }); // \"1 000 000\"\n */\nexport const number = (\n value: string | number,\n {\n locale,\n ...options\n }: Intl.NumberFormatOptions & { locale?: LocalesValues } = {}\n): string =>\n getCachedIntl(\n Intl.NumberFormat,\n locale ?? internationalization?.defaultLocale,\n\n options\n ).format(Number(value));\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,UACX,OACA,EACE,QACA,GAAG,YACsD,EAAE,KAE7D,cACE,KAAK,cACL,UAAU,sBAAsB,eAEhC,QACD,CAAC,OAAO,OAAO,MAAM,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCachedIntl } from "../utils/intl.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/formatters/percentage.ts
|
|
5
5
|
/**
|
|
@@ -14,7 +14,7 @@ import configuration from "@intlayer/config/built";
|
|
|
14
14
|
const percentage = (value, { locale, ...options } = {}) => {
|
|
15
15
|
let numericValue = Number(value);
|
|
16
16
|
if (numericValue > 1) numericValue /= 100;
|
|
17
|
-
return getCachedIntl(Intl.NumberFormat, locale ??
|
|
17
|
+
return getCachedIntl(Intl.NumberFormat, locale ?? internationalization?.defaultLocale, {
|
|
18
18
|
style: "percent",
|
|
19
19
|
...options
|
|
20
20
|
}).format(Number(numericValue));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"percentage.mjs","names":[],"sources":["../../../src/formatters/percentage.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"percentage.mjs","names":[],"sources":["../../../src/formatters/percentage.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\n/**\n * Formats a number as a percentage string (e.g., 0.25 → \"25%\").\n *\n * @example\n * percentage(0.25); // \"25%\"\n *\n * @example\n * percentage(0.25, { minimumFractionDigits: 2 }); // \"25.00%\"\n */\nexport const percentage = (\n value: string | number,\n {\n locale,\n ...options\n }: Intl.NumberFormatOptions & { locale?: LocalesValues } = {}\n): string => {\n let numericValue = Number(value);\n\n // Normalize: if user passes 10, treat it as 10% instead of 1000%\n if (numericValue > 1) {\n numericValue /= 100;\n }\n\n const formatter = getCachedIntl(\n Intl.NumberFormat,\n locale ?? internationalization?.defaultLocale,\n\n {\n style: 'percent',\n ...options,\n }\n );\n\n return formatter.format(Number(numericValue));\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,cACX,OACA,EACE,QACA,GAAG,YACsD,EAAE,KAClD;CACX,IAAI,eAAe,OAAO,MAAM;AAGhC,KAAI,eAAe,EACjB,iBAAgB;AAalB,QAVkB,cAChB,KAAK,cACL,UAAU,sBAAsB,eAEhC;EACE,OAAO;EACP,GAAG;EACJ,CACF,CAEgB,OAAO,OAAO,aAAa,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCachedIntl } from "../utils/intl.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/formatters/relativeTime.ts
|
|
5
5
|
/**
|
|
@@ -33,7 +33,7 @@ const relativeTime = (from, to = /* @__PURE__ */ new Date(), options) => {
|
|
|
33
33
|
const toDate = new Date(to);
|
|
34
34
|
const unit = options?.unit ?? "second";
|
|
35
35
|
const value = diffInUnit(fromDate, toDate, unit);
|
|
36
|
-
return getCachedIntl(Intl.RelativeTimeFormat, options?.locale ??
|
|
36
|
+
return getCachedIntl(Intl.RelativeTimeFormat, options?.locale ?? internationalization?.defaultLocale, options).format(Math.round(value), unit);
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relativeTime.mjs","names":[],"sources":["../../../src/formatters/relativeTime.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"relativeTime.mjs","names":[],"sources":["../../../src/formatters/relativeTime.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\ntype RelativeTimeUnit = Intl.RelativeTimeFormatUnit;\n\n/**\n * Calculate the difference between 2 dates in the given unit.\n */\nconst diffInUnit = (from: Date, to: Date, unit: RelativeTimeUnit): number => {\n const msDiff = to.getTime() - from.getTime();\n const sec = msDiff / 1000;\n\n switch (unit) {\n case 'second':\n return sec;\n case 'minute':\n return sec / 60;\n case 'hour':\n return sec / 3600;\n case 'day':\n return sec / 86400;\n case 'month':\n return sec / (30 * 86400); // approx\n case 'quarter':\n return sec / (3 * 30 * 86400); // 3 months approx\n case 'year':\n return sec / (365 * 86400); // approx\n default:\n return sec;\n }\n};\n\n/**\n * Formats the difference between two dates as a localized relative time string.\n *\n * @example\n * relativeTime(new Date(Date.now() - 30000)); // \"30 seconds ago\"\n *\n * @example\n * relativeTime(\"2025-01-01\", new Date(), { locale: Locales.FRENCH, unit: \"day\" });\n * // \"il y a 443 jours\"\n */\nexport const relativeTime = (\n from: Date | string | number,\n to: Date | string | number = new Date(),\n options?: Intl.RelativeTimeFormatOptions & {\n locale?: LocalesValues;\n unit?: RelativeTimeUnit;\n }\n): string => {\n const fromDate = new Date(from);\n const toDate = new Date(to);\n const unit = options?.unit ?? 'second';\n\n const value = diffInUnit(fromDate, toDate, unit);\n\n return getCachedIntl(\n Intl.RelativeTimeFormat,\n options?.locale ?? internationalization?.defaultLocale,\n\n options\n ).format(Math.round(value), unit);\n};\n"],"mappings":";;;;;;;AASA,MAAM,cAAc,MAAY,IAAU,SAAmC;CAE3E,MAAM,OADS,GAAG,SAAS,GAAG,KAAK,SAAS,IACvB;AAErB,SAAQ,MAAR;EACE,KAAK,SACH,QAAO;EACT,KAAK,SACH,QAAO,MAAM;EACf,KAAK,OACH,QAAO,MAAM;EACf,KAAK,MACH,QAAO,MAAM;EACf,KAAK,QACH,QAAO,OAAO,KAAK;EACrB,KAAK,UACH,QAAO,OAAO,KAAS;EACzB,KAAK,OACH,QAAO,OAAO,MAAM;EACtB,QACE,QAAO;;;;;;;;;;;;;AAcb,MAAa,gBACX,MACA,qBAA6B,IAAI,MAAM,EACvC,YAIW;CACX,MAAM,WAAW,IAAI,KAAK,KAAK;CAC/B,MAAM,SAAS,IAAI,KAAK,GAAG;CAC3B,MAAM,OAAO,SAAS,QAAQ;CAE9B,MAAM,QAAQ,WAAW,UAAU,QAAQ,KAAK;AAEhD,QAAO,cACL,KAAK,oBACL,SAAS,UAAU,sBAAsB,eAEzC,QACD,CAAC,OAAO,KAAK,MAAM,MAAM,EAAE,KAAK"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCachedIntl } from "../utils/intl.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/formatters/units.ts
|
|
5
5
|
/**
|
|
@@ -9,7 +9,7 @@ import configuration from "@intlayer/config/built";
|
|
|
9
9
|
* units(5, { unit: "kilometer", unitDisplay: "long", locale: "en-GB" });
|
|
10
10
|
* // "5 kilometers"
|
|
11
11
|
*/
|
|
12
|
-
const units = (value, options) => getCachedIntl(Intl.NumberFormat, options?.locale ??
|
|
12
|
+
const units = (value, options) => getCachedIntl(Intl.NumberFormat, options?.locale ?? internationalization?.defaultLocale, {
|
|
13
13
|
style: "unit",
|
|
14
14
|
unit: options?.unit ?? "day",
|
|
15
15
|
unitDisplay: options?.unitDisplay ?? "short",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"units.mjs","names":[],"sources":["../../../src/formatters/units.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"units.mjs","names":[],"sources":["../../../src/formatters/units.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\n/**\n * Formats a numeric value as a localized unit string.\n *\n * @example\n * units(5, { unit: \"kilometer\", unitDisplay: \"long\", locale: \"en-GB\" });\n * // \"5 kilometers\"\n */\nexport const units = (\n value: number | string,\n options?: Intl.NumberFormatOptions & { locale?: LocalesValues }\n): string =>\n getCachedIntl(\n Intl.NumberFormat,\n options?.locale ?? internationalization?.defaultLocale,\n\n {\n style: 'unit',\n unit: options?.unit ?? 'day',\n unitDisplay: options?.unitDisplay ?? 'short',\n useGrouping: options?.useGrouping ?? false,\n }\n ).format(Number(value));\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,SACX,OACA,YAEA,cACE,KAAK,cACL,SAAS,UAAU,sBAAsB,eAEzC;CACE,OAAO;CACP,MAAM,SAAS,QAAQ;CACvB,aAAa,SAAS,eAAe;CACrC,aAAa,SAAS,eAAe;CACtC,CACF,CAAC,OAAO,OAAO,MAAM,CAAC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { deepTransformNode } from "./deepTransform.mjs";
|
|
2
2
|
import { conditionPlugin, enumerationPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, translationPlugin } from "./plugins.mjs";
|
|
3
|
-
import
|
|
3
|
+
import { internationalization } from "@intlayer/config/built";
|
|
4
4
|
|
|
5
5
|
//#region src/interpreter/getContent/getContent.ts
|
|
6
6
|
const getBasePlugins = (locale, fallback = true) => [
|
|
7
|
-
translationPlugin(locale ??
|
|
7
|
+
translationPlugin(locale ?? internationalization.defaultLocale, fallback ? internationalization.defaultLocale : void 0),
|
|
8
8
|
enumerationPlugin,
|
|
9
9
|
conditionPlugin,
|
|
10
10
|
insertionPlugin,
|
|
11
|
-
nestedPlugin(locale ??
|
|
11
|
+
nestedPlugin(locale ?? internationalization.defaultLocale),
|
|
12
12
|
filePlugin,
|
|
13
13
|
genderPlugin
|
|
14
14
|
].filter(Boolean);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getContent.mjs","names":[],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"getContent.mjs","names":[],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n translationPlugin,\n} from './plugins';\n\nexport const getBasePlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] =>\n [\n translationPlugin(\n locale ?? internationalization.defaultLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n conditionPlugin,\n insertionPlugin,\n nestedPlugin(locale ?? internationalization.defaultLocale),\n filePlugin,\n genderPlugin,\n ].filter(Boolean) as Plugins[];\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n T extends ContentNode,\n L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n plugins: Plugins[] = []\n) =>\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n"],"mappings":";;;;;AAqBA,MAAa,kBACX,QACA,WAAoB,SAEpB;CACE,kBACE,UAAU,qBAAqB,eAC/B,WAAW,qBAAqB,gBAAgB,OACjD;CACD;CACA;CACA;CACA,aAAa,UAAU,qBAAqB,cAAc;CAC1D;CACA;CACD,CAAC,OAAO,QAAQ;;;;;;;AAQnB,MAAa,cAIX,MACA,WACA,UAAqB,EAAE,KAEvB,kBAAkB,MAAM;CACtB,GAAG;CACH;CACD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getDictionary } from "./getDictionary.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { log } from "@intlayer/config/built";
|
|
3
3
|
import { colorizeKey, getAppLogger } from "@intlayer/config/logger";
|
|
4
4
|
import { getDictionaries } from "@intlayer/dictionaries-entry";
|
|
5
5
|
|
|
@@ -23,7 +23,7 @@ const createSafeFallback = (path = "") => {
|
|
|
23
23
|
const getIntlayer = (key, locale, plugins) => {
|
|
24
24
|
const dictionary = getDictionaries()[key];
|
|
25
25
|
if (!dictionary) {
|
|
26
|
-
getAppLogger(
|
|
26
|
+
getAppLogger({ log })(`Dictionary ${colorizeKey(key)} was not found. Using fallback proxy.`, {
|
|
27
27
|
level: "warn",
|
|
28
28
|
isVerbose: true
|
|
29
29
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIntlayer.mjs","names":[],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"getIntlayer.mjs","names":[],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryContent,\n DictionaryRegistryElement,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy(\n // Target is a function so it can be called if the dictionary expects a function\n () => path,\n {\n get: (_target, prop) => {\n // Handle common object methods to prevent infinite recursion or weird behavior\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n // If the code tries to execute the missing key as a function: t.title()\n apply: () => {\n return path;\n },\n }\n );\n};\n\nexport const getIntlayer = <\n T extends DictionaryKeys,\n L extends LocalesValues = DeclaredLocales,\n>(\n key: T,\n locale?: L,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryContent<T>,\n IInterpreterPluginState,\n L\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T] as DictionaryRegistryElement<T>;\n\n if (!dictionary) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n `Dictionary ${colorizeKey(key as string)} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n isVerbose: true,\n }\n );\n\n if (process.env.NODE_ENV === 'development') {\n // Return the Safe Proxy\n // We initialize it with the dictionary key name so the UI shows \"my-dictionary.someKey\"\n return createSafeFallback(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n return getDictionary<DictionaryRegistryElement<T>, L>(\n dictionary,\n locale,\n plugins\n );\n};\n"],"mappings":";;;;;;;;;;AAqBA,MAAM,sBAAsB,OAAO,OAAY;AAC7C,QAAO,IAAI,YAEH,MACN;EACE,MAAM,SAAS,SAAS;AAEtB,OACE,SAAS,YACT,SAAS,OAAO,eAChB,SAAS,WAET,cAAa;AAEf,OAAI,SAAS,OACX;AAKF,UAAO,mBADU,OAAO,GAAG,KAAK,GAAG,OAAO,KAAK,KAAK,OAAO,KAAK,CAC7B;;EAGrC,aAAa;AACX,UAAO;;EAEV,CACF;;AAGH,MAAa,eAIX,KACA,QACA,YAKG;CAEH,MAAM,aADe,iBAAiB,CACN;AAEhC,KAAI,CAAC,YAAY;AAGf,EADe,aAAa,EAAE,KAAK,CAAC,CAElC,cAAc,YAAY,IAAc,CAAC,wCACzC;GACE,OAAO;GACP,WAAW;GACZ,CACF;AAKC,SAAO,mBAAmB,IAAc;;AAM5C,QAAO,cACL,YACA,QACA,QACD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getLocaleFromStorageClient } from "../utils/localeStorage.mjs";
|
|
2
2
|
import { localeDetector } from "./localeDetector.mjs";
|
|
3
|
-
import
|
|
3
|
+
import { internationalization } from "@intlayer/config/built";
|
|
4
4
|
import { ENGLISH } from "@intlayer/types/locales";
|
|
5
5
|
|
|
6
6
|
//#region src/localization/getBrowserLocale.tsx
|
|
@@ -76,7 +76,6 @@ const detectLanguage = (order, options) => {
|
|
|
76
76
|
};
|
|
77
77
|
const navigatorDetector = () => {
|
|
78
78
|
if (typeof navigator === "undefined") return;
|
|
79
|
-
const { internationalization } = configuration;
|
|
80
79
|
const languages = navigator.languages ?? [navigator.language];
|
|
81
80
|
const locale = localeDetector({ "accept-language": languages.join(",") }, internationalization.locales, internationalization.defaultLocale);
|
|
82
81
|
if (locale) detected[LanguageDetector.Navigator] = locale;
|
|
@@ -86,7 +85,6 @@ const detectLanguage = (order, options) => {
|
|
|
86
85
|
if (htmlTag && typeof htmlTag.getAttribute === "function") {
|
|
87
86
|
const lang = htmlTag.getAttribute("lang");
|
|
88
87
|
if (lang) {
|
|
89
|
-
const { internationalization } = configuration;
|
|
90
88
|
const locale = localeDetector({ "accept-language": lang }, internationalization.locales, internationalization.defaultLocale);
|
|
91
89
|
detected[LanguageDetector.HtmlTag] = locale;
|
|
92
90
|
}
|
|
@@ -104,7 +102,6 @@ const detectLanguage = (order, options) => {
|
|
|
104
102
|
return detected;
|
|
105
103
|
};
|
|
106
104
|
const getFirstAvailableLocale = (locales, order) => {
|
|
107
|
-
const { internationalization } = configuration;
|
|
108
105
|
for (const detector of order) {
|
|
109
106
|
const locale = locales[detector];
|
|
110
107
|
if (locale && internationalization.locales.includes(locale)) return locale;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getBrowserLocale.mjs","names":[],"sources":["../../../src/localization/getBrowserLocale.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"getBrowserLocale.mjs","names":[],"sources":["../../../src/localization/getBrowserLocale.tsx"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { ENGLISH } from '@intlayer/types/locales';\nimport {\n getLocaleFromStorageClient,\n type LocaleStorageClientOptions,\n} from '../utils/localeStorage';\nimport { localeDetector } from './localeDetector';\n\nexport enum LanguageDetector {\n Querystring = 'querystring',\n Storage = 'storage',\n Navigator = 'navigator',\n HtmlTag = 'htmlTag',\n}\n\nexport const localeStorageOptions: LocaleStorageClientOptions = {\n getCookie: (name: string) =>\n document.cookie\n .split(';')\n .find((c) => c.trim().startsWith(`${name}=`))\n ?.split('=')[1],\n getLocaleStorage: (name: string) => localStorage.getItem(name),\n getSessionStorage: (name: string) => sessionStorage.getItem(name),\n isCookieEnabled: true,\n setCookieStore: (name, value, attributes) =>\n cookieStore.set({\n name,\n value,\n path: attributes.path,\n domain: attributes.domain,\n expires: attributes.expires,\n sameSite: attributes.sameSite,\n }),\n setCookieString: (_name, cookie) => {\n // biome-ignore lint/suspicious/noDocumentCookie: set cookie fallback\n document.cookie = cookie;\n },\n setSessionStorage: (name, value) => sessionStorage.setItem(name, value),\n setLocaleStorage: (name, value) => localStorage.setItem(name, value),\n};\n\n// Default settings for the language detector\ntype LanguageDetectorOptions = {\n order?: LanguageDetector[];\n lookupQuerystring?: string;\n htmlTag?: HTMLElement | null;\n};\n\nconst getDefaultsOptions = (): LanguageDetectorOptions => {\n return {\n order: [\n LanguageDetector.Querystring,\n LanguageDetector.Storage,\n LanguageDetector.Navigator,\n LanguageDetector.HtmlTag,\n ],\n lookupQuerystring: 'locale',\n htmlTag: typeof document !== 'undefined' ? document.documentElement : null,\n };\n};\n\nconst detectLanguage = (\n order: string[],\n options: LanguageDetectorOptions\n): Record<LanguageDetector, Locale | undefined> => {\n const detected: Record<LanguageDetector, Locale | undefined> = {} as Record<\n LanguageDetector,\n Locale | undefined\n >;\n\n const queryStringDetector = () => {\n if (typeof window === 'undefined') return;\n const search = window.location.search || '';\n const params = new URLSearchParams(search);\n const value = params.get(options.lookupQuerystring ?? '');\n if (value) {\n detected[LanguageDetector.Querystring] = value as Locale;\n }\n };\n\n const storageDetector = () => {\n if (typeof window === 'undefined') return;\n\n const locale = getLocaleFromStorageClient({\n getCookie: (name: string) => {\n try {\n const cookies = document.cookie.split(';');\n const cookieName = `${name}=`;\n\n const cookie = cookies.find((cookie) =>\n cookie.trim().startsWith(cookieName)\n );\n\n if (cookie) {\n return cookie.split('=')[1].trim();\n }\n } catch {}\n return undefined;\n },\n getSessionStorage: (name: string) => {\n try {\n return window.sessionStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n getLocaleStorage: (name: string) => {\n try {\n return window.localStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n });\n\n if (locale) {\n detected[LanguageDetector.Storage] = locale;\n }\n };\n\n const navigatorDetector = () => {\n if (typeof navigator === 'undefined') return;\n\n const languages = navigator.languages ?? [navigator.language];\n\n // Use localeDetector to find the best matching locale\n const locale = localeDetector(\n { 'accept-language': languages.join(',') },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n if (locale) {\n detected[LanguageDetector.Navigator] = locale;\n }\n };\n\n const htmlTagDetector = () => {\n const htmlTag = options.htmlTag;\n if (htmlTag && typeof htmlTag.getAttribute === 'function') {\n const lang = htmlTag.getAttribute('lang');\n if (lang) {\n // Validate and resolve the locale\n\n const locale = localeDetector(\n { 'accept-language': lang },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n detected[LanguageDetector.HtmlTag] = locale;\n }\n }\n };\n\n // Map detector names to their corresponding functions\n const detectors: Record<string, () => void> = {\n [LanguageDetector.Querystring]: queryStringDetector,\n [LanguageDetector.Storage]: storageDetector,\n [LanguageDetector.Navigator]: navigatorDetector,\n [LanguageDetector.HtmlTag]: htmlTagDetector,\n };\n\n // Use the provided order to run each detector\n order.forEach((detectorName) => {\n detectors[detectorName]?.();\n });\n\n return detected;\n};\n\nconst getFirstAvailableLocale = (\n locales: Record<LanguageDetector, Locale | undefined>,\n order: LanguageDetector[]\n): Locale => {\n for (const detector of order) {\n const locale = locales[detector];\n\n if (locale && internationalization.locales.includes(locale)) {\n return locale;\n }\n }\n\n return internationalization?.defaultLocale ?? ENGLISH;\n};\n\n/**\n * Core language detector function for browser environments.\n *\n * Detects the user's preferred locale by checking multiple sources in order:\n * 1. Query string parameter\n * 2. Storage (cookies, localStorage, sessionStorage) - uses getLocaleFromStorage\n * 3. Navigator languages - uses localeDetector\n * 4. HTML lang attribute - uses localeDetector\n *\n * @param userOptions - Optional configuration for detection order and lookup keys\n * @returns The detected locale or the default locale\n *\n * @example\n * const locale = getBrowserLocale({ order: [LanguageDetector.Storage, LanguageDetector.Navigator] });\n */\nexport const getBrowserLocale = (\n userOptions: LanguageDetectorOptions | undefined = {}\n): Locale => {\n const options = { ...getDefaultsOptions(), ...userOptions };\n\n const locales = detectLanguage(options.order ?? [], options);\n\n return getFirstAvailableLocale(locales, options.order ?? []);\n};\n"],"mappings":";;;;;;AASA,IAAY,mBAAL;AACL;AACA;AACA;AACA;;KACD;AAED,MAAa,uBAAmD;CAC9D,YAAY,SACV,SAAS,OACN,MAAM,IAAI,CACV,MAAM,MAAM,EAAE,MAAM,CAAC,WAAW,GAAG,KAAK,GAAG,CAAC,EAC3C,MAAM,IAAI,CAAC;CACjB,mBAAmB,SAAiB,aAAa,QAAQ,KAAK;CAC9D,oBAAoB,SAAiB,eAAe,QAAQ,KAAK;CACjE,iBAAiB;CACjB,iBAAiB,MAAM,OAAO,eAC5B,YAAY,IAAI;EACd;EACA;EACA,MAAM,WAAW;EACjB,QAAQ,WAAW;EACnB,SAAS,WAAW;EACpB,UAAU,WAAW;EACtB,CAAC;CACJ,kBAAkB,OAAO,WAAW;AAElC,WAAS,SAAS;;CAEpB,oBAAoB,MAAM,UAAU,eAAe,QAAQ,MAAM,MAAM;CACvE,mBAAmB,MAAM,UAAU,aAAa,QAAQ,MAAM,MAAM;CACrE;AASD,MAAM,2BAAoD;AACxD,QAAO;EACL,OAAO;GACL,iBAAiB;GACjB,iBAAiB;GACjB,iBAAiB;GACjB,iBAAiB;GAClB;EACD,mBAAmB;EACnB,SAAS,OAAO,aAAa,cAAc,SAAS,kBAAkB;EACvE;;AAGH,MAAM,kBACJ,OACA,YACiD;CACjD,MAAM,WAAyD,EAAE;CAKjE,MAAM,4BAA4B;AAChC,MAAI,OAAO,WAAW,YAAa;EACnC,MAAM,SAAS,OAAO,SAAS,UAAU;EAEzC,MAAM,QADS,IAAI,gBAAgB,OAAO,CACrB,IAAI,QAAQ,qBAAqB,GAAG;AACzD,MAAI,MACF,UAAS,iBAAiB,eAAe;;CAI7C,MAAM,wBAAwB;AAC5B,MAAI,OAAO,WAAW,YAAa;EAEnC,MAAM,SAAS,2BAA2B;GACxC,YAAY,SAAiB;AAC3B,QAAI;KACF,MAAM,UAAU,SAAS,OAAO,MAAM,IAAI;KAC1C,MAAM,aAAa,GAAG,KAAK;KAE3B,MAAM,SAAS,QAAQ,MAAM,WAC3B,OAAO,MAAM,CAAC,WAAW,WAAW,CACrC;AAED,SAAI,OACF,QAAO,OAAO,MAAM,IAAI,CAAC,GAAG,MAAM;YAE9B;;GAGV,oBAAoB,SAAiB;AACnC,QAAI;AACF,YAAO,OAAO,eAAe,QAAQ,KAAK,IAAI;YACxC;;GAGV,mBAAmB,SAAiB;AAClC,QAAI;AACF,YAAO,OAAO,aAAa,QAAQ,KAAK,IAAI;YACtC;;GAGX,CAAC;AAEF,MAAI,OACF,UAAS,iBAAiB,WAAW;;CAIzC,MAAM,0BAA0B;AAC9B,MAAI,OAAO,cAAc,YAAa;EAEtC,MAAM,YAAY,UAAU,aAAa,CAAC,UAAU,SAAS;EAG7D,MAAM,SAAS,eACb,EAAE,mBAAmB,UAAU,KAAK,IAAI,EAAE,EAC1C,qBAAqB,SACrB,qBAAqB,cACtB;AAED,MAAI,OACF,UAAS,iBAAiB,aAAa;;CAI3C,MAAM,wBAAwB;EAC5B,MAAM,UAAU,QAAQ;AACxB,MAAI,WAAW,OAAO,QAAQ,iBAAiB,YAAY;GACzD,MAAM,OAAO,QAAQ,aAAa,OAAO;AACzC,OAAI,MAAM;IAGR,MAAM,SAAS,eACb,EAAE,mBAAmB,MAAM,EAC3B,qBAAqB,SACrB,qBAAqB,cACtB;AAED,aAAS,iBAAiB,WAAW;;;;CAM3C,MAAM,YAAwC;GAC3C,iBAAiB,cAAc;GAC/B,iBAAiB,UAAU;GAC3B,iBAAiB,YAAY;GAC7B,iBAAiB,UAAU;EAC7B;AAGD,OAAM,SAAS,iBAAiB;AAC9B,YAAU,iBAAiB;GAC3B;AAEF,QAAO;;AAGT,MAAM,2BACJ,SACA,UACW;AACX,MAAK,MAAM,YAAY,OAAO;EAC5B,MAAM,SAAS,QAAQ;AAEvB,MAAI,UAAU,qBAAqB,QAAQ,SAAS,OAAO,CACzD,QAAO;;AAIX,QAAO,sBAAsB,iBAAiB;;;;;;;;;;;;;;;;;AAkBhD,MAAa,oBACX,cAAmD,EAAE,KAC1C;CACX,MAAM,UAAU;EAAE,GAAG,oBAAoB;EAAE,GAAG;EAAa;AAI3D,QAAO,wBAFS,eAAe,QAAQ,SAAS,EAAE,EAAE,QAAQ,EAEpB,QAAQ,SAAS,EAAE,CAAC"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { getLocaleFromStorageServer } from "../utils/localeStorage.mjs";
|
|
2
2
|
import { localeResolver } from "./localeResolver.mjs";
|
|
3
3
|
import { getPreferredLanguages } from "./localeDetector.mjs";
|
|
4
|
-
import
|
|
4
|
+
import { internationalization } from "@intlayer/config/built";
|
|
5
5
|
import { DEFAULT_LOCALE, LOCALES } from "@intlayer/config/defaultValues";
|
|
6
6
|
|
|
7
7
|
//#region src/localization/getLocale.ts
|
|
8
8
|
const getLocale = async (ctx = {}) => {
|
|
9
|
-
const defaultLocale =
|
|
10
|
-
const availableLocales =
|
|
9
|
+
const defaultLocale = internationalization?.defaultLocale ?? DEFAULT_LOCALE;
|
|
10
|
+
const availableLocales = internationalization?.locales ?? LOCALES;
|
|
11
11
|
const storedLocale = getLocaleFromStorageServer({
|
|
12
12
|
getCookie: ctx.getCookie,
|
|
13
13
|
getHeader: ctx.getHeader
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocale.mjs","names":[],"sources":["../../../src/localization/getLocale.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"getLocale.mjs","names":[],"sources":["../../../src/localization/getLocale.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport { DEFAULT_LOCALE, LOCALES } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { getLocaleFromStorageServer } from '../utils/localeStorage';\nimport { getPreferredLanguages } from './localeDetector';\nimport { localeResolver } from './localeResolver';\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 = internationalization?.defaultLocale ?? DEFAULT_LOCALE;\n const availableLocales = internationalization?.locales ?? LOCALES;\n\n // Try locale from storage (cookie or header)\n const storedLocale = getLocaleFromStorageServer({\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":";;;;;;;AAYA,MAAa,YAAY,OAAO,MAAsB,EAAE,KAAsB;CAC5E,MAAM,gBAAgB,sBAAsB,iBAAiB;CAC7D,MAAM,mBAAmB,sBAAsB,WAAW;CAG1D,MAAM,eAAe,2BAA2B;EAC9C,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"}
|
|
@@ -2,7 +2,7 @@ import { checkIsURLAbsolute } from "../utils/checkIsURLAbsolute.mjs";
|
|
|
2
2
|
import { getPathWithoutLocale } from "./getPathWithoutLocale.mjs";
|
|
3
3
|
import { getPrefix, resolveRoutingConfig } from "./getPrefix.mjs";
|
|
4
4
|
import { getCanonicalPath, getLocalizedPath, getRewriteRules } from "./rewriteUtils.mjs";
|
|
5
|
-
import
|
|
5
|
+
import { internationalization } from "@intlayer/config/built";
|
|
6
6
|
|
|
7
7
|
//#region src/localization/getLocalizedUrl.ts
|
|
8
8
|
/**
|
|
@@ -49,7 +49,7 @@ const TREE_SHAKE_SEARCH_PARAMS = process.env["INTLAYER_ROUTING_MODE"] && process
|
|
|
49
49
|
* @param options.mode - URL routing mode for locale handling. Defaults to configured mode.
|
|
50
50
|
* @returns The localized URL for the current locale.
|
|
51
51
|
*/
|
|
52
|
-
const getLocalizedUrl = (url, currentLocale =
|
|
52
|
+
const getLocalizedUrl = (url, currentLocale = internationalization?.defaultLocale, options = {}) => {
|
|
53
53
|
const { defaultLocale, mode, locales, rewrite } = resolveRoutingConfig(options);
|
|
54
54
|
const urlWithoutLocale = getPathWithoutLocale(url, locales);
|
|
55
55
|
const rewriteRules = getRewriteRules(rewrite, "url");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocalizedUrl.mjs","names":[],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"getLocalizedUrl.mjs","names":[],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\n\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 'no-prefix'.\n */\nconst TREE_SHAKE_NO_PREFIX =\n process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'no-prefix';\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 { Locale } from '@intlayer/types/allLocales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport {\n getPrefix,\n type RoutingOptions,\n resolveRoutingConfig,\n} from './getPrefix';\nimport {\n getCanonicalPath,\n getLocalizedPath,\n getRewriteRules,\n} from './rewriteUtils';\n\nexport type { RoutingOptions };\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 = internationalization?.defaultLocale,\n\n options: RoutingOptions = {}\n): string => {\n const { defaultLocale, mode, locales, rewrite } =\n resolveRoutingConfig(options);\n\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n const rewriteRules = getRewriteRules(rewrite, 'url');\n\n if (!TREE_SHAKE_NO_PREFIX && mode === 'no-prefix') {\n return getLocalizedPath(\n getCanonicalPath(urlWithoutLocale, undefined, rewriteRules),\n currentLocale as Locale,\n rewriteRules\n ).path;\n }\n\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n const translatedPathname = getLocalizedPath(\n getCanonicalPath(parsedUrl.pathname, undefined, rewriteRules),\n currentLocale as Locale,\n rewriteRules\n ).path;\n\n const baseUrl = isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n\n if (!TREE_SHAKE_SEARCH_PARAMS && mode === 'search-params') {\n const searchParams = new URLSearchParams(parsedUrl.search);\n\n searchParams.set('locale', currentLocale.toString());\n\n const queryParams = searchParams.toString();\n const path = queryParams\n ? `${translatedPathname}?${queryParams}`\n : translatedPathname;\n\n return `${baseUrl}${path}${parsedUrl.hash}`;\n }\n\n const { prefix } = getPrefix(currentLocale, { defaultLocale, mode, locales });\n\n let localizedPath = `/${prefix}${translatedPathname}`.replace(/\\/+/g, '/');\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n return `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n};\n"],"mappings":";;;;;;;;;;AAUA,MAAM,uBACJ,QAAQ,IAAI,4BACZ,QAAQ,IAAI,6BAA6B;;;;AAK3C,MAAM,2BACJ,QAAQ,IAAI,4BACZ,QAAQ,IAAI,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuD3C,MAAa,mBACX,KACA,gBAA+B,sBAAsB,eAErD,UAA0B,EAAE,KACjB;CACX,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,QAAQ;CAE/B,MAAM,mBAAmB,qBAAqB,KAAK,QAAQ;CAC3D,MAAM,eAAe,gBAAgB,SAAS,MAAM;AAEpD,KAAI,CAAC,wBAAwB,SAAS,YACpC,QAAO,iBACL,iBAAiB,kBAAkB,QAAW,aAAa,EAC3D,eACA,aACD,CAAC;CAGJ,MAAM,gBAAgB,mBAAmB,iBAAiB;CAC1D,MAAM,YAAY,gBACd,IAAI,IAAI,iBAAiB,GACzB,IAAI,IAAI,kBAAkB,qBAAqB;CAEnD,MAAM,qBAAqB,iBACzB,iBAAiB,UAAU,UAAU,QAAW,aAAa,EAC7D,eACA,aACD,CAAC;CAEF,MAAM,UAAU,gBACZ,GAAG,UAAU,SAAS,IAAI,UAAU,SACpC;AAEJ,KAAI,CAAC,4BAA4B,SAAS,iBAAiB;EACzD,MAAM,eAAe,IAAI,gBAAgB,UAAU,OAAO;AAE1D,eAAa,IAAI,UAAU,cAAc,UAAU,CAAC;EAEpD,MAAM,cAAc,aAAa,UAAU;AAK3C,SAAO,GAAG,UAJG,cACT,GAAG,mBAAmB,GAAG,gBACzB,qBAEuB,UAAU;;CAGvC,MAAM,EAAE,WAAW,UAAU,eAAe;EAAE;EAAe;EAAM;EAAS,CAAC;CAE7E,IAAI,gBAAgB,IAAI,SAAS,qBAAqB,QAAQ,QAAQ,IAAI;AAE1E,KAAI,cAAc,SAAS,KAAK,cAAc,SAAS,IAAI,CACzD,iBAAgB,cAAc,MAAM,GAAG,GAAG;AAG5C,QAAO,GAAG,UAAU,gBAAgB,UAAU,SAAS,UAAU"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { checkIsURLAbsolute } from "../utils/checkIsURLAbsolute.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { internationalization } from "@intlayer/config/built";
|
|
3
3
|
|
|
4
4
|
//#region src/localization/getPathWithoutLocale.ts
|
|
5
5
|
/**
|
|
@@ -35,7 +35,7 @@ const TREE_SHAKE_SEARCH_PARAMS = process.env["INTLAYER_ROUTING_MODE"] && process
|
|
|
35
35
|
* @param locales - Optional array of supported locales. Defaults to `localesDefault`.
|
|
36
36
|
* @returns The URL string or pathname without the locale segment or locale search parameter.
|
|
37
37
|
*/
|
|
38
|
-
const getPathWithoutLocale = (inputUrl, locales =
|
|
38
|
+
const getPathWithoutLocale = (inputUrl, locales = internationalization?.locales) => {
|
|
39
39
|
const isAbsoluteUrl = checkIsURLAbsolute(inputUrl);
|
|
40
40
|
let fixedInputUrl = inputUrl;
|
|
41
41
|
if (inputUrl?.endsWith("/")) fixedInputUrl = inputUrl.slice(0, -1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPathWithoutLocale.mjs","names":[],"sources":["../../../src/localization/getPathWithoutLocale.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"getPathWithoutLocale.mjs","names":[],"sources":["../../../src/localization/getPathWithoutLocale.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\n\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 { LocalesValues } 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 */\nexport const getPathWithoutLocale = (\n inputUrl: string,\n locales: LocalesValues[] = internationalization?.locales\n\n): string => {\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://example.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 LocalesValues)) {\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 the modified URL as a string\n return url.toString();\n }\n\n // Return the modified URL as a string\n return url.toString().replace('http://example.com', '');\n};\n"],"mappings":";;;;;;;;AAWA,MAAM,0BACJ,QAAQ,IAAI,4BACZ,QAAQ,IAAI,6BAA6B,gBACzC,QAAQ,IAAI,6BAA6B;;;;AAK3C,MAAM,2BACJ,QAAQ,IAAI,4BACZ,QAAQ,IAAI,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;AA6B3C,MAAa,wBACX,UACA,UAA2B,sBAAsB,YAEtC;CAEX,MAAM,gBAAgB,mBAAmB,SAAS;CAElD,IAAI,gBAAgB;AAEpB,KAAI,UAAU,SAAS,IAAI,CACzB,iBAAgB,SAAS,MAAM,GAAG,GAAG;CAKvC,MAAM,MAAM,gBACR,IAAI,IAAI,cAAc,GACtB,IAAI,IAAI,eAAe,qBAAqB;CAEhD,MAAM,WAAW,IAAI;AAGrB,KAAI,CAAC,SAAS,WAAW,IAAI,CAE3B,KAAI,WAAW,IAAI;AAIrB,KAAI,CAAC,yBAAyB;EAE5B,MAAM,eAAe,SAAS,MAAM,IAAI;EACxC,MAAM,eAAe,aAAa;AAGlC,MAAI,SAAS,SAAS,aAA8B,EAAE;AAEpD,gBAAa,OAAO,GAAG,EAAE;AAIzB,OAAI,WADgB,aAAa,KAAK,IAAI,IAAI;;;AAMlD,KAAI,CAAC,0BAA0B;EAC7B,MAAM,eAAe,IAAI,gBAAgB,IAAI,OAAO;AACpD,MAAI,aAAa,IAAI,SAAS,EAAE;AAC9B,gBAAa,OAAO,SAAS;AAC7B,OAAI,SAAS,aAAa,UAAU;;;AAIxC,KAAI,cAEF,QAAO,IAAI,UAAU;AAIvB,QAAO,IAAI,UAAU,CAAC,QAAQ,sBAAsB,GAAG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { internationalization, routing } from "@intlayer/config/built";
|
|
2
2
|
import { DEFAULT_LOCALE, LOCALES, ROUTING_MODE } from "@intlayer/config/defaultValues";
|
|
3
3
|
|
|
4
4
|
//#region src/localization/getPrefix.ts
|
|
@@ -11,16 +11,13 @@ const TREE_SHAKE_PREFIX_MODES = process.env["INTLAYER_ROUTING_MODE"] && process.
|
|
|
11
11
|
* Resolves routing configuration by merging provided options with configuration defaults.
|
|
12
12
|
* Single source of truth for default routing config resolution across all localization functions.
|
|
13
13
|
*/
|
|
14
|
-
const resolveRoutingConfig = (options = {}) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
...options
|
|
22
|
-
};
|
|
23
|
-
};
|
|
14
|
+
const resolveRoutingConfig = (options = {}) => ({
|
|
15
|
+
defaultLocale: internationalization?.defaultLocale ?? DEFAULT_LOCALE,
|
|
16
|
+
mode: routing?.mode ?? ROUTING_MODE,
|
|
17
|
+
locales: internationalization?.locales ?? LOCALES,
|
|
18
|
+
rewrite: routing?.rewrite,
|
|
19
|
+
...options
|
|
20
|
+
});
|
|
24
21
|
/**
|
|
25
22
|
* Determines the URL prefix for a given locale based on the routing mode configuration.
|
|
26
23
|
*
|