@intlayer/core 5.7.8 → 5.8.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/cjs/formatters/compact.cjs +47 -0
  2. package/dist/cjs/formatters/compact.cjs.map +1 -0
  3. package/dist/cjs/formatters/currency.cjs +51 -0
  4. package/dist/cjs/formatters/currency.cjs.map +1 -0
  5. package/dist/cjs/formatters/date.cjs +83 -0
  6. package/dist/cjs/formatters/date.cjs.map +1 -0
  7. package/dist/cjs/formatters/index.cjs +37 -0
  8. package/dist/cjs/formatters/index.cjs.map +1 -0
  9. package/dist/cjs/formatters/list.cjs +48 -0
  10. package/dist/cjs/formatters/list.cjs.map +1 -0
  11. package/dist/cjs/formatters/number.cjs +44 -0
  12. package/dist/cjs/formatters/number.cjs.map +1 -0
  13. package/dist/cjs/formatters/percentage.cjs +54 -0
  14. package/dist/cjs/formatters/percentage.cjs.map +1 -0
  15. package/dist/cjs/formatters/relativeTime.cjs +75 -0
  16. package/dist/cjs/formatters/relativeTime.cjs.map +1 -0
  17. package/dist/cjs/formatters/units.cjs +49 -0
  18. package/dist/cjs/formatters/units.cjs.map +1 -0
  19. package/dist/cjs/index.cjs +4 -0
  20. package/dist/cjs/index.cjs.map +1 -1
  21. package/dist/cjs/localization/getLocaleName.cjs +5 -15
  22. package/dist/cjs/localization/getLocaleName.cjs.map +1 -1
  23. package/dist/cjs/types/index.cjs +2 -2
  24. package/dist/cjs/types/index.cjs.map +1 -1
  25. package/dist/cjs/utils/intl.cjs +74 -0
  26. package/dist/cjs/utils/intl.cjs.map +1 -0
  27. package/dist/esm/formatters/compact.mjs +13 -0
  28. package/dist/esm/formatters/compact.mjs.map +1 -0
  29. package/dist/esm/formatters/currency.mjs +17 -0
  30. package/dist/esm/formatters/currency.mjs.map +1 -0
  31. package/dist/esm/formatters/date.mjs +49 -0
  32. package/dist/esm/formatters/date.mjs.map +1 -0
  33. package/dist/esm/formatters/index.mjs +9 -0
  34. package/dist/esm/formatters/index.mjs.map +1 -0
  35. package/dist/esm/formatters/list.mjs +14 -0
  36. package/dist/esm/formatters/list.mjs.map +1 -0
  37. package/dist/esm/formatters/number.mjs +10 -0
  38. package/dist/esm/formatters/number.mjs.map +1 -0
  39. package/dist/esm/formatters/percentage.mjs +20 -0
  40. package/dist/esm/formatters/percentage.mjs.map +1 -0
  41. package/dist/esm/formatters/relativeTime.mjs +41 -0
  42. package/dist/esm/formatters/relativeTime.mjs.map +1 -0
  43. package/dist/esm/formatters/units.mjs +15 -0
  44. package/dist/esm/formatters/units.mjs.map +1 -0
  45. package/dist/esm/index.mjs +2 -0
  46. package/dist/esm/index.mjs.map +1 -1
  47. package/dist/esm/localization/getLocaleName.mjs +5 -15
  48. package/dist/esm/localization/getLocaleName.mjs.map +1 -1
  49. package/dist/esm/types/index.mjs +1 -1
  50. package/dist/esm/types/index.mjs.map +1 -1
  51. package/dist/esm/utils/intl.mjs +39 -0
  52. package/dist/esm/utils/intl.mjs.map +1 -0
  53. package/dist/types/formatters/compact.d.ts +16 -0
  54. package/dist/types/formatters/compact.d.ts.map +1 -0
  55. package/dist/types/formatters/currency.d.ts +16 -0
  56. package/dist/types/formatters/currency.d.ts.map +1 -0
  57. package/dist/types/formatters/date.d.ts +16 -0
  58. package/dist/types/formatters/date.d.ts.map +1 -0
  59. package/dist/types/formatters/index.d.ts +9 -0
  60. package/dist/types/formatters/index.d.ts.map +1 -0
  61. package/dist/types/formatters/list.d.ts +20 -0
  62. package/dist/types/formatters/list.d.ts.map +1 -0
  63. package/dist/types/formatters/number.d.ts +12 -0
  64. package/dist/types/formatters/number.d.ts.map +1 -0
  65. package/dist/types/formatters/percentage.d.ts +12 -0
  66. package/dist/types/formatters/percentage.d.ts.map +1 -0
  67. package/dist/types/formatters/relativeTime.d.ts +8 -0
  68. package/dist/types/formatters/relativeTime.d.ts.map +1 -0
  69. package/dist/types/formatters/units.d.ts +12 -0
  70. package/dist/types/formatters/units.d.ts.map +1 -0
  71. package/dist/types/index.d.ts +2 -0
  72. package/dist/types/index.d.ts.map +1 -1
  73. package/dist/types/localization/getLocaleName.d.ts.map +1 -1
  74. package/dist/types/types/index.d.ts +1 -1
  75. package/dist/types/types/index.d.ts.map +1 -1
  76. package/dist/types/utils/intl.d.ts +12 -0
  77. package/dist/types/utils/intl.d.ts.map +1 -0
  78. package/package.json +59 -14
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/types/index.ts"],"sourcesContent":["export * from './dictionary';\nexport * from './nodeType';\nexport * from './keyPath';\nexport * from './translation';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,yBAAd;AACA,0BAAc,uBADd;AAEA,0BAAc,sBAFd;AAGA,0BAAc,0BAHd;","names":[]}
1
+ {"version":3,"sources":["../../../src/types/index.ts"],"sourcesContent":["export * from './dictionary';\nexport * from './keyPath';\nexport * from './nodeType';\nexport * from './translation';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,yBAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,uBAFd;AAGA,0BAAc,0BAHd;","names":[]}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var intl_exports = {};
30
+ __export(intl_exports, {
31
+ Intl: () => CachedIntl,
32
+ createCachedIntl: () => createCachedIntl
33
+ });
34
+ module.exports = __toCommonJS(intl_exports);
35
+ var import_built = __toESM(require("@intlayer/config/built"));
36
+ const cacheKey = (locales, options) => JSON.stringify([locales, options]);
37
+ const createCachedConstructor = (Ctor) => {
38
+ const cache = /* @__PURE__ */ new Map();
39
+ function Wrapped(locales, options) {
40
+ if (Ctor.name === "DisplayNames" && typeof Intl?.DisplayNames !== "function") {
41
+ if (process.env.NODE_ENV === "development") {
42
+ console.warn(
43
+ `Intl.DisplayNames is not supported; falling back to raw locale (${locales}). Consider adding a polyfill as https://formatjs.io/docs/polyfills/intl-displaynames/`
44
+ );
45
+ }
46
+ return locales;
47
+ }
48
+ const key = cacheKey(
49
+ locales ?? import_built.default.internationalization.defaultLocale,
50
+ options
51
+ );
52
+ let instance = cache.get(key);
53
+ if (!instance) {
54
+ instance = new Ctor(locales, options);
55
+ cache.set(key, instance);
56
+ }
57
+ return instance;
58
+ }
59
+ Wrapped.prototype = Ctor.prototype;
60
+ return Wrapped;
61
+ };
62
+ const createCachedIntl = () => new Proxy(Intl, {
63
+ get: (target, prop, receiver) => {
64
+ const value = Reflect.get(target, prop, receiver);
65
+ return typeof value === "function" && /^[A-Z]/.test(String(prop)) ? createCachedConstructor(value) : value;
66
+ }
67
+ });
68
+ const CachedIntl = createCachedIntl();
69
+ // Annotate the CommonJS export names for ESM import in node:
70
+ 0 && (module.exports = {
71
+ Intl,
72
+ createCachedIntl
73
+ });
74
+ //# sourceMappingURL=intl.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/intl.ts"],"sourcesContent":["// Cached Intl helper – drop‑in replacement for the global `Intl` object.\n// ‑‑‑\n// • Uses a `Proxy` to lazily wrap every *constructor* hanging off `Intl` (NumberFormat, DateTimeFormat, …).\n// • Each wrapped constructor keeps an in‑memory cache keyed by `[locales, options]` so that identical requests\n// reuse the same heavy instance instead of reparsing CLDR data every time.\n// • A polyfill warning for `Intl.DisplayNames` is emitted only once and only in dev.\n// • The public API is fully type‑safe and mirrors the native `Intl` surface exactly –\n// you can treat `CachedIntl` just like the built‑in `Intl`.\n//\n// Usage examples:\n// ---------------\n// import { CachedIntl } from \"./cached-intl\";\n//\n// const nf = CachedIntl.NumberFormat(\"en-US\", { style: \"currency\", currency: \"USD\" });\n// console.log(nf.format(1234));\n//\n// const dn = CachedIntl.DisplayNames([\"fr\"], { type: \"language\" });\n// console.log(dn.of(\"en\")); // → \"anglais\"\n//\n// You can also spin up an isolated instance with its own caches (handy in test suites):\n// const TestIntl = createCachedIntl();\n//\n// ---------------------------------------------------------------------\n\nimport { LocalesValues } from '@intlayer/config';\nimport configuration from '@intlayer/config/built';\n\n// Helper type that picks just the constructor members off `typeof Intl`.\n// The \"capital‑letter\" heuristic is 100 % accurate today and keeps the\n// mapping short‑lived, so we don't have to manually list every constructor.\ntype IntlConstructors = {\n [K in keyof typeof Intl as (typeof Intl)[K] extends new (...args: any) => any\n ? K\n : never]: (typeof Intl)[K];\n};\n\n// Type wrapper to replace locale arguments with LocalesValues\ntype ReplaceLocaleWithLocalesValues<T> = T extends new (\n locales: any,\n options?: infer Options\n) => infer Instance\n ? new (locales?: LocalesValues, options?: Options) => Instance\n : T extends new (locales: any) => infer Instance\n ? new (locales?: LocalesValues) => Instance\n : T;\n\n// Wrapped Intl type with LocalesValues\ntype WrappedIntl = {\n [K in keyof typeof Intl]: K extends keyof IntlConstructors\n ? ReplaceLocaleWithLocalesValues<(typeof Intl)[K]>\n : (typeof Intl)[K];\n};\n\n// Generic cache key – JSON.stringify is fine because locale strings are short\n// and option objects are small and deterministic.\nconst cacheKey = (locales: LocalesValues, options: unknown) =>\n JSON.stringify([locales, options]);\n\n// Generic wrapper for any `new Intl.*()` constructor.\n// Returns a constructable function (usable with or without `new`) that\n// pulls instances from a Map cache when possible.\nconst createCachedConstructor = <T extends new (...args: any[]) => any>(\n Ctor: T\n) => {\n const cache = new Map<string, InstanceType<T>>();\n\n function Wrapped(locales?: LocalesValues, options?: any) {\n // Special case – guard older runtimes missing DisplayNames.\n if (\n Ctor.name === 'DisplayNames' &&\n typeof (Intl as any)?.DisplayNames !== 'function'\n ) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `Intl.DisplayNames is not supported; falling back to raw locale (${locales}). ` +\n `Consider adding a polyfill as https://formatjs.io/docs/polyfills/intl-displaynames/`\n );\n }\n return locales as any;\n }\n\n const key = cacheKey(\n locales ?? configuration.internationalization.defaultLocale,\n options\n );\n let instance: InstanceType<T> | undefined = cache.get(key);\n\n if (!instance) {\n instance = new Ctor(locales as never, options as never);\n cache.set(key, instance as InstanceType<T>);\n }\n\n return instance as InstanceType<T>;\n }\n\n // Ensure it behaves like a constructor when used with `new`.\n (Wrapped as any).prototype = (Ctor as any).prototype;\n\n return Wrapped as unknown as ReplaceLocaleWithLocalesValues<T>;\n};\n\n// Factory that turns the global `Intl` into a cached clone.\nexport const createCachedIntl = (): WrappedIntl =>\n new Proxy(Intl as IntlConstructors, {\n get: (target, prop, receiver) => {\n const value = Reflect.get(target, prop, receiver);\n\n // Wrap *only* constructor functions (safest heuristic: they start with a capital letter).\n return typeof value === 'function' && /^[A-Z]/.test(String(prop))\n ? createCachedConstructor(value)\n : value;\n },\n }) as unknown as WrappedIntl;\n\n// Singleton – import this in application code if you just want shared caches.\nconst CachedIntl = createCachedIntl();\n\n// new CachedIntl.DisplayNames(Locales.FRENCH, { type: 'language' });\n// new CachedIntl.DisplayNames('fr', { type: 'language' });\n// new CachedIntl.DateTimeFormat('fr', {\n// year: 'numeric',\n// month: 'long',\n// day: 'numeric',\n// });\n// new CachedIntl.NumberFormat('fr', {\n// style: 'currency',\n// currency: 'EUR',\n// });\n// new CachedIntl.Collator('fr', { sensitivity: 'base' });\n// new CachedIntl.PluralRules('fr');\n// new CachedIntl.RelativeTimeFormat('fr', { numeric: 'auto' });\n// new CachedIntl.ListFormat('fr', { type: 'conjunction' });\n\nexport { CachedIntl as Intl };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBA,mBAA0B;AA8B1B,MAAM,WAAW,CAAC,SAAwB,YACxC,KAAK,UAAU,CAAC,SAAS,OAAO,CAAC;AAKnC,MAAM,0BAA0B,CAC9B,SACG;AACH,QAAM,QAAQ,oBAAI,IAA6B;AAE/C,WAAS,QAAQ,SAAyB,SAAe;AAEvD,QACE,KAAK,SAAS,kBACd,OAAQ,MAAc,iBAAiB,YACvC;AACA,UAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,gBAAQ;AAAA,UACN,mEAAmE,OAAO;AAAA,QAE5E;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,UAAM,MAAM;AAAA,MACV,WAAW,aAAAA,QAAc,qBAAqB;AAAA,MAC9C;AAAA,IACF;AACA,QAAI,WAAwC,MAAM,IAAI,GAAG;AAEzD,QAAI,CAAC,UAAU;AACb,iBAAW,IAAI,KAAK,SAAkB,OAAgB;AACtD,YAAM,IAAI,KAAK,QAA2B;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAGA,EAAC,QAAgB,YAAa,KAAa;AAE3C,SAAO;AACT;AAGO,MAAM,mBAAmB,MAC9B,IAAI,MAAM,MAA0B;AAAA,EAClC,KAAK,CAAC,QAAQ,MAAM,aAAa;AAC/B,UAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAGhD,WAAO,OAAO,UAAU,cAAc,SAAS,KAAK,OAAO,IAAI,CAAC,IAC5D,wBAAwB,KAAK,IAC7B;AAAA,EACN;AACF,CAAC;AAGH,MAAM,aAAa,iBAAiB;","names":["configuration"]}
@@ -0,0 +1,13 @@
1
+ import configuration from "@intlayer/config/built";
2
+ import { Intl } from "../utils/intl.mjs";
3
+ const compact = (value, options) => new Intl.NumberFormat(
4
+ options?.locale ?? configuration.internationalization.defaultLocale,
5
+ {
6
+ ...options,
7
+ notation: "compact"
8
+ }
9
+ ).format(Number(value));
10
+ export {
11
+ compact
12
+ };
13
+ //# sourceMappingURL=compact.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/compact.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { LocalesValues } from '@intlayer/config/client';\nimport { Intl } 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({ value: 1200 }); // \"1.2K\"\n *\n * @example\n * compact({ value: \"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 new Intl.NumberFormat(\n options?.locale ?? configuration.internationalization.defaultLocale,\n {\n ...options,\n notation: 'compact',\n }\n ).format(Number(value));\n"],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,SAAS,YAAY;AAad,MAAM,UAAU,CACrB,OACA,YAEA,IAAI,KAAK;AAAA,EACP,SAAS,UAAU,cAAc,qBAAqB;AAAA,EACtD;AAAA,IACE,GAAG;AAAA,IACH,UAAU;AAAA,EACZ;AACF,EAAE,OAAO,OAAO,KAAK,CAAC;","names":[]}
@@ -0,0 +1,17 @@
1
+ import configuration from "@intlayer/config/built";
2
+ import { Intl } from "../utils/intl.mjs";
3
+ const currency = (value, options) => new Intl.NumberFormat(
4
+ options?.locale ?? configuration.internationalization.defaultLocale,
5
+ {
6
+ style: "currency",
7
+ currency: options?.currency ?? "USD",
8
+ currencyDisplay: options?.currencyDisplay ?? "symbol",
9
+ minimumFractionDigits: options?.minimumFractionDigits ?? 2,
10
+ maximumFractionDigits: options?.maximumFractionDigits ?? 2,
11
+ ...options
12
+ }
13
+ ).format(Number(value));
14
+ export {
15
+ currency
16
+ };
17
+ //# sourceMappingURL=currency.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/currency.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type LocalesValues } from '@intlayer/config/client';\nimport { Intl } 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({ value: 1234.5, currency: 'EUR' });\n * // \"€1,234.50\"\n *\n * @example\n * currency({ value: \"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 new Intl.NumberFormat(\n options?.locale ?? configuration.internationalization.defaultLocale,\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":"AAAA,OAAO,mBAAmB;AAE1B,SAAS,YAAY;AAad,MAAM,WAAW,CACtB,OACA,YAEA,IAAI,KAAK;AAAA,EACP,SAAS,UAAU,cAAc,qBAAqB;AAAA,EACtD;AAAA,IACE,OAAO;AAAA,IACP,UAAU,SAAS,YAAY;AAAA,IAC/B,iBAAiB,SAAS,mBAAmB;AAAA,IAC7C,uBAAuB,SAAS,yBAAyB;AAAA,IACzD,uBAAuB,SAAS,yBAAyB;AAAA,IACzD,GAAG;AAAA,EACL;AACF,EAAE,OAAO,OAAO,KAAK,CAAC;","names":[]}
@@ -0,0 +1,49 @@
1
+ import configuration from "@intlayer/config/built";
2
+ import { Intl } from "../utils/intl.mjs";
3
+ const presets = {
4
+ short: {
5
+ year: "2-digit",
6
+ month: "2-digit",
7
+ day: "2-digit",
8
+ hour: "2-digit",
9
+ minute: "2-digit"
10
+ },
11
+ long: {
12
+ year: "numeric",
13
+ month: "long",
14
+ day: "numeric",
15
+ hour: "numeric",
16
+ minute: "numeric"
17
+ },
18
+ full: {
19
+ year: "numeric",
20
+ month: "long",
21
+ day: "numeric",
22
+ hour: "numeric",
23
+ minute: "numeric",
24
+ hour12: false
25
+ },
26
+ dateOnly: {
27
+ year: "numeric",
28
+ month: "short",
29
+ day: "numeric"
30
+ },
31
+ timeOnly: {
32
+ hour: "numeric",
33
+ minute: "numeric",
34
+ second: "numeric"
35
+ }
36
+ };
37
+ const date = (date2, options) => {
38
+ const dateTime = new Date(date2);
39
+ const resolvedOptions = typeof options === "string" ? presets[options] ?? {} : options;
40
+ const formatter = new Intl.DateTimeFormat(
41
+ options?.locale ?? configuration.internationalization.defaultLocale,
42
+ resolvedOptions
43
+ );
44
+ return formatter.format(dateTime);
45
+ };
46
+ export {
47
+ date
48
+ };
49
+ //# sourceMappingURL=date.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/date.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type LocalesValues } from '@intlayer/config/client';\nimport { Intl } from '../utils/intl';\n\ntype DateTimePreset = 'short' | 'long' | 'dateOnly' | 'timeOnly' | 'full';\n\nconst 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({ date: new Date(), options: \"short\" });\n * // \"08/02/25, 14:30\"\n *\n * @example\n * date({ date: \"2025-08-02T14:30:00Z\", locale: Locales.FRENCH, options: { month: \"long\", day: \"numeric\" } });\n * // \"2 août\"\n */\nexport const date = (\n date: Date | string | number,\n options?: Intl.DateTimeFormatOptions & { locale?: LocalesValues }\n): string => {\n const dateTime = new Date(date);\n\n const resolvedOptions =\n typeof options === 'string' ? (presets[options] ?? {}) : options;\n\n const formatter = new Intl.DateTimeFormat(\n options?.locale ?? configuration.internationalization.defaultLocale,\n resolvedOptions\n );\n\n return formatter.format(dateTime);\n};\n"],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,SAAS,YAAY;AAIrB,MAAM,UAA8D;AAAA,EAClE,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,EACP;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;AAaO,MAAM,OAAO,CAClBA,OACA,YACW;AACX,QAAM,WAAW,IAAI,KAAKA,KAAI;AAE9B,QAAM,kBACJ,OAAO,YAAY,WAAY,QAAQ,OAAO,KAAK,CAAC,IAAK;AAE3D,QAAM,YAAY,IAAI,KAAK;AAAA,IACzB,SAAS,UAAU,cAAc,qBAAqB;AAAA,IACtD;AAAA,EACF;AAEA,SAAO,UAAU,OAAO,QAAQ;AAClC;","names":["date"]}
@@ -0,0 +1,9 @@
1
+ export * from "./compact.mjs";
2
+ export * from "./currency.mjs";
3
+ export * from "./date.mjs";
4
+ export * from "./list.mjs";
5
+ export * from "./number.mjs";
6
+ export * from "./percentage.mjs";
7
+ export * from "./relativeTime.mjs";
8
+ export * from "./units.mjs";
9
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/index.ts"],"sourcesContent":["export * from './compact';\nexport * from './currency';\nexport * from './date';\nexport * from './list';\nexport * from './number';\nexport * from './percentage';\nexport * from './relativeTime';\nexport * from './units';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,14 @@
1
+ import configuration from "@intlayer/config/built";
2
+ import { Intl } from "../utils/intl.mjs";
3
+ const list = (values, options) => new Intl.ListFormat(
4
+ options?.locale ?? configuration.internationalization.defaultLocale,
5
+ {
6
+ type: options?.type ?? "conjunction",
7
+ style: options?.style ?? "long",
8
+ ...options
9
+ }
10
+ ).format(values.map(String));
11
+ export {
12
+ list
13
+ };
14
+ //# sourceMappingURL=list.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/list.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type LocalesValues } from '@intlayer/config/client';\nimport { Intl } from '../utils/intl';\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?: Intl.ListFormatOptions & { locale?: LocalesValues }\n): string =>\n new Intl.ListFormat(\n options?.locale ?? configuration.internationalization.defaultLocale,\n {\n type: options?.type ?? 'conjunction',\n style: options?.style ?? 'long',\n ...options,\n }\n ).format(values.map(String));\n"],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,SAAS,YAAY;AAiBd,MAAM,OAAO,CAClB,QACA,YAEA,IAAI,KAAK;AAAA,EACP,SAAS,UAAU,cAAc,qBAAqB;AAAA,EACtD;AAAA,IACE,MAAM,SAAS,QAAQ;AAAA,IACvB,OAAO,SAAS,SAAS;AAAA,IACzB,GAAG;AAAA,EACL;AACF,EAAE,OAAO,OAAO,IAAI,MAAM,CAAC;","names":[]}
@@ -0,0 +1,10 @@
1
+ import configuration from "@intlayer/config/built";
2
+ import { Intl } from "../utils/intl.mjs";
3
+ const number = (value, options) => new Intl.NumberFormat(
4
+ options?.locale ?? configuration.internationalization.defaultLocale,
5
+ options
6
+ ).format(Number(value));
7
+ export {
8
+ number
9
+ };
10
+ //# sourceMappingURL=number.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/number.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type LocalesValues } from '@intlayer/config/client';\nimport { Intl } from '../utils/intl';\n\n/**\n * Formats a numeric value using locale-aware formatting.\n *\n * @example\n * number({ value: 123456.789 }); // \"123,456.789\"\n * number({ value: \"1000000\", locale: Locales.FRENCH }); // \"1 000 000\"\n */\nexport const number = (\n value: string | number,\n options?: Intl.NumberFormatOptions & { locale?: LocalesValues }\n): string =>\n new Intl.NumberFormat(\n options?.locale ?? configuration.internationalization.defaultLocale,\n options\n ).format(Number(value));\n"],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,SAAS,YAAY;AASd,MAAM,SAAS,CACpB,OACA,YAEA,IAAI,KAAK;AAAA,EACP,SAAS,UAAU,cAAc,qBAAqB;AAAA,EACtD;AACF,EAAE,OAAO,OAAO,KAAK,CAAC;","names":[]}
@@ -0,0 +1,20 @@
1
+ import configuration from "@intlayer/config/built";
2
+ import { Intl } from "../utils/intl.mjs";
3
+ const percentage = (value, options) => {
4
+ let numericValue = Number(value);
5
+ if (numericValue > 1) {
6
+ numericValue = numericValue / 100;
7
+ }
8
+ const formatter = new Intl.NumberFormat(
9
+ options?.locale ?? configuration.internationalization.defaultLocale,
10
+ {
11
+ style: "percent",
12
+ ...options
13
+ }
14
+ );
15
+ return formatter.format(Number(numericValue));
16
+ };
17
+ export {
18
+ percentage
19
+ };
20
+ //# sourceMappingURL=percentage.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/percentage.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type LocalesValues } from '@intlayer/config/client';\nimport { Intl } from '../utils/intl';\n\n/**\n * Formats a number as a percentage string (e.g., 0.25 → \"25%\").\n *\n * @example\n * percentage({ value: 0.25 }) // \"25%\"\n * percentage({ value: 0.25, minimumFractionDigits: 2 }) // \"25.00%\"\n */\nexport const percentage = (\n value: string | number,\n options?: 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 = numericValue / 100;\n }\n\n const formatter = new Intl.NumberFormat(\n options?.locale ?? configuration.internationalization.defaultLocale,\n {\n style: 'percent',\n ...options,\n }\n );\n\n return formatter.format(Number(numericValue));\n};\n"],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,SAAS,YAAY;AASd,MAAM,aAAa,CACxB,OACA,YACW;AACX,MAAI,eAAe,OAAO,KAAK;AAG/B,MAAI,eAAe,GAAG;AACpB,mBAAe,eAAe;AAAA,EAChC;AAEA,QAAM,YAAY,IAAI,KAAK;AAAA,IACzB,SAAS,UAAU,cAAc,qBAAqB;AAAA,IACtD;AAAA,MACE,OAAO;AAAA,MACP,GAAG;AAAA,IACL;AAAA,EACF;AAEA,SAAO,UAAU,OAAO,OAAO,YAAY,CAAC;AAC9C;","names":[]}
@@ -0,0 +1,41 @@
1
+ import configuration from "@intlayer/config/built";
2
+ import { Intl } from "../utils/intl.mjs";
3
+ const diffInUnit = (from, to, unit) => {
4
+ const msDiff = to.getTime() - from.getTime();
5
+ const sec = msDiff / 1e3;
6
+ switch (unit) {
7
+ case "second":
8
+ return sec;
9
+ case "minute":
10
+ return sec / 60;
11
+ case "hour":
12
+ return sec / 3600;
13
+ case "day":
14
+ return sec / 86400;
15
+ case "month":
16
+ return sec / (30 * 86400);
17
+ // approx
18
+ case "quarter":
19
+ return sec / (3 * 30 * 86400);
20
+ // 3 months approx
21
+ case "year":
22
+ return sec / (365 * 86400);
23
+ // approx
24
+ default:
25
+ return sec;
26
+ }
27
+ };
28
+ const relativeTime = (from, to = /* @__PURE__ */ new Date(), options) => {
29
+ const fromDate = new Date(from);
30
+ const toDate = new Date(to);
31
+ const unit = options?.unit ?? "second";
32
+ const value = diffInUnit(fromDate, toDate, unit);
33
+ return new Intl.RelativeTimeFormat(
34
+ options?.locale ?? configuration.internationalization.defaultLocale,
35
+ options
36
+ ).format(Math.round(value), unit);
37
+ };
38
+ export {
39
+ relativeTime
40
+ };
41
+ //# sourceMappingURL=relativeTime.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/relativeTime.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type LocalesValues } from '@intlayer/config/client';\nimport { Intl } 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\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 new Intl.RelativeTimeFormat(\n options?.locale ?? configuration.internationalization.defaultLocale,\n options\n ).format(Math.round(value), unit);\n};\n"],"mappings":"AAAA,OAAO,mBAAmB;AAE1B,SAAS,YAAY;AAOrB,MAAM,aAAa,CAAC,MAAY,IAAU,SAAmC;AAC3E,QAAM,SAAS,GAAG,QAAQ,IAAI,KAAK,QAAQ;AAC3C,QAAM,MAAM,SAAS;AAErB,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,MAAM;AAAA,IACf,KAAK;AACH,aAAO,MAAM;AAAA,IACf,KAAK;AACH,aAAO,MAAM;AAAA,IACf,KAAK;AACH,aAAO,OAAO,KAAK;AAAA;AAAA,IACrB,KAAK;AACH,aAAO,OAAO,IAAI,KAAK;AAAA;AAAA,IACzB,KAAK;AACH,aAAO,OAAO,MAAM;AAAA;AAAA,IACtB;AACE,aAAO;AAAA,EACX;AACF;AAEO,MAAM,eAAe,CAC1B,MACA,KAA6B,oBAAI,KAAK,GACtC,YAIW;AACX,QAAM,WAAW,IAAI,KAAK,IAAI;AAC9B,QAAM,SAAS,IAAI,KAAK,EAAE;AAC1B,QAAM,OAAO,SAAS,QAAQ;AAE9B,QAAM,QAAQ,WAAW,UAAU,QAAQ,IAAI;AAE/C,SAAO,IAAI,KAAK;AAAA,IACd,SAAS,UAAU,cAAc,qBAAqB;AAAA,IACtD;AAAA,EACF,EAAE,OAAO,KAAK,MAAM,KAAK,GAAG,IAAI;AAClC;","names":[]}
@@ -0,0 +1,15 @@
1
+ import configuration from "@intlayer/config/built";
2
+ import { Intl } from "../utils/intl.mjs";
3
+ const units = (value, options) => new Intl.NumberFormat(
4
+ options.locale ?? configuration.internationalization.defaultLocale,
5
+ {
6
+ style: "unit",
7
+ unit: options.unit ?? "day",
8
+ unitDisplay: options.unitDisplay ?? "short",
9
+ useGrouping: options.useGrouping ?? false
10
+ }
11
+ ).format(Number(value));
12
+ export {
13
+ units
14
+ };
15
+ //# sourceMappingURL=units.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/formatters/units.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type LocalesValues } from '@intlayer/config/client';\nimport { Intl } from '../utils/intl';\n\n/**\n * Formats a numeric value as a localized unit string.\n *\n * @example\n * units({ value: 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 new Intl.NumberFormat(\n options.locale ?? configuration.internationalization.defaultLocale,\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":"AAAA,OAAO,mBAAmB;AAE1B,SAAS,YAAY;AASd,MAAM,QAAQ,CACnB,OACA,YAEA,IAAI,KAAK;AAAA,EACP,QAAQ,UAAU,cAAc,qBAAqB;AAAA,EACrD;AAAA,IACE,OAAO;AAAA,IACP,MAAM,QAAQ,QAAQ;AAAA,IACtB,aAAa,QAAQ,eAAe;AAAA,IACpC,aAAa,QAAQ,eAAe;AAAA,EACtC;AACF,EAAE,OAAO,OAAO,KAAK,CAAC;","names":[]}
@@ -1,9 +1,11 @@
1
1
  export * from "./dictionaryManipulator/index.mjs";
2
+ export * from "./formatters/index.mjs";
2
3
  export * from "./interpreter/index.mjs";
3
4
  export * from "./localization/index.mjs";
4
5
  export * from "./transpiler/index.mjs";
5
6
  export * from "./types/index.mjs";
6
7
  export * from "./utils/checkIsURLAbsolute.mjs";
8
+ export * from "./utils/intl.mjs";
7
9
  export * from "./utils/isSameKeyPath.mjs";
8
10
  export * from "./utils/isValidReactElement.mjs";
9
11
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './dictionaryManipulator/index';\nexport * from './interpreter/index';\nexport * from './localization/index';\nexport * from './transpiler/index';\nexport * from './types/index';\nexport * from './utils/checkIsURLAbsolute';\nexport * from './utils/isSameKeyPath';\nexport * from './utils/isValidReactElement';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './dictionaryManipulator/index';\nexport * from './formatters/index';\nexport * from './interpreter/index';\nexport * from './localization/index';\nexport * from './transpiler/index';\nexport * from './types/index';\nexport * from './utils/checkIsURLAbsolute';\nexport * from './utils/intl';\nexport * from './utils/isSameKeyPath';\nexport * from './utils/isValidReactElement';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -1,19 +1,9 @@
1
- const dnCache = /* @__PURE__ */ new Map();
1
+ import { Intl } from "../utils/intl.mjs";
2
2
  const getLocaleName = (displayLocale, targetLocale = displayLocale) => {
3
- if (typeof Intl?.DisplayNames !== "function") {
4
- if (process.env.NODE_ENV === "development") {
5
- console.warn(
6
- `Intl.DisplayNames is not supported; falling back to raw locale (${displayLocale}). Consider adding a polyfill as https://formatjs.github.io/docs/polyfills/intl-displaynames/`
7
- );
8
- }
9
- return displayLocale;
10
- }
11
- let dn = dnCache.get(targetLocale);
12
- if (!dn) {
13
- dn = new Intl.DisplayNames([targetLocale], { type: "language" });
14
- dnCache.set(targetLocale, dn);
15
- }
16
- return dn.of(displayLocale) ?? "Unknown locale";
3
+ let displayNames = new Intl.DisplayNames(targetLocale, {
4
+ type: "language"
5
+ });
6
+ return displayNames.of(displayLocale) ?? "Unknown locale";
17
7
  };
18
8
  export {
19
9
  getLocaleName
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/localization/getLocaleName.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/config/client';\n\nconst dnCache = new Map<LocalesValues, Intl.DisplayNames>();\n\nexport const getLocaleName = (\n displayLocale: LocalesValues,\n targetLocale: LocalesValues = displayLocale\n): string => {\n if (typeof Intl?.DisplayNames !== 'function') {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `Intl.DisplayNames is not supported; falling back to raw locale (${displayLocale}). Consider adding a polyfill as https://formatjs.github.io/docs/polyfills/intl-displaynames/`\n );\n }\n return displayLocale;\n }\n\n // new Intl.DisplayNames() is fairly heavy: under the hood every call parses CLDR data and builds a resolver table. In your LocaleSwitcher it’s invoked:\n let dn = dnCache.get(targetLocale);\n if (!dn) {\n dn = new Intl.DisplayNames([targetLocale], { type: 'language' });\n dnCache.set(targetLocale, dn);\n }\n\n return dn.of(displayLocale) ?? 'Unknown locale';\n};\n"],"mappings":"AAEA,MAAM,UAAU,oBAAI,IAAsC;AAEnD,MAAM,gBAAgB,CAC3B,eACA,eAA8B,kBACnB;AACX,MAAI,OAAO,MAAM,iBAAiB,YAAY;AAC5C,QAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,cAAQ;AAAA,QACN,mEAAmE,aAAa;AAAA,MAClF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,QAAQ,IAAI,YAAY;AACjC,MAAI,CAAC,IAAI;AACP,SAAK,IAAI,KAAK,aAAa,CAAC,YAAY,GAAG,EAAE,MAAM,WAAW,CAAC;AAC/D,YAAQ,IAAI,cAAc,EAAE;AAAA,EAC9B;AAEA,SAAO,GAAG,GAAG,aAAa,KAAK;AACjC;","names":[]}
1
+ {"version":3,"sources":["../../../src/localization/getLocaleName.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/config/client';\nimport { Intl } from '../utils/intl';\n\nexport const getLocaleName = (\n displayLocale: LocalesValues,\n targetLocale: LocalesValues = displayLocale\n): string => {\n // new Intl.DisplayNames() is fairly heavy: under the hood every call parses CLDR data and builds a resolver table. In your LocaleSwitcher it’s invoked:\n let displayNames = new Intl.DisplayNames(targetLocale, {\n type: 'language',\n });\n\n return displayNames.of(displayLocale) ?? 'Unknown locale';\n};\n"],"mappings":"AACA,SAAS,YAAY;AAEd,MAAM,gBAAgB,CAC3B,eACA,eAA8B,kBACnB;AAEX,MAAI,eAAe,IAAI,KAAK,aAAa,cAAc;AAAA,IACrD,MAAM;AAAA,EACR,CAAC;AAED,SAAO,aAAa,GAAG,aAAa,KAAK;AAC3C;","names":[]}
@@ -1,5 +1,5 @@
1
1
  export * from "./dictionary.mjs";
2
- export * from "./nodeType.mjs";
3
2
  export * from "./keyPath.mjs";
3
+ export * from "./nodeType.mjs";
4
4
  export * from "./translation.mjs";
5
5
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/types/index.ts"],"sourcesContent":["export * from './dictionary';\nexport * from './nodeType';\nexport * from './keyPath';\nexport * from './translation';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../src/types/index.ts"],"sourcesContent":["export * from './dictionary';\nexport * from './keyPath';\nexport * from './nodeType';\nexport * from './translation';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,39 @@
1
+ import configuration from "@intlayer/config/built";
2
+ const cacheKey = (locales, options) => JSON.stringify([locales, options]);
3
+ const createCachedConstructor = (Ctor) => {
4
+ const cache = /* @__PURE__ */ new Map();
5
+ function Wrapped(locales, options) {
6
+ if (Ctor.name === "DisplayNames" && typeof Intl?.DisplayNames !== "function") {
7
+ if (process.env.NODE_ENV === "development") {
8
+ console.warn(
9
+ `Intl.DisplayNames is not supported; falling back to raw locale (${locales}). Consider adding a polyfill as https://formatjs.io/docs/polyfills/intl-displaynames/`
10
+ );
11
+ }
12
+ return locales;
13
+ }
14
+ const key = cacheKey(
15
+ locales ?? configuration.internationalization.defaultLocale,
16
+ options
17
+ );
18
+ let instance = cache.get(key);
19
+ if (!instance) {
20
+ instance = new Ctor(locales, options);
21
+ cache.set(key, instance);
22
+ }
23
+ return instance;
24
+ }
25
+ Wrapped.prototype = Ctor.prototype;
26
+ return Wrapped;
27
+ };
28
+ const createCachedIntl = () => new Proxy(Intl, {
29
+ get: (target, prop, receiver) => {
30
+ const value = Reflect.get(target, prop, receiver);
31
+ return typeof value === "function" && /^[A-Z]/.test(String(prop)) ? createCachedConstructor(value) : value;
32
+ }
33
+ });
34
+ const CachedIntl = createCachedIntl();
35
+ export {
36
+ CachedIntl as Intl,
37
+ createCachedIntl
38
+ };
39
+ //# sourceMappingURL=intl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/intl.ts"],"sourcesContent":["// Cached Intl helper – drop‑in replacement for the global `Intl` object.\n// ‑‑‑\n// • Uses a `Proxy` to lazily wrap every *constructor* hanging off `Intl` (NumberFormat, DateTimeFormat, …).\n// • Each wrapped constructor keeps an in‑memory cache keyed by `[locales, options]` so that identical requests\n// reuse the same heavy instance instead of reparsing CLDR data every time.\n// • A polyfill warning for `Intl.DisplayNames` is emitted only once and only in dev.\n// • The public API is fully type‑safe and mirrors the native `Intl` surface exactly –\n// you can treat `CachedIntl` just like the built‑in `Intl`.\n//\n// Usage examples:\n// ---------------\n// import { CachedIntl } from \"./cached-intl\";\n//\n// const nf = CachedIntl.NumberFormat(\"en-US\", { style: \"currency\", currency: \"USD\" });\n// console.log(nf.format(1234));\n//\n// const dn = CachedIntl.DisplayNames([\"fr\"], { type: \"language\" });\n// console.log(dn.of(\"en\")); // → \"anglais\"\n//\n// You can also spin up an isolated instance with its own caches (handy in test suites):\n// const TestIntl = createCachedIntl();\n//\n// ---------------------------------------------------------------------\n\nimport { LocalesValues } from '@intlayer/config';\nimport configuration from '@intlayer/config/built';\n\n// Helper type that picks just the constructor members off `typeof Intl`.\n// The \"capital‑letter\" heuristic is 100 % accurate today and keeps the\n// mapping short‑lived, so we don't have to manually list every constructor.\ntype IntlConstructors = {\n [K in keyof typeof Intl as (typeof Intl)[K] extends new (...args: any) => any\n ? K\n : never]: (typeof Intl)[K];\n};\n\n// Type wrapper to replace locale arguments with LocalesValues\ntype ReplaceLocaleWithLocalesValues<T> = T extends new (\n locales: any,\n options?: infer Options\n) => infer Instance\n ? new (locales?: LocalesValues, options?: Options) => Instance\n : T extends new (locales: any) => infer Instance\n ? new (locales?: LocalesValues) => Instance\n : T;\n\n// Wrapped Intl type with LocalesValues\ntype WrappedIntl = {\n [K in keyof typeof Intl]: K extends keyof IntlConstructors\n ? ReplaceLocaleWithLocalesValues<(typeof Intl)[K]>\n : (typeof Intl)[K];\n};\n\n// Generic cache key – JSON.stringify is fine because locale strings are short\n// and option objects are small and deterministic.\nconst cacheKey = (locales: LocalesValues, options: unknown) =>\n JSON.stringify([locales, options]);\n\n// Generic wrapper for any `new Intl.*()` constructor.\n// Returns a constructable function (usable with or without `new`) that\n// pulls instances from a Map cache when possible.\nconst createCachedConstructor = <T extends new (...args: any[]) => any>(\n Ctor: T\n) => {\n const cache = new Map<string, InstanceType<T>>();\n\n function Wrapped(locales?: LocalesValues, options?: any) {\n // Special case – guard older runtimes missing DisplayNames.\n if (\n Ctor.name === 'DisplayNames' &&\n typeof (Intl as any)?.DisplayNames !== 'function'\n ) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `Intl.DisplayNames is not supported; falling back to raw locale (${locales}). ` +\n `Consider adding a polyfill as https://formatjs.io/docs/polyfills/intl-displaynames/`\n );\n }\n return locales as any;\n }\n\n const key = cacheKey(\n locales ?? configuration.internationalization.defaultLocale,\n options\n );\n let instance: InstanceType<T> | undefined = cache.get(key);\n\n if (!instance) {\n instance = new Ctor(locales as never, options as never);\n cache.set(key, instance as InstanceType<T>);\n }\n\n return instance as InstanceType<T>;\n }\n\n // Ensure it behaves like a constructor when used with `new`.\n (Wrapped as any).prototype = (Ctor as any).prototype;\n\n return Wrapped as unknown as ReplaceLocaleWithLocalesValues<T>;\n};\n\n// Factory that turns the global `Intl` into a cached clone.\nexport const createCachedIntl = (): WrappedIntl =>\n new Proxy(Intl as IntlConstructors, {\n get: (target, prop, receiver) => {\n const value = Reflect.get(target, prop, receiver);\n\n // Wrap *only* constructor functions (safest heuristic: they start with a capital letter).\n return typeof value === 'function' && /^[A-Z]/.test(String(prop))\n ? createCachedConstructor(value)\n : value;\n },\n }) as unknown as WrappedIntl;\n\n// Singleton – import this in application code if you just want shared caches.\nconst CachedIntl = createCachedIntl();\n\n// new CachedIntl.DisplayNames(Locales.FRENCH, { type: 'language' });\n// new CachedIntl.DisplayNames('fr', { type: 'language' });\n// new CachedIntl.DateTimeFormat('fr', {\n// year: 'numeric',\n// month: 'long',\n// day: 'numeric',\n// });\n// new CachedIntl.NumberFormat('fr', {\n// style: 'currency',\n// currency: 'EUR',\n// });\n// new CachedIntl.Collator('fr', { sensitivity: 'base' });\n// new CachedIntl.PluralRules('fr');\n// new CachedIntl.RelativeTimeFormat('fr', { numeric: 'auto' });\n// new CachedIntl.ListFormat('fr', { type: 'conjunction' });\n\nexport { CachedIntl as Intl };\n"],"mappings":"AAyBA,OAAO,mBAAmB;AA8B1B,MAAM,WAAW,CAAC,SAAwB,YACxC,KAAK,UAAU,CAAC,SAAS,OAAO,CAAC;AAKnC,MAAM,0BAA0B,CAC9B,SACG;AACH,QAAM,QAAQ,oBAAI,IAA6B;AAE/C,WAAS,QAAQ,SAAyB,SAAe;AAEvD,QACE,KAAK,SAAS,kBACd,OAAQ,MAAc,iBAAiB,YACvC;AACA,UAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,gBAAQ;AAAA,UACN,mEAAmE,OAAO;AAAA,QAE5E;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,UAAM,MAAM;AAAA,MACV,WAAW,cAAc,qBAAqB;AAAA,MAC9C;AAAA,IACF;AACA,QAAI,WAAwC,MAAM,IAAI,GAAG;AAEzD,QAAI,CAAC,UAAU;AACb,iBAAW,IAAI,KAAK,SAAkB,OAAgB;AACtD,YAAM,IAAI,KAAK,QAA2B;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAGA,EAAC,QAAgB,YAAa,KAAa;AAE3C,SAAO;AACT;AAGO,MAAM,mBAAmB,MAC9B,IAAI,MAAM,MAA0B;AAAA,EAClC,KAAK,CAAC,QAAQ,MAAM,aAAa;AAC/B,UAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAGhD,WAAO,OAAO,UAAU,cAAc,SAAS,KAAK,OAAO,IAAI,CAAC,IAC5D,wBAAwB,KAAK,IAC7B;AAAA,EACN;AACF,CAAC;AAGH,MAAM,aAAa,iBAAiB;","names":[]}
@@ -0,0 +1,16 @@
1
+ import { LocalesValues } from '@intlayer/config/client';
2
+ /**
3
+ * Formats a numeric value using compact notation (e.g., 1K, 1M, 1B)
4
+ * based on locale and formatting options.
5
+ *
6
+ * @example
7
+ * compact({ value: 1200 }); // "1.2K"
8
+ *
9
+ * @example
10
+ * compact({ value: "1000000", locale: Locales.FRENCH, compactDisplay: "long" });
11
+ * // "1 million"
12
+ */
13
+ export declare const compact: (value: string | number, options?: Intl.NumberFormatOptions & {
14
+ locale?: LocalesValues;
15
+ }) => string;
16
+ //# sourceMappingURL=compact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../../src/formatters/compact.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,GAClB,OAAO,MAAM,GAAG,MAAM,EACtB,UAAU,IAAI,CAAC,mBAAmB,GAAG;IAAE,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,KAC9D,MAOsB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type LocalesValues } from '@intlayer/config/client';
2
+ /**
3
+ * Formats a numeric or string value into a localized currency string using the Intl API.
4
+ *
5
+ * @example
6
+ * currency({ value: 1234.5, currency: 'EUR' });
7
+ * // "€1,234.50"
8
+ *
9
+ * @example
10
+ * currency({ value: "5000", locale: Locales.FRENCH, currency: "CAD", currencyDisplay: "code" });
11
+ * // "5 000,00 CAD"
12
+ */
13
+ export declare const currency: (value: string | number, options?: Intl.NumberFormatOptions & {
14
+ locale?: LocalesValues;
15
+ }) => string;
16
+ //# sourceMappingURL=currency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currency.d.ts","sourceRoot":"","sources":["../../../src/formatters/currency.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,GACnB,OAAO,MAAM,GAAG,MAAM,EACtB,UAAU,IAAI,CAAC,mBAAmB,GAAG;IAAE,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,KAC9D,MAWsB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type LocalesValues } from '@intlayer/config/client';
2
+ /**
3
+ * Formats a date/time value into a localized string using Intl.DateTimeFormat.
4
+ *
5
+ * @example
6
+ * date({ date: new Date(), options: "short" });
7
+ * // "08/02/25, 14:30"
8
+ *
9
+ * @example
10
+ * date({ date: "2025-08-02T14:30:00Z", locale: Locales.FRENCH, options: { month: "long", day: "numeric" } });
11
+ * // "2 août"
12
+ */
13
+ export declare const date: (date: Date | string | number, options?: Intl.DateTimeFormatOptions & {
14
+ locale?: LocalesValues;
15
+ }) => string;
16
+ //# sourceMappingURL=date.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../../src/formatters/date.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAwC7D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,GACf,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,EAC5B,UAAU,IAAI,CAAC,qBAAqB,GAAG;IAAE,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,KAChE,MAYF,CAAC"}
@@ -0,0 +1,9 @@
1
+ export * from './compact';
2
+ export * from './currency';
3
+ export * from './date';
4
+ export * from './list';
5
+ export * from './number';
6
+ export * from './percentage';
7
+ export * from './relativeTime';
8
+ export * from './units';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/formatters/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type LocalesValues } from '@intlayer/config/client';
2
+ /**
3
+ * Formats an array of values into a localized list string using the Intl API.
4
+ *
5
+ * @example
6
+ * list(['apple', 'banana', 'orange']);
7
+ * // "apple, banana, and orange"
8
+ *
9
+ * @example
10
+ * list(['red', 'green', 'blue'], { locale: Locales.FRENCH, type: 'disjunction' });
11
+ * // "rouge, vert ou bleu"
12
+ *
13
+ * @example
14
+ * list([1, 2, 3], { type: 'unit' });
15
+ * // "1, 2, 3"
16
+ */
17
+ export declare const list: (values: (string | number)[], options?: Intl.ListFormatOptions & {
18
+ locale?: LocalesValues;
19
+ }) => string;
20
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/formatters/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,IAAI,GACf,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAC3B,UAAU,IAAI,CAAC,iBAAiB,GAAG;IAAE,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,KAC5D,MAQ2B,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type LocalesValues } from '@intlayer/config/client';
2
+ /**
3
+ * Formats a numeric value using locale-aware formatting.
4
+ *
5
+ * @example
6
+ * number({ value: 123456.789 }); // "123,456.789"
7
+ * number({ value: "1000000", locale: Locales.FRENCH }); // "1 000 000"
8
+ */
9
+ export declare const number: (value: string | number, options?: Intl.NumberFormatOptions & {
10
+ locale?: LocalesValues;
11
+ }) => string;
12
+ //# sourceMappingURL=number.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number.d.ts","sourceRoot":"","sources":["../../../src/formatters/number.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,GACjB,OAAO,MAAM,GAAG,MAAM,EACtB,UAAU,IAAI,CAAC,mBAAmB,GAAG;IAAE,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,KAC9D,MAIsB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type LocalesValues } from '@intlayer/config/client';
2
+ /**
3
+ * Formats a number as a percentage string (e.g., 0.25 → "25%").
4
+ *
5
+ * @example
6
+ * percentage({ value: 0.25 }) // "25%"
7
+ * percentage({ value: 0.25, minimumFractionDigits: 2 }) // "25.00%"
8
+ */
9
+ export declare const percentage: (value: string | number, options?: Intl.NumberFormatOptions & {
10
+ locale?: LocalesValues;
11
+ }) => string;
12
+ //# sourceMappingURL=percentage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"percentage.d.ts","sourceRoot":"","sources":["../../../src/formatters/percentage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GACrB,OAAO,MAAM,GAAG,MAAM,EACtB,UAAU,IAAI,CAAC,mBAAmB,GAAG;IAAE,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,KAC9D,MAiBF,CAAC"}