@intlayer/lingui 8.12.5-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 (60) hide show
  1. package/README.md +330 -0
  2. package/dist/cjs/I18nClass.cjs +127 -0
  3. package/dist/cjs/I18nClass.cjs.map +1 -0
  4. package/dist/cjs/I18nProvider.cjs +64 -0
  5. package/dist/cjs/I18nProvider.cjs.map +1 -0
  6. package/dist/cjs/LinguiContext.cjs +23 -0
  7. package/dist/cjs/LinguiContext.cjs.map +1 -0
  8. package/dist/cjs/Trans.cjs +71 -0
  9. package/dist/cjs/Trans.cjs.map +1 -0
  10. package/dist/cjs/_virtual/_rolldown/runtime.cjs +29 -0
  11. package/dist/cjs/eventEmitter.cjs +37 -0
  12. package/dist/cjs/eventEmitter.cjs.map +1 -0
  13. package/dist/cjs/formats.cjs +66 -0
  14. package/dist/cjs/formats.cjs.map +1 -0
  15. package/dist/cjs/index.cjs +19 -0
  16. package/dist/cjs/plugin/index.cjs +64 -0
  17. package/dist/cjs/plugin/index.cjs.map +1 -0
  18. package/dist/cjs/setupI18n.cjs +33 -0
  19. package/dist/cjs/setupI18n.cjs.map +1 -0
  20. package/dist/cjs/useLingui.cjs +40 -0
  21. package/dist/cjs/useLingui.cjs.map +1 -0
  22. package/dist/esm/I18nClass.mjs +126 -0
  23. package/dist/esm/I18nClass.mjs.map +1 -0
  24. package/dist/esm/I18nProvider.mjs +63 -0
  25. package/dist/esm/I18nProvider.mjs.map +1 -0
  26. package/dist/esm/LinguiContext.mjs +22 -0
  27. package/dist/esm/LinguiContext.mjs.map +1 -0
  28. package/dist/esm/Trans.mjs +70 -0
  29. package/dist/esm/Trans.mjs.map +1 -0
  30. package/dist/esm/eventEmitter.mjs +35 -0
  31. package/dist/esm/eventEmitter.mjs.map +1 -0
  32. package/dist/esm/formats.mjs +64 -0
  33. package/dist/esm/formats.mjs.map +1 -0
  34. package/dist/esm/index.mjs +11 -0
  35. package/dist/esm/plugin/index.mjs +60 -0
  36. package/dist/esm/plugin/index.mjs.map +1 -0
  37. package/dist/esm/setupI18n.mjs +31 -0
  38. package/dist/esm/setupI18n.mjs.map +1 -0
  39. package/dist/esm/useLingui.mjs +39 -0
  40. package/dist/esm/useLingui.mjs.map +1 -0
  41. package/dist/types/I18nClass.d.ts +92 -0
  42. package/dist/types/I18nClass.d.ts.map +1 -0
  43. package/dist/types/I18nProvider.d.ts +39 -0
  44. package/dist/types/I18nProvider.d.ts.map +1 -0
  45. package/dist/types/LinguiContext.d.ts +21 -0
  46. package/dist/types/LinguiContext.d.ts.map +1 -0
  47. package/dist/types/Trans.d.ts +38 -0
  48. package/dist/types/Trans.d.ts.map +1 -0
  49. package/dist/types/eventEmitter.d.ts +24 -0
  50. package/dist/types/eventEmitter.d.ts.map +1 -0
  51. package/dist/types/formats.d.ts +32 -0
  52. package/dist/types/formats.d.ts.map +1 -0
  53. package/dist/types/index.d.ts +10 -0
  54. package/dist/types/plugin/index.d.ts +25 -0
  55. package/dist/types/plugin/index.d.ts.map +1 -0
  56. package/dist/types/setupI18n.d.ts +37 -0
  57. package/dist/types/setupI18n.d.ts.map +1 -0
  58. package/dist/types/useLingui.d.ts +21 -0
  59. package/dist/types/useLingui.d.ts.map +1 -0
  60. package/package.json +115 -0
@@ -0,0 +1,71 @@
1
+ 'use client';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+ const require_useLingui = require('./useLingui.cjs');
5
+ let _intlayer_core_messageFormat = require("@intlayer/core/messageFormat");
6
+ let react = require("react");
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
+
9
+ //#region src/Trans.tsx
10
+ /** Maps tagged tokens to React nodes using a components record (numbered or named). */
11
+ const renderTaggedTokens = (tokens, components) => tokens.map((token, tokenIndex) => {
12
+ if (typeof token === "string") return token;
13
+ const children = renderTaggedTokens(token.children, components);
14
+ const component = components[token.tag];
15
+ if (component === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children }, tokenIndex);
16
+ if (typeof component === "function") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: component(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children })) }, tokenIndex);
17
+ if (typeof component === "object" && component !== null && "type" in component) {
18
+ const { type: TagComponent, props: tagProps } = component;
19
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TagComponent, {
20
+ ...tagProps,
21
+ children
22
+ }, tokenIndex);
23
+ }
24
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children }, tokenIndex);
25
+ });
26
+ /**
27
+ * Drop-in for `@lingui/react`'s `<Trans>`.
28
+ *
29
+ * Looks up the message `id` in the `messages` intlayer dictionary and renders
30
+ * the result. When `components` is provided, named tags in the translated
31
+ * string are mapped to React elements (uses `parseTaggedMessage` from
32
+ * `@intlayer/core`).
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * // Simple message
37
+ * <Trans id="home.title" message="Welcome" />
38
+ *
39
+ * // Rich text with components
40
+ * <Trans
41
+ * id="legal.terms"
42
+ * message="I agree to the <link>terms</link>"
43
+ * components={{ link: <a href="/terms" /> }}
44
+ * />
45
+ * ```
46
+ */
47
+ const Trans = ({ id, message, values, components, formats: _formats, comment: _comment, render, component: WrapperComponent }) => {
48
+ const { i18n, defaultComponent: DefaultComponent } = require_useLingui.useLingui();
49
+ const translation = i18n._(id, values ?? {}, { message });
50
+ const hasComponents = components && Object.keys(components).length > 0;
51
+ let content;
52
+ if (hasComponents) content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: renderTaggedTokens((0, _intlayer_core_messageFormat.parseTaggedMessage)(translation), components) });
53
+ else content = translation;
54
+ const renderProps = {
55
+ id,
56
+ translation: content,
57
+ children: content,
58
+ message: message ?? null
59
+ };
60
+ if (typeof render === "function") return render(renderProps);
61
+ const Wrapper = WrapperComponent ?? DefaultComponent;
62
+ if (Wrapper) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Wrapper, {
63
+ ...renderProps,
64
+ children: content
65
+ });
66
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: content });
67
+ };
68
+
69
+ //#endregion
70
+ exports.Trans = Trans;
71
+ //# sourceMappingURL=Trans.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Trans.cjs","names":["Fragment","useLingui"],"sources":["../../src/Trans.tsx"],"sourcesContent":["'use client';\n\nimport {\n parseTaggedMessage,\n type TaggedMessageToken,\n} from '@intlayer/core/messageFormat';\nimport type { MessageId } from '@lingui/core';\nimport type { TransProps, TransRenderProps } from '@lingui/react';\nimport {\n type ComponentType,\n Fragment,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { useLingui } from './useLingui';\n\ntype RichRenderer = (...args: unknown[]) => ReactNode;\n\n/** Maps tagged tokens to React nodes using a components record (numbered or named). */\nconst renderTaggedTokens = (\n tokens: TaggedMessageToken[],\n components: Record<\n string,\n ComponentType<Record<string, unknown>> | ReactElement | unknown\n >\n): ReactNode[] =>\n tokens.map((token, tokenIndex) => {\n if (typeof token === 'string') return token;\n const children = renderTaggedTokens(token.children, components);\n const component = components[token.tag];\n if (component === undefined) {\n return <Fragment key={tokenIndex}>{children}</Fragment>;\n }\n if (typeof component === 'function') {\n return (\n <Fragment key={tokenIndex}>\n {(component as RichRenderer)(<>{children}</>)}\n </Fragment>\n );\n }\n if (\n typeof component === 'object' &&\n component !== null &&\n 'type' in component\n ) {\n const { type: TagComponent, props: tagProps } = component as ReactElement;\n return (\n <TagComponent\n key={tokenIndex}\n {...(tagProps as Record<string, unknown>)}\n >\n {children}\n </TagComponent>\n );\n }\n return <Fragment key={tokenIndex}>{children}</Fragment>;\n });\n\n/**\n * Drop-in for `@lingui/react`'s `<Trans>`.\n *\n * Looks up the message `id` in the `messages` intlayer dictionary and renders\n * the result. When `components` is provided, named tags in the translated\n * string are mapped to React elements (uses `parseTaggedMessage` from\n * `@intlayer/core`).\n *\n * @example\n * ```tsx\n * // Simple message\n * <Trans id=\"home.title\" message=\"Welcome\" />\n *\n * // Rich text with components\n * <Trans\n * id=\"legal.terms\"\n * message=\"I agree to the <link>terms</link>\"\n * components={{ link: <a href=\"/terms\" /> }}\n * />\n * ```\n */\nexport const Trans = ({\n id,\n message,\n values,\n components,\n formats: _formats,\n comment: _comment,\n render,\n component: WrapperComponent,\n}: TransProps): ReactElement | null => {\n const { i18n, defaultComponent: DefaultComponent } = useLingui();\n\n const translation = i18n._(id as MessageId, values ?? {}, { message });\n const hasComponents = components && Object.keys(components).length > 0;\n\n let content: ReactNode;\n\n if (hasComponents) {\n const tokens = parseTaggedMessage(translation);\n const nodes = renderTaggedTokens(tokens, components);\n content = <>{nodes}</>;\n } else {\n content = translation;\n }\n\n const renderProps: TransRenderProps = {\n id: id as MessageId,\n translation: content,\n children: content,\n message: message ?? null,\n };\n\n if (typeof render === 'function') {\n return render(renderProps);\n }\n\n const Wrapper =\n WrapperComponent ??\n (DefaultComponent as ComponentType<TransRenderProps> | undefined);\n\n if (Wrapper) {\n return <Wrapper {...renderProps}>{content}</Wrapper>;\n }\n\n return <>{content}</>;\n};\n"],"mappings":";;;;;;;;;;AAmBA,MAAM,sBACJ,QACA,eAKA,OAAO,KAAK,OAAO,eAAe;CAChC,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,MAAM,WAAW,mBAAmB,MAAM,UAAU,UAAU;CAC9D,MAAM,YAAY,WAAW,MAAM;CACnC,IAAI,cAAc,QAChB,OAAO,2CAACA,gBAAD,EAA4B,SAAmB,GAAhC,UAAgC;CAExD,IAAI,OAAO,cAAc,YACvB,OACE,2CAACA,gBAAD,YACI,UAA2B,yEAAG,SAAW,EAAC,EACpC,GAFK,UAEL;CAGd,IACE,OAAO,cAAc,YACrB,cAAc,QACd,UAAU,WACV;EACA,MAAM,EAAE,MAAM,cAAc,OAAO,aAAa;EAChD,OACE,2CAAC,cAAD;GAEE,GAAK;GAEJ;EACW,GAJP,UAIO;CAElB;CACA,OAAO,2CAACA,gBAAD,EAA4B,SAAmB,GAAhC,UAAgC;AACxD,CAAC;;;;;;;;;;;;;;;;;;;;;;AAuBH,MAAa,SAAS,EACpB,IACA,SACA,QACA,YACA,SAAS,UACT,SAAS,UACT,QACA,WAAW,uBAC0B;CACrC,MAAM,EAAE,MAAM,kBAAkB,qBAAqBC,4BAAU;CAE/D,MAAM,cAAc,KAAK,EAAE,IAAiB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;CACrE,MAAM,gBAAgB,cAAc,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS;CAErE,IAAI;CAEJ,IAAI,eAGF,UAAU,mFADI,wEADoB,WACI,GAAG,UACxB,EAAI;MAErB,UAAU;CAGZ,MAAM,cAAgC;EAChC;EACJ,aAAa;EACb,UAAU;EACV,SAAS,WAAW;CACtB;CAEA,IAAI,OAAO,WAAW,YACpB,OAAO,OAAO,WAAW;CAG3B,MAAM,UACJ,oBACC;CAEH,IAAI,SACF,OAAO,2CAAC,SAAD;EAAS,GAAI;YAAc;CAAiB;CAGrD,OAAO,mFAAG,QAAU;AACtB"}
@@ -0,0 +1,29 @@
1
+ //#region \0rolldown/runtime.js
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 __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
28
+
29
+ exports.__toESM = __toESM;
@@ -0,0 +1,37 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ //#region src/eventEmitter.ts
4
+ /**
5
+ * Minimal EventEmitter that mirrors `@lingui/core`'s EventEmitter API.
6
+ * Required because we cannot import from `@lingui/core` at runtime
7
+ * (we are its alias) — so we reimplement the base class here.
8
+ */
9
+ var EventEmitter = class {
10
+ _events = /* @__PURE__ */ new Map();
11
+ /**
12
+ * Registers a listener for the given event and returns an unsubscribe function.
13
+ */
14
+ on(event, listener) {
15
+ if (!this._events.has(event)) this._events.set(event, /* @__PURE__ */ new Set());
16
+ this._events.get(event).add(listener);
17
+ return () => this.removeListener(event, listener);
18
+ }
19
+ /**
20
+ * Removes a previously registered listener.
21
+ */
22
+ removeListener(event, listener) {
23
+ this._events.get(event)?.delete(listener);
24
+ }
25
+ /**
26
+ * Emits an event, invoking all registered listeners.
27
+ */
28
+ emit(event, ...args) {
29
+ this._events.get(event)?.forEach((listener) => {
30
+ listener(...args);
31
+ });
32
+ }
33
+ };
34
+
35
+ //#endregion
36
+ exports.EventEmitter = EventEmitter;
37
+ //# sourceMappingURL=eventEmitter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventEmitter.cjs","names":[],"sources":["../../src/eventEmitter.ts"],"sourcesContent":["/**\n * Minimal EventEmitter that mirrors `@lingui/core`'s EventEmitter API.\n * Required because we cannot import from `@lingui/core` at runtime\n * (we are its alias) — so we reimplement the base class here.\n */\nexport class EventEmitter<\n Events extends Record<string, (...args: unknown[]) => void>,\n> {\n private readonly _events: Map<\n keyof Events,\n Set<(...args: unknown[]) => void>\n > = new Map();\n\n /**\n * Registers a listener for the given event and returns an unsubscribe function.\n */\n on<E extends keyof Events>(event: E, listener: Events[E]): () => void {\n if (!this._events.has(event)) {\n this._events.set(event, new Set());\n }\n this._events.get(event)!.add(listener as (...args: unknown[]) => void);\n return () => this.removeListener(event, listener);\n }\n\n /**\n * Removes a previously registered listener.\n */\n removeListener<E extends keyof Events>(event: E, listener: Events[E]): void {\n this._events.get(event)?.delete(listener as (...args: unknown[]) => void);\n }\n\n /**\n * Emits an event, invoking all registered listeners.\n */\n emit<E extends keyof Events>(event: E, ...args: Parameters<Events[E]>): void {\n this._events.get(event)?.forEach((listener) => {\n listener(...(args as unknown[]));\n });\n }\n}\n"],"mappings":";;;;;;;;AAKA,IAAa,eAAb,MAEE;CACA,AAAiB,0BAGb,IAAI,IAAI;;;;CAKZ,GAA2B,OAAU,UAAiC;EACpE,IAAI,CAAC,KAAK,QAAQ,IAAI,KAAK,GACzB,KAAK,QAAQ,IAAI,uBAAO,IAAI,IAAI,CAAC;EAEnC,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAE,IAAI,QAAwC;EACrE,aAAa,KAAK,eAAe,OAAO,QAAQ;CAClD;;;;CAKA,eAAuC,OAAU,UAA2B;EAC1E,KAAK,QAAQ,IAAI,KAAK,CAAC,EAAE,OAAO,QAAwC;CAC1E;;;;CAKA,KAA6B,OAAU,GAAG,MAAmC;EAC3E,KAAK,QAAQ,IAAI,KAAK,CAAC,EAAE,SAAS,aAAa;GAC7C,SAAS,GAAI,IAAkB;EACjC,CAAC;CACH;AACF"}
@@ -0,0 +1,66 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ //#region src/formats.ts
4
+ const SIZE_FORMAT_MAP = {
5
+ short: {
6
+ dateStyle: "short",
7
+ timeStyle: "short"
8
+ },
9
+ default: {
10
+ dateStyle: "medium",
11
+ timeStyle: "medium"
12
+ },
13
+ long: {
14
+ dateStyle: "long",
15
+ timeStyle: "long"
16
+ },
17
+ full: {
18
+ dateStyle: "full",
19
+ timeStyle: "full"
20
+ }
21
+ };
22
+ const toDateObject = (value) => typeof value === "string" ? new Date(value) : new Date(value);
23
+ const resolveLocales = (locales) => locales;
24
+ /**
25
+ * Formats a date value.
26
+ * @deprecated Use `Intl.DateTimeFormat` directly.
27
+ */
28
+ const date = (locales, value, format) => {
29
+ const options = typeof format === "string" ? SIZE_FORMAT_MAP[format] ?? SIZE_FORMAT_MAP.default : format ?? {};
30
+ return new Intl.DateTimeFormat(resolveLocales(locales), options).format(toDateObject(value));
31
+ };
32
+ /**
33
+ * Formats a time value.
34
+ * @deprecated Use `Intl.DateTimeFormat` directly.
35
+ */
36
+ const time = (locales, value, format) => {
37
+ const options = typeof format === "string" ? SIZE_FORMAT_MAP[format] ?? SIZE_FORMAT_MAP.default : format ?? { timeStyle: "medium" };
38
+ return new Intl.DateTimeFormat(resolveLocales(locales), options).format(toDateObject(value));
39
+ };
40
+ /**
41
+ * Formats a number value.
42
+ * @deprecated Use `Intl.NumberFormat` directly.
43
+ */
44
+ const number = (locales, value, format) => new Intl.NumberFormat(resolveLocales(locales), format).format(value);
45
+ /**
46
+ * Selects the correct plural form from a set of plural rules.
47
+ * @deprecated Use `Intl.PluralRules` directly.
48
+ */
49
+ const plural = (locales, ordinal, value, { offset = 0, ...rules }) => {
50
+ const count = value - offset;
51
+ const pluralRule = new Intl.PluralRules(resolveLocales(locales), { type: ordinal ? "ordinal" : "cardinal" }).select(count);
52
+ return rules[String(count)] ?? rules[pluralRule] ?? rules.other;
53
+ };
54
+ /** Default locale used when none is configured. */
55
+ const defaultLocale = "en";
56
+ const formats = {
57
+ date,
58
+ time,
59
+ number,
60
+ plural,
61
+ defaultLocale
62
+ };
63
+
64
+ //#endregion
65
+ exports.formats = formats;
66
+ //# sourceMappingURL=formats.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.cjs","names":[],"sources":["../../src/formats.ts"],"sourcesContent":["/**\n * Reimplementation of `@lingui/core`'s `formats` namespace.\n *\n * These static helpers are deliberately kept independent of any I18n instance\n * so that they can be used without a Provider.\n *\n * @deprecated Use `Intl.*` APIs directly — these helpers will be removed in\n * a future version of lingui.\n */\n\nexport type DateTimeFormatSize = 'short' | 'default' | 'long' | 'full';\nexport type DateTimeFormatValue = Parameters<Intl.DateTimeFormat['format']>[0];\nexport type NumberFormatValue = Parameters<Intl.NumberFormat['format']>[0];\n\nexport type PluralOptions = {\n [key: string]: string | undefined;\n} & {\n offset?: number;\n other: string;\n};\n\nconst SIZE_FORMAT_MAP: Record<DateTimeFormatSize, Intl.DateTimeFormatOptions> =\n {\n short: { dateStyle: 'short', timeStyle: 'short' },\n default: { dateStyle: 'medium', timeStyle: 'medium' },\n long: { dateStyle: 'long', timeStyle: 'long' },\n full: { dateStyle: 'full', timeStyle: 'full' },\n };\n\nconst toDateObject = (value: string | DateTimeFormatValue): Date =>\n typeof value === 'string' ? new Date(value) : new Date(value as number);\n\nconst resolveLocales = (locales: string | string[]): string | string[] =>\n locales;\n\n/**\n * Formats a date value.\n * @deprecated Use `Intl.DateTimeFormat` directly.\n */\nconst date = (\n locales: string | string[],\n value: string | DateTimeFormatValue,\n format?: Intl.DateTimeFormatOptions | DateTimeFormatSize\n): string => {\n const options: Intl.DateTimeFormatOptions =\n typeof format === 'string'\n ? (SIZE_FORMAT_MAP[format] ?? SIZE_FORMAT_MAP.default)\n : (format ?? {});\n return new Intl.DateTimeFormat(resolveLocales(locales), options).format(\n toDateObject(value)\n );\n};\n\n/**\n * Formats a time value.\n * @deprecated Use `Intl.DateTimeFormat` directly.\n */\nconst time = (\n locales: string | string[],\n value: string | DateTimeFormatValue,\n format?: Intl.DateTimeFormatOptions | DateTimeFormatSize\n): string => {\n const options: Intl.DateTimeFormatOptions =\n typeof format === 'string'\n ? (SIZE_FORMAT_MAP[format] ?? SIZE_FORMAT_MAP.default)\n : (format ?? { timeStyle: 'medium' });\n return new Intl.DateTimeFormat(resolveLocales(locales), options).format(\n toDateObject(value)\n );\n};\n\n/**\n * Formats a number value.\n * @deprecated Use `Intl.NumberFormat` directly.\n */\nconst number = (\n locales: string | string[],\n value: NumberFormatValue,\n format?: Intl.NumberFormatOptions\n): string =>\n new Intl.NumberFormat(resolveLocales(locales), format).format(value);\n\n/**\n * Selects the correct plural form from a set of plural rules.\n * @deprecated Use `Intl.PluralRules` directly.\n */\nconst plural = (\n locales: string | string[],\n ordinal: boolean,\n value: number,\n { offset = 0, ...rules }: PluralOptions\n): string => {\n const count = value - offset;\n const pluralRule = new Intl.PluralRules(resolveLocales(locales), {\n type: ordinal ? 'ordinal' : 'cardinal',\n }).select(count);\n return (\n (rules[String(count)] as string | undefined) ??\n (rules[pluralRule] as string | undefined) ??\n rules.other\n );\n};\n\n/** Default locale used when none is configured. */\nconst defaultLocale = 'en';\n\nexport const formats = {\n date,\n time,\n number,\n plural,\n defaultLocale,\n};\n"],"mappings":";;;AAqBA,MAAM,kBACJ;CACE,OAAO;EAAE,WAAW;EAAS,WAAW;CAAQ;CAChD,SAAS;EAAE,WAAW;EAAU,WAAW;CAAS;CACpD,MAAM;EAAE,WAAW;EAAQ,WAAW;CAAO;CAC7C,MAAM;EAAE,WAAW;EAAQ,WAAW;CAAO;AAC/C;AAEF,MAAM,gBAAgB,UACpB,OAAO,UAAU,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAe;AAExE,MAAM,kBAAkB,YACtB;;;;;AAMF,MAAM,QACJ,SACA,OACA,WACW;CACX,MAAM,UACJ,OAAO,WAAW,WACb,gBAAgB,WAAW,gBAAgB,UAC3C,UAAU,CAAC;CAClB,OAAO,IAAI,KAAK,eAAe,eAAe,OAAO,GAAG,OAAO,CAAC,CAAC,OAC/D,aAAa,KAAK,CACpB;AACF;;;;;AAMA,MAAM,QACJ,SACA,OACA,WACW;CACX,MAAM,UACJ,OAAO,WAAW,WACb,gBAAgB,WAAW,gBAAgB,UAC3C,UAAU,EAAE,WAAW,SAAS;CACvC,OAAO,IAAI,KAAK,eAAe,eAAe,OAAO,GAAG,OAAO,CAAC,CAAC,OAC/D,aAAa,KAAK,CACpB;AACF;;;;;AAMA,MAAM,UACJ,SACA,OACA,WAEA,IAAI,KAAK,aAAa,eAAe,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO,KAAK;;;;;AAMrE,MAAM,UACJ,SACA,SACA,OACA,EAAE,SAAS,GAAG,GAAG,YACN;CACX,MAAM,QAAQ,QAAQ;CACtB,MAAM,aAAa,IAAI,KAAK,YAAY,eAAe,OAAO,GAAG,EAC/D,MAAM,UAAU,YAAY,WAC9B,CAAC,CAAC,CAAC,OAAO,KAAK;CACf,OACG,MAAM,OAAO,KAAK,MAClB,MAAM,eACP,MAAM;AAEV;;AAGA,MAAM,gBAAgB;AAEtB,MAAa,UAAU;CACrB;CACA;CACA;CACA;CACA;AACF"}
@@ -0,0 +1,19 @@
1
+ 'use client';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+ const require_I18nClass = require('./I18nClass.cjs');
5
+ const require_LinguiContext = require('./LinguiContext.cjs');
6
+ const require_useLingui = require('./useLingui.cjs');
7
+ const require_formats = require('./formats.cjs');
8
+ const require_I18nProvider = require('./I18nProvider.cjs');
9
+ const require_Trans = require('./Trans.cjs');
10
+ const require_setupI18n = require('./setupI18n.cjs');
11
+
12
+ exports.I18n = require_I18nClass.I18nClass;
13
+ exports.I18nProvider = require_I18nProvider.I18nProvider;
14
+ exports.LinguiContext = require_LinguiContext.LinguiContext;
15
+ exports.Trans = require_Trans.Trans;
16
+ exports.formats = require_formats.formats;
17
+ exports.i18n = require_setupI18n.i18n;
18
+ exports.setupI18n = require_setupI18n.setupI18n;
19
+ exports.useLingui = require_useLingui.useLingui;
@@ -0,0 +1,64 @@
1
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ let node_path = require("node:path");
4
+ let _intlayer_chokidar_utils = require("@intlayer/chokidar/utils");
5
+ let _intlayer_config_colors = require("@intlayer/config/colors");
6
+ _intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
7
+ let _intlayer_config_logger = require("@intlayer/config/logger");
8
+ let _intlayer_config_node = require("@intlayer/config/node");
9
+ let vite_intlayer = require("vite-intlayer");
10
+
11
+ //#region src/plugin/index.ts
12
+ /**
13
+ * Caller configurations for lingui.
14
+ *
15
+ * Lingui's `i18n._(id)` / `i18n.t` and `useLingui()`'s `_()` all resolve
16
+ * translations at runtime through the intlayer `messages` dictionary. Since the
17
+ * mapping is 1:1 (one catalog → one `messages` dict) there is no namespace
18
+ * splitting needed at the analyser level, so the caller list is empty for now.
19
+ *
20
+ * Future: once `namespace: { from: 'self' }` is supported in the babel/swc
21
+ * analyser, we can add callers for `useLingui()._(id)`.
22
+ */
23
+ const LINGUI_COMPAT_CALLERS = [];
24
+ /**
25
+ * A Vite plugin for the lingui compat adapter.
26
+ *
27
+ * Wraps `vite-intlayer` and adds resolve aliases so that both
28
+ * `@lingui/core` **and** `@lingui/react` are redirected to
29
+ * `@intlayer/lingui` at bundle time.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * // vite.config.ts
34
+ * import { linguiVitePlugin } from '@intlayer/lingui/plugin';
35
+ *
36
+ * export default defineConfig({
37
+ * plugins: [linguiVitePlugin()],
38
+ * });
39
+ * ```
40
+ */
41
+ const linguiVitePlugin = (options) => {
42
+ const intlayerConfig = (0, _intlayer_config_node.getConfiguration)();
43
+ const appLogger = (0, _intlayer_config_logger.getAppLogger)(intlayerConfig);
44
+ (0, _intlayer_chokidar_utils.runOnce)((0, node_path.join)(intlayerConfig.system.baseDir, ".intlayer", "cache", "intlayer-issues-invitation.lock"), () => {
45
+ appLogger([(0, _intlayer_config_logger.colorize)("Please report any issues you met on GitHub:", _intlayer_config_colors.GREY), (0, _intlayer_config_logger.colorize)("https://github.com/aymericzip/intlayer/issues", _intlayer_config_colors.GREY_LIGHT)]);
46
+ }, { cacheTimeoutMs: 1e3 * 60 * 60 });
47
+ const basePlugins = (0, vite_intlayer.intlayer)({
48
+ ...options,
49
+ compatCallers: [...options?.compatCallers ?? [], ...LINGUI_COMPAT_CALLERS]
50
+ });
51
+ const compatPlugin = {
52
+ name: "vite-lingui-compat-plugin",
53
+ config: () => ({ resolve: { alias: {
54
+ "@lingui/core": "@intlayer/lingui",
55
+ "@lingui/react": "@intlayer/lingui"
56
+ } } })
57
+ };
58
+ return [...Array.isArray(basePlugins) ? basePlugins : [basePlugins], compatPlugin];
59
+ };
60
+
61
+ //#endregion
62
+ exports.default = linguiVitePlugin;
63
+ exports.linguiVitePlugin = linguiVitePlugin;
64
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["ANSIColors"],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { runOnce } from '@intlayer/chokidar/utils';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { PluginOption } from 'vite';\nimport { type CompatCallerConfig, intlayer } from 'vite-intlayer';\n\n/**\n * Caller configurations for lingui.\n *\n * Lingui's `i18n._(id)` / `i18n.t` and `useLingui()`'s `_()` all resolve\n * translations at runtime through the intlayer `messages` dictionary. Since the\n * mapping is 1:1 (one catalog → one `messages` dict) there is no namespace\n * splitting needed at the analyser level, so the caller list is empty for now.\n *\n * Future: once `namespace: { from: 'self' }` is supported in the babel/swc\n * analyser, we can add callers for `useLingui()._(id)`.\n */\nconst LINGUI_COMPAT_CALLERS: CompatCallerConfig[] = [];\n\n/**\n * A Vite plugin for the lingui compat adapter.\n *\n * Wraps `vite-intlayer` and adds resolve aliases so that both\n * `@lingui/core` **and** `@lingui/react` are redirected to\n * `@intlayer/lingui` at bundle time.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { linguiVitePlugin } from '@intlayer/lingui/plugin';\n *\n * export default defineConfig({\n * plugins: [linguiVitePlugin()],\n * });\n * ```\n */\nexport const linguiVitePlugin = (\n options?: Parameters<typeof intlayer>[0]\n): PluginOption[] => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig.system.baseDir,\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const basePlugins = intlayer({\n ...options,\n compatCallers: [\n ...(options?.compatCallers ?? []),\n ...LINGUI_COMPAT_CALLERS,\n ],\n });\n\n const compatPlugin: PluginOption = {\n name: 'vite-lingui-compat-plugin',\n config: () => ({\n resolve: {\n alias: {\n '@lingui/core': '@intlayer/lingui',\n '@lingui/react': '@intlayer/lingui',\n },\n },\n }),\n };\n\n return [\n ...(Array.isArray(basePlugins) ? basePlugins : [basePlugins]),\n compatPlugin,\n ];\n};\n\nexport default linguiVitePlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAmBA,MAAM,wBAA8C,CAAC;;;;;;;;;;;;;;;;;;AAmBrD,MAAa,oBACX,YACmB;CACnB,MAAM,6DAAkC;CACxC,MAAM,sDAAyB,cAAc;CAE7C,0DAEI,eAAe,OAAO,SACtB,aACA,SACA,iCACF,SACM;EACJ,UAAU,uCAEN,+CACAA,wBAAW,IACb,yCAEE,iDACAA,wBAAW,UACb,CACF,CAAC;CACH,GACA,EACE,gBAAgB,MAAO,KAAK,GAC9B,CACF;CAEA,MAAM,0CAAuB;EAC3B,GAAG;EACH,eAAe,CACb,GAAI,SAAS,iBAAiB,CAAC,GAC/B,GAAG,qBACL;CACF,CAAC;CAED,MAAM,eAA6B;EACjC,MAAM;EACN,eAAe,EACb,SAAS,EACP,OAAO;GACL,gBAAgB;GAChB,iBAAiB;EACnB,EACF,EACF;CACF;CAEA,OAAO,CACL,GAAI,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,WAAW,GAC3D,YACF;AACF"}
@@ -0,0 +1,33 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_I18nClass = require('./I18nClass.cjs');
3
+
4
+ //#region src/setupI18n.ts
5
+ /**
6
+ * Drop-in for `@lingui/core`'s `setupI18n`.
7
+ *
8
+ * Creates a new intlayer-backed `I18n` instance. The `messages` and
9
+ * `missing` properties from `params` are accepted for API compatibility
10
+ * but are ignored — messages are served by intlayer's compiled dictionaries.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { setupI18n } from '@lingui/core';
15
+ *
16
+ * const i18n = setupI18n({ locale: 'en' });
17
+ * i18n.activate('fr');
18
+ * ```
19
+ */
20
+ const setupI18n = (params) => new require_I18nClass.I18nClass(params);
21
+ /**
22
+ * Global `i18n` singleton — drop-in for `@lingui/core`'s `i18n`.
23
+ *
24
+ * Call `i18n.activate(locale)` to set the active locale before rendering.
25
+ * In React apps, prefer using `useLingui()` inside components so that
26
+ * locale updates are handled reactively via `I18nProvider`.
27
+ */
28
+ const i18n = setupI18n({ locale: "en" });
29
+
30
+ //#endregion
31
+ exports.i18n = i18n;
32
+ exports.setupI18n = setupI18n;
33
+ //# sourceMappingURL=setupI18n.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupI18n.cjs","names":["I18nClass"],"sources":["../../src/setupI18n.ts"],"sourcesContent":["import type { AllMessages, I18n, Locale, Locales } from '@lingui/core';\nimport { I18nClass } from './I18nClass';\n\n/** Mirrors the unexported `I18nProps` type from `@lingui/core`. */\ntype I18nProps = {\n locale?: Locale;\n locales?: Locales;\n messages?: AllMessages;\n missing?: string | ((locale: string, id: string) => string);\n};\n\n/**\n * Drop-in for `@lingui/core`'s `setupI18n`.\n *\n * Creates a new intlayer-backed `I18n` instance. The `messages` and\n * `missing` properties from `params` are accepted for API compatibility\n * but are ignored — messages are served by intlayer's compiled dictionaries.\n *\n * @example\n * ```ts\n * import { setupI18n } from '@lingui/core';\n *\n * const i18n = setupI18n({ locale: 'en' });\n * i18n.activate('fr');\n * ```\n */\nexport const setupI18n = (params?: I18nProps): I18n =>\n new I18nClass(params) as unknown as I18n;\n\n/**\n * Global `i18n` singleton — drop-in for `@lingui/core`'s `i18n`.\n *\n * Call `i18n.activate(locale)` to set the active locale before rendering.\n * In React apps, prefer using `useLingui()` inside components so that\n * locale updates are handled reactively via `I18nProvider`.\n */\nexport const i18n: I18n = setupI18n({ locale: 'en' });\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA0BA,MAAa,aAAa,WACxB,IAAIA,4BAAU,MAAM;;;;;;;;AAStB,MAAa,OAAa,UAAU,EAAE,QAAQ,KAAK,CAAC"}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+ const require_I18nClass = require('./I18nClass.cjs');
5
+ const require_LinguiContext = require('./LinguiContext.cjs');
6
+ let react = require("react");
7
+ let react_intlayer = require("react-intlayer");
8
+
9
+ //#region src/useLingui.ts
10
+ /**
11
+ * Drop-in for `@lingui/react`'s `useLingui`.
12
+ *
13
+ * Returns `{ i18n, _, defaultComponent }` from the nearest `I18nProvider`.
14
+ * When used outside a provider, derives a locale-aware `i18n` instance from
15
+ * `react-intlayer`'s `useLocale()` so that Server Components and test contexts
16
+ * work without an explicit provider.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * const { _ } = useLingui();
21
+ * return <h1>{_({ id: 'home.title', message: 'Welcome' })}</h1>;
22
+ * ```
23
+ */
24
+ const useLingui = () => {
25
+ const context = (0, react.useContext)(require_LinguiContext.LinguiContext);
26
+ const { locale } = (0, react_intlayer.useLocale)();
27
+ const derivedI18n = (0, react.useMemo)(() => {
28
+ const instance = new require_I18nClass.I18nClass({ locale });
29
+ return {
30
+ i18n: instance,
31
+ _: instance._.bind(instance)
32
+ };
33
+ }, [locale]);
34
+ if (context) return context;
35
+ return derivedI18n;
36
+ };
37
+
38
+ //#endregion
39
+ exports.useLingui = useLingui;
40
+ //# sourceMappingURL=useLingui.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLingui.cjs","names":["LinguiContext","I18nClass"],"sources":["../../src/useLingui.ts"],"sourcesContent":["'use client';\n\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { I18nContext } from '@lingui/react';\nimport { useContext, useMemo } from 'react';\nimport { useLocale } from 'react-intlayer';\nimport { I18nClass } from './I18nClass';\nimport { LinguiContext } from './LinguiContext';\n\n/**\n * Drop-in for `@lingui/react`'s `useLingui`.\n *\n * Returns `{ i18n, _, defaultComponent }` from the nearest `I18nProvider`.\n * When used outside a provider, derives a locale-aware `i18n` instance from\n * `react-intlayer`'s `useLocale()` so that Server Components and test contexts\n * work without an explicit provider.\n *\n * @example\n * ```tsx\n * const { _ } = useLingui();\n * return <h1>{_({ id: 'home.title', message: 'Welcome' })}</h1>;\n * ```\n */\nexport const useLingui = (): I18nContext => {\n const context = useContext(LinguiContext);\n const { locale } = useLocale();\n\n const derivedI18n = useMemo(() => {\n const instance = new I18nClass({ locale: locale as string });\n return {\n i18n: instance as unknown as I18nContext['i18n'],\n _: instance._.bind(instance) as I18nContext['_'],\n };\n }, [locale]);\n\n if (context) {\n return context;\n }\n\n return derivedI18n as I18nContext;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,kBAA+B;CAC1C,MAAM,gCAAqBA,mCAAa;CACxC,MAAM,EAAE,yCAAqB;CAE7B,MAAM,uCAA4B;EAChC,MAAM,WAAW,IAAIC,4BAAU,EAAU,OAAiB,CAAC;EAC3D,OAAO;GACL,MAAM;GACN,GAAG,SAAS,EAAE,KAAK,QAAQ;EAC7B;CACF,GAAG,CAAC,MAAM,CAAC;CAEX,IAAI,SACF,OAAO;CAGT,OAAO;AACT"}
@@ -0,0 +1,126 @@
1
+ import { EventEmitter } from "./eventEmitter.mjs";
2
+ import { getIntlayer } from "@intlayer/core/interpreter";
3
+ import { resolveMessage } from "@intlayer/core/messageFormat";
4
+
5
+ //#region src/I18nClass.ts
6
+ /**
7
+ * Navigates a nested object by a dot-separated path.
8
+ *
9
+ * Example: `navigatePath({home: {title: 'Hello'}}, 'home.title')` → `'Hello'`
10
+ */
11
+ const navigatePath = (object, path) => {
12
+ if (!path) return object;
13
+ const parts = path.split(".");
14
+ let current = object;
15
+ for (const part of parts) {
16
+ if (current === null || current === void 0 || typeof current !== "object") return;
17
+ current = current[part];
18
+ }
19
+ return current;
20
+ };
21
+ /**
22
+ * Looks up a lingui message from the `messages` intlayer dictionary.
23
+ *
24
+ * The entire lingui catalog is stored in a single `messages` dictionary.
25
+ * Dotted IDs (e.g. `'home.title'`) are resolved as nested paths within that
26
+ * dictionary. Hash-style IDs (no dots) are direct top-level keys.
27
+ */
28
+ const lookupMessage = (id, locale) => {
29
+ try {
30
+ const value = navigatePath(getIntlayer("messages", locale), id);
31
+ return typeof value === "string" ? value : void 0;
32
+ } catch {
33
+ return;
34
+ }
35
+ };
36
+ /**
37
+ * Intlayer-backed implementation of `@lingui/core`'s `I18n` class.
38
+ *
39
+ * - Messages are read from the `messages` intlayer dictionary.
40
+ * - ICU MessageFormat syntax is resolved via `@intlayer/core/messageFormat`.
41
+ * - `load()` / `loadAndActivate()` / `setMessagesCompiler()` are no-ops —
42
+ * messages are served by intlayer's compiled dictionaries.
43
+ * - `activate(locale)` emits `'change'` so that React consumers re-render.
44
+ */
45
+ var I18nClass = class extends EventEmitter {
46
+ _locale;
47
+ _locales;
48
+ constructor({ locale = "en", locales } = {}) {
49
+ super();
50
+ this._locale = typeof locale === "string" ? locale : "en";
51
+ this._locales = locales;
52
+ }
53
+ get locale() {
54
+ return this._locale;
55
+ }
56
+ get locales() {
57
+ return this._locales;
58
+ }
59
+ get messages() {
60
+ try {
61
+ return getIntlayer("messages", this._locale);
62
+ } catch {
63
+ return {};
64
+ }
65
+ }
66
+ /**
67
+ * No-op: intlayer handles message compilation at build time.
68
+ */
69
+ setMessagesCompiler(_compiler) {
70
+ console.warn("@intlayer/lingui: i18n.setMessagesCompiler() is a no-op — message compilation is handled at build time by intlayer.");
71
+ return this;
72
+ }
73
+ /**
74
+ * No-op: messages are loaded automatically via intlayer dictionaries.
75
+ */
76
+ load(_localeOrAll, _messages) {
77
+ console.warn("@intlayer/lingui: i18n.load() is a no-op — messages are loaded automatically via intlayer dictionaries.");
78
+ }
79
+ /**
80
+ * Activates the given locale (emits `'change'`).
81
+ * The `messages` argument is ignored — intlayer handles the catalog.
82
+ */
83
+ loadAndActivate({ locale, locales }) {
84
+ this.activate(locale, locales);
85
+ }
86
+ /**
87
+ * Sets the active locale and emits `'change'` to notify React consumers.
88
+ */
89
+ activate(locale, locales) {
90
+ this._locale = locale;
91
+ this._locales = locales;
92
+ this.emit("change");
93
+ }
94
+ _(descriptorOrId, values, options) {
95
+ const isDescriptor = typeof descriptorOrId === "object" && descriptorOrId !== null;
96
+ const id = isDescriptor ? descriptorOrId.id : descriptorOrId;
97
+ const defaultMessage = isDescriptor ? descriptorOrId.message ?? options?.message : options?.message;
98
+ const resolvedValues = isDescriptor ? {
99
+ ...descriptorOrId.values ?? {},
100
+ ...values ?? {}
101
+ } : values ?? {};
102
+ return resolveMessage(lookupMessage(id, this._locale) ?? defaultMessage ?? id, resolvedValues, this._locale, "icu") ?? id;
103
+ }
104
+ /**
105
+ * Alias for `_`. Provided for lingui API compatibility.
106
+ */
107
+ t = (descriptorOrId, values, options) => this._(descriptorOrId, values, options);
108
+ /**
109
+ * @deprecated Use `Intl.DateTimeFormat` directly.
110
+ */
111
+ date(value, format) {
112
+ if (value === void 0 || value === null) return "";
113
+ const dateValue = value instanceof Date ? value : new Date(typeof value === "string" ? value : value);
114
+ return new Intl.DateTimeFormat(this._locale, format).format(dateValue);
115
+ }
116
+ /**
117
+ * @deprecated Use `Intl.NumberFormat` directly.
118
+ */
119
+ number(value, format) {
120
+ return new Intl.NumberFormat(this._locale, format).format(value);
121
+ }
122
+ };
123
+
124
+ //#endregion
125
+ export { I18nClass };
126
+ //# sourceMappingURL=I18nClass.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"I18nClass.mjs","names":[],"sources":["../../src/I18nClass.ts"],"sourcesContent":["import { getIntlayer } from '@intlayer/core/interpreter';\nimport { resolveMessage } from '@intlayer/core/messageFormat';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n AllMessages,\n Locale,\n Locales,\n MessageDescriptor,\n MessageId,\n MessageOptions,\n Messages,\n} from '@lingui/core';\nimport { EventEmitter } from './eventEmitter';\n\n/** Mirrors the unexported `Values` type from `@lingui/core`. */\ntype Values = Record<string, unknown>;\n\n/** Mirrors the unexported `MessageCompiler` type from `@lingui/core`. */\ntype MessageCompiler = (message: string) => unknown;\n\n/** Mirrors the unexported `Events` type from `@lingui/core`. */\ntype LinguiEvents = {\n change: () => void;\n missing: (event: { locale: Locale; id: MessageId }) => void;\n};\n\n/** Mirrors the unexported `I18nProps` type from `@lingui/core`. */\ntype I18nProps = {\n locale?: Locale;\n locales?: Locales;\n messages?: AllMessages;\n missing?: string | ((locale: string, id: string) => string);\n};\n\n/**\n * Navigates a nested object by a dot-separated path.\n *\n * Example: `navigatePath({home: {title: 'Hello'}}, 'home.title')` → `'Hello'`\n */\nconst navigatePath = (object: unknown, path: string): unknown => {\n if (!path) return object;\n const parts = path.split('.');\n let current: unknown = object;\n for (const part of parts) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/**\n * Looks up a lingui message from the `messages` intlayer dictionary.\n *\n * The entire lingui catalog is stored in a single `messages` dictionary.\n * Dotted IDs (e.g. `'home.title'`) are resolved as nested paths within that\n * dictionary. Hash-style IDs (no dots) are direct top-level keys.\n */\nconst lookupMessage = (\n id: string,\n locale: LocalesValues\n): string | undefined => {\n try {\n const dictionary = getIntlayer('messages' as DictionaryKeys, locale);\n const value = navigatePath(dictionary, id);\n return typeof value === 'string' ? value : undefined;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Intlayer-backed implementation of `@lingui/core`'s `I18n` class.\n *\n * - Messages are read from the `messages` intlayer dictionary.\n * - ICU MessageFormat syntax is resolved via `@intlayer/core/messageFormat`.\n * - `load()` / `loadAndActivate()` / `setMessagesCompiler()` are no-ops —\n * messages are served by intlayer's compiled dictionaries.\n * - `activate(locale)` emits `'change'` so that React consumers re-render.\n */\nexport class I18nClass extends EventEmitter<LinguiEvents> {\n private _locale: string;\n private _locales?: Locales;\n\n constructor({ locale = 'en', locales }: I18nProps = {}) {\n super();\n this._locale = typeof locale === 'string' ? locale : 'en';\n this._locales = locales;\n }\n\n get locale(): string {\n return this._locale;\n }\n\n get locales(): Locales | undefined {\n return this._locales;\n }\n\n get messages(): Messages {\n try {\n return getIntlayer(\n 'messages' as DictionaryKeys,\n this._locale as LocalesValues\n ) as Messages;\n } catch {\n return {};\n }\n }\n\n /**\n * No-op: intlayer handles message compilation at build time.\n */\n setMessagesCompiler(_compiler: MessageCompiler): this {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n '@intlayer/lingui: i18n.setMessagesCompiler() is a no-op — ' +\n 'message compilation is handled at build time by intlayer.'\n );\n }\n return this;\n }\n\n /**\n * No-op: messages are loaded automatically via intlayer dictionaries.\n */\n load(_localeOrAll: Locale | AllMessages, _messages?: Messages): void {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n '@intlayer/lingui: i18n.load() is a no-op — ' +\n 'messages are loaded automatically via intlayer dictionaries.'\n );\n }\n }\n\n /**\n * Activates the given locale (emits `'change'`).\n * The `messages` argument is ignored — intlayer handles the catalog.\n */\n loadAndActivate({\n locale,\n locales,\n }: {\n locale: Locale;\n locales?: Locales;\n messages: Messages;\n }): void {\n this.activate(locale, locales);\n }\n\n /**\n * Sets the active locale and emits `'change'` to notify React consumers.\n */\n activate(locale: Locale, locales?: Locales): void {\n this._locale = locale;\n this._locales = locales;\n this.emit('change');\n }\n\n /**\n * Translates a message descriptor or a plain ID.\n *\n * Resolution order:\n * 1. `messages` intlayer dictionary (dotted path navigation)\n * 2. `descriptor.message` or `options.message` (original source string)\n * 3. The raw `id` as fallback\n */\n _(descriptor: MessageDescriptor): string;\n _(id: MessageId, values?: Values, options?: MessageOptions): string;\n _(\n descriptorOrId: MessageDescriptor | MessageId,\n values?: Values,\n options?: MessageOptions\n ): string {\n const isDescriptor =\n typeof descriptorOrId === 'object' && descriptorOrId !== null;\n const id = isDescriptor\n ? (descriptorOrId as MessageDescriptor).id\n : (descriptorOrId as MessageId);\n const defaultMessage = isDescriptor\n ? ((descriptorOrId as MessageDescriptor).message ?? options?.message)\n : options?.message;\n const resolvedValues: Values = isDescriptor\n ? {\n ...((descriptorOrId as MessageDescriptor).values ?? {}),\n ...(values ?? {}),\n }\n : (values ?? {});\n\n const rawValue = lookupMessage(id, this._locale as LocalesValues);\n const template = rawValue ?? defaultMessage ?? id;\n\n return (\n resolveMessage(\n template,\n resolvedValues as Record<string, string | number>,\n this._locale as LocalesValues,\n 'icu'\n ) ?? id\n );\n }\n\n /**\n * Alias for `_`. Provided for lingui API compatibility.\n */\n t = (\n descriptorOrId: MessageDescriptor | MessageId,\n values?: Values,\n options?: MessageOptions\n ): string => this._(descriptorOrId as MessageId, values, options);\n\n /**\n * @deprecated Use `Intl.DateTimeFormat` directly.\n */\n date(\n value?: string | Date | number,\n format?: Intl.DateTimeFormatOptions\n ): string {\n if (value === undefined || value === null) return '';\n const dateValue =\n value instanceof Date\n ? value\n : new Date(typeof value === 'string' ? value : value);\n return new Intl.DateTimeFormat(this._locale, format).format(dateValue);\n }\n\n /**\n * @deprecated Use `Intl.NumberFormat` directly.\n */\n number(value: number | bigint, format?: Intl.NumberFormatOptions): string {\n return new Intl.NumberFormat(this._locale, format).format(value);\n }\n}\n"],"mappings":";;;;;;;;;;AA0CA,MAAM,gBAAgB,QAAiB,SAA0B;CAC/D,IAAI,CAAC,MAAM,OAAO;CAClB,MAAM,QAAQ,KAAK,MAAM,GAAG;CAC5B,IAAI,UAAmB;CACvB,KAAK,MAAM,QAAQ,OAAO;EACxB,IACE,YAAY,QACZ,YAAY,UACZ,OAAO,YAAY,UAEnB;EAEF,UAAW,QAAoC;CACjD;CACA,OAAO;AACT;;;;;;;;AASA,MAAM,iBACJ,IACA,WACuB;CACvB,IAAI;EAEF,MAAM,QAAQ,aADK,YAAY,YAA8B,MACzB,GAAG,EAAE;EACzC,OAAO,OAAO,UAAU,WAAW,QAAQ;CAC7C,QAAQ;EACN;CACF;AACF;;;;;;;;;;AAWA,IAAa,YAAb,cAA+B,aAA2B;CACxD,AAAQ;CACR,AAAQ;CAER,YAAY,EAAE,SAAS,MAAM,YAAuB,CAAC,GAAG;EACtD,MAAM;EACN,KAAK,UAAU,OAAO,WAAW,WAAW,SAAS;EACrD,KAAK,WAAW;CAClB;CAEA,IAAI,SAAiB;EACnB,OAAO,KAAK;CACd;CAEA,IAAI,UAA+B;EACjC,OAAO,KAAK;CACd;CAEA,IAAI,WAAqB;EACvB,IAAI;GACF,OAAO,YACL,YACA,KAAK,OACP;EACF,QAAQ;GACN,OAAO,CAAC;EACV;CACF;;;;CAKA,oBAAoB,WAAkC;EAElD,QAAQ,KACN,qHAEF;EAEF,OAAO;CACT;;;;CAKA,KAAK,cAAoC,WAA4B;EAEjE,QAAQ,KACN,yGAEF;CAEJ;;;;;CAMA,gBAAgB,EACd,QACA,WAKO;EACP,KAAK,SAAS,QAAQ,OAAO;CAC/B;;;;CAKA,SAAS,QAAgB,SAAyB;EAChD,KAAK,UAAU;EACf,KAAK,WAAW;EAChB,KAAK,KAAK,QAAQ;CACpB;CAYA,EACE,gBACA,QACA,SACQ;EACR,MAAM,eACJ,OAAO,mBAAmB,YAAY,mBAAmB;EAC3D,MAAM,KAAK,eACN,eAAqC,KACrC;EACL,MAAM,iBAAiB,eACjB,eAAqC,WAAW,SAAS,UAC3D,SAAS;EACb,MAAM,iBAAyB,eAC3B;GACE,GAAK,eAAqC,UAAU,CAAC;GACrD,GAAI,UAAU,CAAC;EACjB,IACC,UAAU,CAAC;EAKhB,OACE,eAJe,cAAc,IAAI,KAAK,OAChB,KAAK,kBAAkB,IAK3C,gBACA,KAAK,SACL,KACF,KAAK;CAET;;;;CAKA,KACE,gBACA,QACA,YACW,KAAK,EAAE,gBAA6B,QAAQ,OAAO;;;;CAKhE,KACE,OACA,QACQ;EACR,IAAI,UAAU,UAAa,UAAU,MAAM,OAAO;EAClD,MAAM,YACJ,iBAAiB,OACb,QACA,IAAI,KAAK,OAAO,UAAU,WAAW,QAAQ,KAAK;EACxD,OAAO,IAAI,KAAK,eAAe,KAAK,SAAS,MAAM,CAAC,CAAC,OAAO,SAAS;CACvE;;;;CAKA,OAAO,OAAwB,QAA2C;EACxE,OAAO,IAAI,KAAK,aAAa,KAAK,SAAS,MAAM,CAAC,CAAC,OAAO,KAAK;CACjE;AACF"}
@@ -0,0 +1,63 @@
1
+ 'use client';
2
+
3
+ import { LinguiContext } from "./LinguiContext.mjs";
4
+ import { useEffect, useState } from "react";
5
+ import { IntlayerProvider } from "react-intlayer";
6
+ import { jsx } from "react/jsx-runtime";
7
+
8
+ //#region src/I18nProvider.tsx
9
+ /**
10
+ * Drop-in for `@lingui/react`'s `I18nProvider`.
11
+ *
12
+ * Differences from the original:
13
+ * - Wraps children in an `IntlayerProvider` so that intlayer hooks receive the
14
+ * correct locale from the `i18n` instance.
15
+ * - Listens to the `i18n` `'change'` event to sync locale and context when
16
+ * `i18n.activate(locale)` is called at runtime.
17
+ * - The `defaultComponent` prop is forwarded but not used for rendering — it is
18
+ * stored in context for downstream `useLingui()` consumers.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * import { i18n } from '@lingui/core';
23
+ * import { I18nProvider } from '@lingui/react';
24
+ *
25
+ * i18n.activate('fr');
26
+ *
27
+ * export default function App() {
28
+ * return (
29
+ * <I18nProvider i18n={i18n}>
30
+ * <YourApp />
31
+ * </I18nProvider>
32
+ * );
33
+ * }
34
+ * ```
35
+ */
36
+ const I18nProvider = ({ i18n, defaultComponent, children }) => {
37
+ const buildContext = (instance) => ({
38
+ i18n: instance,
39
+ _: instance._.bind(instance),
40
+ defaultComponent
41
+ });
42
+ const [linguiContext, setLinguiContext] = useState(() => buildContext(i18n));
43
+ const [locale, setLocale] = useState(i18n.locale);
44
+ useEffect(() => {
45
+ setLinguiContext(buildContext(i18n));
46
+ setLocale(i18n.locale);
47
+ return i18n.on("change", () => {
48
+ setLinguiContext(buildContext(i18n));
49
+ setLocale(i18n.locale);
50
+ });
51
+ }, [i18n]);
52
+ return /* @__PURE__ */ jsx(LinguiContext.Provider, {
53
+ value: linguiContext,
54
+ children: /* @__PURE__ */ jsx(IntlayerProvider, {
55
+ locale,
56
+ children
57
+ })
58
+ });
59
+ };
60
+
61
+ //#endregion
62
+ export { I18nProvider };
63
+ //# sourceMappingURL=I18nProvider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"I18nProvider.mjs","names":[],"sources":["../../src/I18nProvider.tsx"],"sourcesContent":["'use client';\n\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type { I18n } from '@lingui/core';\nimport type { I18nProviderProps } from '@lingui/react';\nimport { type JSX, useEffect, useState } from 'react';\nimport { IntlayerProvider } from 'react-intlayer';\nimport { LinguiContext } from './LinguiContext';\n\n/**\n * Drop-in for `@lingui/react`'s `I18nProvider`.\n *\n * Differences from the original:\n * - Wraps children in an `IntlayerProvider` so that intlayer hooks receive the\n * correct locale from the `i18n` instance.\n * - Listens to the `i18n` `'change'` event to sync locale and context when\n * `i18n.activate(locale)` is called at runtime.\n * - The `defaultComponent` prop is forwarded but not used for rendering — it is\n * stored in context for downstream `useLingui()` consumers.\n *\n * @example\n * ```tsx\n * import { i18n } from '@lingui/core';\n * import { I18nProvider } from '@lingui/react';\n *\n * i18n.activate('fr');\n *\n * export default function App() {\n * return (\n * <I18nProvider i18n={i18n}>\n * <YourApp />\n * </I18nProvider>\n * );\n * }\n * ```\n */\nexport const I18nProvider = ({\n i18n,\n defaultComponent,\n children,\n}: I18nProviderProps): JSX.Element | null => {\n const buildContext = (instance: I18n) => ({\n i18n: instance,\n _: instance._.bind(instance),\n defaultComponent,\n });\n\n const [linguiContext, setLinguiContext] = useState(() => buildContext(i18n));\n const [locale, setLocale] = useState<string>(i18n.locale);\n\n useEffect(() => {\n setLinguiContext(buildContext(i18n));\n setLocale(i18n.locale);\n\n return i18n.on('change', () => {\n setLinguiContext(buildContext(i18n));\n setLocale(i18n.locale);\n });\n // defaultComponent intentionally excluded — changes to it require remounting anyway\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [i18n]);\n\n return (\n <LinguiContext.Provider value={linguiContext}>\n <IntlayerProvider locale={locale as LocalesValues}>\n {children}\n </IntlayerProvider>\n </LinguiContext.Provider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,MAAa,gBAAgB,EAC3B,MACA,kBACA,eAC2C;CAC3C,MAAM,gBAAgB,cAAoB;EACxC,MAAM;EACN,GAAG,SAAS,EAAE,KAAK,QAAQ;EAC3B;CACF;CAEA,MAAM,CAAC,eAAe,oBAAoB,eAAe,aAAa,IAAI,CAAC;CAC3E,MAAM,CAAC,QAAQ,aAAa,SAAiB,KAAK,MAAM;CAExD,gBAAgB;EACd,iBAAiB,aAAa,IAAI,CAAC;EACnC,UAAU,KAAK,MAAM;EAErB,OAAO,KAAK,GAAG,gBAAgB;GAC7B,iBAAiB,aAAa,IAAI,CAAC;GACnC,UAAU,KAAK,MAAM;EACvB,CAAC;CAGH,GAAG,CAAC,IAAI,CAAC;CAET,OACE,oBAAC,cAAc,UAAf;EAAwB,OAAO;YAC7B,oBAAC,kBAAD;GAA0B;GACvB;EACe;CACI;AAE5B"}