@intlayer/react-intl 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.
- package/README.md +330 -0
- package/dist/cjs/FormattedComponents.cjs +131 -0
- package/dist/cjs/FormattedComponents.cjs.map +1 -0
- package/dist/cjs/FormattedMessage.cjs +45 -0
- package/dist/cjs/FormattedMessage.cjs.map +1 -0
- package/dist/cjs/IntlProvider.cjs +38 -0
- package/dist/cjs/IntlProvider.cjs.map +1 -0
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/cjs/context.cjs +16 -0
- package/dist/cjs/context.cjs.map +1 -0
- package/dist/cjs/createIntl.cjs +46 -0
- package/dist/cjs/createIntl.cjs.map +1 -0
- package/dist/cjs/createIntlObject.cjs +132 -0
- package/dist/cjs/createIntlObject.cjs.map +1 -0
- package/dist/cjs/defineMessages.cjs +20 -0
- package/dist/cjs/defineMessages.cjs.map +1 -0
- package/dist/cjs/errors.cjs +85 -0
- package/dist/cjs/errors.cjs.map +1 -0
- package/dist/cjs/index.cjs +40 -0
- package/dist/cjs/plugin/index.cjs +57 -0
- package/dist/cjs/plugin/index.cjs.map +1 -0
- package/dist/cjs/useIntl.cjs +33 -0
- package/dist/cjs/useIntl.cjs.map +1 -0
- package/dist/esm/FormattedComponents.mjs +119 -0
- package/dist/esm/FormattedComponents.mjs.map +1 -0
- package/dist/esm/FormattedMessage.mjs +44 -0
- package/dist/esm/FormattedMessage.mjs.map +1 -0
- package/dist/esm/IntlProvider.mjs +37 -0
- package/dist/esm/IntlProvider.mjs.map +1 -0
- package/dist/esm/context.mjs +14 -0
- package/dist/esm/context.mjs.map +1 -0
- package/dist/esm/createIntl.mjs +44 -0
- package/dist/esm/createIntl.mjs.map +1 -0
- package/dist/esm/createIntlObject.mjs +131 -0
- package/dist/esm/createIntlObject.mjs.map +1 -0
- package/dist/esm/defineMessages.mjs +17 -0
- package/dist/esm/defineMessages.mjs.map +1 -0
- package/dist/esm/errors.mjs +77 -0
- package/dist/esm/errors.mjs.map +1 -0
- package/dist/esm/index.mjs +12 -0
- package/dist/esm/plugin/index.mjs +53 -0
- package/dist/esm/plugin/index.mjs.map +1 -0
- package/dist/esm/useIntl.mjs +32 -0
- package/dist/esm/useIntl.mjs.map +1 -0
- package/dist/types/FormattedComponents.d.ts +67 -0
- package/dist/types/FormattedComponents.d.ts.map +1 -0
- package/dist/types/FormattedMessage.d.ts +28 -0
- package/dist/types/FormattedMessage.d.ts.map +1 -0
- package/dist/types/IntlProvider.d.ts +16 -0
- package/dist/types/IntlProvider.d.ts.map +1 -0
- package/dist/types/context.d.ts +13 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/createIntl.d.ts +35 -0
- package/dist/types/createIntl.d.ts.map +1 -0
- package/dist/types/createIntlObject.d.ts +15 -0
- package/dist/types/createIntlObject.d.ts.map +1 -0
- package/dist/types/defineMessages.d.ts +18 -0
- package/dist/types/defineMessages.d.ts.map +1 -0
- package/dist/types/errors.d.ts +56 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/plugin/index.d.ts +23 -0
- package/dist/types/plugin/index.d.ts.map +1 -0
- package/dist/types/useIntl.d.ts +21 -0
- package/dist/types/useIntl.d.ts.map +1 -0
- package/package.json +117 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormattedComponents.mjs","names":[],"sources":["../../src/FormattedComponents.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport type {\n FormattedDate as _FormattedDate,\n FormattedDateParts as _FormattedDateParts,\n FormattedDateTimeRange as _FormattedDateTimeRange,\n FormattedDisplayName as _FormattedDisplayName,\n FormattedList as _FormattedList,\n FormattedListParts as _FormattedListParts,\n FormattedNumber as _FormattedNumber,\n FormattedNumberParts as _FormattedNumberParts,\n FormattedPlural as _FormattedPlural,\n FormattedRelativeTime as _FormattedRelativeTime,\n FormattedTime as _FormattedTime,\n FormattedTimeParts as _FormattedTimeParts,\n} from 'react-intl';\nimport { useIntl } from './useIntl';\n\nconst toDate = (value: Date | number | string | undefined): Date =>\n value instanceof Date\n ? value\n : typeof value === 'undefined'\n ? new Date()\n : new Date(value);\n\n/**\n * Drop-in for react-intl's `<FormattedDate>`.\n * Renders a locale-aware date string using `Intl.DateTimeFormat`.\n */\nexport const FormattedDate: typeof _FormattedDate = ({\n value,\n children,\n format: _format,\n ...options\n}) => {\n const intl = useIntl();\n const formatted = intl.formatDate(value, options);\n if (typeof children === 'function') {\n return (children(formatted) ?? null) as ReactElement | null;\n }\n return <>{formatted}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedTime>`.\n * Renders a locale-aware time string using `Intl.DateTimeFormat`.\n */\nexport const FormattedTime: typeof _FormattedTime = ({\n value,\n children,\n format: _format,\n ...options\n}) => {\n const intl = useIntl();\n const formatted = intl.formatTime(value, options);\n if (typeof children === 'function') {\n return (children(formatted) ?? null) as ReactElement | null;\n }\n return <>{formatted}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedNumber>`.\n * Renders a locale-aware number string using `Intl.NumberFormat`.\n */\nexport const FormattedNumber: typeof _FormattedNumber = ({\n value,\n children,\n format: _format,\n ...options\n}) => {\n const intl = useIntl();\n const formatted = intl.formatNumber(value, options);\n if (typeof children === 'function') {\n return (children(formatted) ?? null) as ReactElement | null;\n }\n return <>{formatted}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedList>`.\n * Renders a locale-aware list string using `Intl.ListFormat`.\n */\nexport const FormattedList: typeof _FormattedList = ({ value, ...options }) => {\n const intl = useIntl();\n const strings = (value as unknown[]).filter(\n (item): item is string => typeof item === 'string'\n );\n const formatted = intl.formatList(strings, options);\n return <>{formatted}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedDisplayName>`.\n * Renders a locale-aware display name using `Intl.DisplayNames`.\n */\nexport const FormattedDisplayName: typeof _FormattedDisplayName = ({\n value,\n ...options\n}) => {\n const intl = useIntl();\n const formatted = intl.formatDisplayName(\n value,\n options as Intl.DisplayNamesOptions\n );\n return <>{formatted ?? value}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedRelativeTime>`.\n * Renders a locale-aware relative time string using `Intl.RelativeTimeFormat`.\n * Auto-update (`updateIntervalInSeconds`) is not implemented.\n */\nexport const FormattedRelativeTime: typeof _FormattedRelativeTime = ({\n value = 0,\n unit = 'second',\n children,\n updateIntervalInSeconds: _updateIntervalInSeconds,\n ...options\n}) => {\n const intl = useIntl();\n const formatted = intl.formatRelativeTime(value, unit, options);\n if (typeof children === 'function') {\n return (children(formatted) ?? null) as ReactElement | null;\n }\n return <>{formatted}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedPlural>`.\n * Selects the matching plural slot using `Intl.PluralRules`.\n */\nexport const FormattedPlural: typeof _FormattedPlural = ({\n value,\n other,\n zero,\n one,\n two,\n few,\n many,\n children,\n ...options\n}) => {\n const intl = useIntl();\n const rule = intl.formatPlural(value, options);\n const slots: Record<Intl.LDMLPluralRule, unknown> = {\n zero,\n one,\n two,\n few,\n many,\n other,\n };\n const selected = slots[rule] ?? other;\n\n if (typeof children === 'function') {\n return (children(selected as import('react').ReactNode) ??\n null) as ReactElement | null;\n }\n\n return <>{selected}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedDateTimeRange>`.\n * Renders a locale-aware date range string using `Intl.DateTimeFormat#formatRange`.\n */\nexport const FormattedDateTimeRange: typeof _FormattedDateTimeRange = ({\n from,\n to,\n children,\n ...options\n}) => {\n const intl = useIntl();\n const formatted = intl.formatDateTimeRange(from, to, options);\n if (typeof children === 'function') {\n return (children(formatted) ?? null) as ReactElement | null;\n }\n return <>{formatted}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedDateParts>`.\n * Renders format parts via a `children` render-prop.\n */\nexport const FormattedDateParts: typeof _FormattedDateParts = ({\n value,\n children,\n format: _format,\n ...options\n}) => {\n const intl = useIntl();\n const parts = intl.formatDateToParts(\n value as Parameters<Intl.DateTimeFormat['format']>[0],\n options\n );\n return <>{children(parts)}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedTimeParts>`.\n * Renders format parts via a `children` render-prop.\n */\nexport const FormattedTimeParts: typeof _FormattedTimeParts = ({\n value,\n children,\n format: _format,\n ...options\n}) => {\n const intl = useIntl();\n const parts = intl.formatTimeToParts(\n value as Parameters<Intl.DateTimeFormat['format']>[0],\n options\n );\n return <>{children(parts)}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedNumberParts>`.\n * Renders format parts via a `children` render-prop.\n */\nexport const FormattedNumberParts: typeof _FormattedNumberParts = ({\n value,\n children,\n format: _format,\n ...options\n}) => {\n const intl = useIntl();\n const parts = intl.formatNumberToParts(value, options);\n return <>{children(parts)}</>;\n};\n\n/**\n * Drop-in for react-intl's `<FormattedListParts>`.\n * Renders list format parts via a `children` render-prop.\n */\nexport const FormattedListParts: typeof _FormattedListParts = ({\n value,\n children,\n ...options\n}) => {\n const intl = useIntl();\n const strings = Array.from(value).filter(\n (item): item is string => typeof item === 'string'\n );\n const parts = intl.formatListToParts(strings, options);\n return <>{children(parts)}</>;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useIntl } from "./useIntl.mjs";
|
|
4
|
+
import { Fragment } from "react";
|
|
5
|
+
import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/FormattedMessage.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Drop-in for react-intl's `<FormattedMessage>`.
|
|
10
|
+
*
|
|
11
|
+
* Translates the message identified by `id` using the active intl context.
|
|
12
|
+
* Full ICU MessageFormat syntax is supported.
|
|
13
|
+
*
|
|
14
|
+
* When `values` contains render functions, rich text tags
|
|
15
|
+
* (`<b>chunks</b>`) are mapped through them. When a `tagName` is provided,
|
|
16
|
+
* the output is wrapped in that element; otherwise a fragment is used.
|
|
17
|
+
* A `children` render-prop receives the resolved nodes.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <FormattedMessage id="home.title" />
|
|
22
|
+
* <FormattedMessage id="home.greeting" values={{ name: 'Alice' }} />
|
|
23
|
+
* <FormattedMessage
|
|
24
|
+
* id="terms.agreement"
|
|
25
|
+
* values={{ b: (chunks) => <strong>{chunks}</strong> }}
|
|
26
|
+
* />
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
const FormattedMessage = ({ id = "", description: _description, defaultMessage, values, tagName: TagName, children, ignoreTag: _ignoreTag }) => {
|
|
30
|
+
const intl = useIntl();
|
|
31
|
+
const stringDefaultMessage = typeof defaultMessage === "string" ? defaultMessage : void 0;
|
|
32
|
+
const result = intl.formatMessage({
|
|
33
|
+
id,
|
|
34
|
+
defaultMessage: stringDefaultMessage
|
|
35
|
+
}, values);
|
|
36
|
+
const nodes = Array.isArray(result) ? result : [result];
|
|
37
|
+
if (typeof children === "function") return children(nodes) ?? null;
|
|
38
|
+
if (TagName && TagName !== Fragment) return /* @__PURE__ */ jsx(TagName, { children: nodes });
|
|
39
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: nodes });
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
export { FormattedMessage };
|
|
44
|
+
//# sourceMappingURL=FormattedMessage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormattedMessage.mjs","names":[],"sources":["../../src/FormattedMessage.tsx"],"sourcesContent":["'use client';\n\nimport { Fragment, type ReactElement, type ReactNode } from 'react';\nimport type { FormattedMessage as _FormattedMessage } from 'react-intl';\nimport { useIntl } from './useIntl';\n\n/**\n * Drop-in for react-intl's `<FormattedMessage>`.\n *\n * Translates the message identified by `id` using the active intl context.\n * Full ICU MessageFormat syntax is supported.\n *\n * When `values` contains render functions, rich text tags\n * (`<b>chunks</b>`) are mapped through them. When a `tagName` is provided,\n * the output is wrapped in that element; otherwise a fragment is used.\n * A `children` render-prop receives the resolved nodes.\n *\n * @example\n * ```tsx\n * <FormattedMessage id=\"home.title\" />\n * <FormattedMessage id=\"home.greeting\" values={{ name: 'Alice' }} />\n * <FormattedMessage\n * id=\"terms.agreement\"\n * values={{ b: (chunks) => <strong>{chunks}</strong> }}\n * />\n * ```\n */\nexport const FormattedMessage: typeof _FormattedMessage = ({\n id = '',\n description: _description,\n defaultMessage,\n values,\n tagName: TagName,\n children,\n ignoreTag: _ignoreTag,\n}) => {\n const intl = useIntl();\n const stringDefaultMessage =\n typeof defaultMessage === 'string' ? defaultMessage : undefined;\n const result = (\n intl.formatMessage as (\n descriptor: { id: string; defaultMessage?: string },\n values?: Record<string, unknown>\n ) => string | ReactNode[]\n )(\n { id, defaultMessage: stringDefaultMessage },\n values as Record<string, unknown>\n );\n const nodes: ReactNode[] = Array.isArray(result) ? result : [result];\n\n if (typeof children === 'function') {\n return (children(nodes) ?? null) as ReactElement | null;\n }\n\n if (TagName && TagName !== Fragment) {\n return <TagName>{nodes}</TagName>;\n }\n\n return <>{nodes}</>;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,MAAa,oBAA8C,EACzD,KAAK,IACL,aAAa,cACb,gBACA,QACA,SAAS,SACT,UACA,WAAW,iBACP;CACJ,MAAM,OAAO,QAAQ;CACrB,MAAM,uBACJ,OAAO,mBAAmB,WAAW,iBAAiB;CACxD,MAAM,SACJ,KAAK,cAKL;EAAE;EAAI,gBAAgB;CAAqB,GAC3C,MACF;CACA,MAAM,QAAqB,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;CAEnE,IAAI,OAAO,aAAa,YACtB,OAAQ,SAAS,KAAK,KAAK;CAG7B,IAAI,WAAW,YAAY,UACzB,OAAO,oBAAC,SAAD,YAAU,MAAe;CAGlC,OAAO,4CAAG,MAAQ;AACpB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { IntlContext } from "./context.mjs";
|
|
4
|
+
import { createIntlObject } from "./createIntlObject.mjs";
|
|
5
|
+
import { log } from "@intlayer/config/built";
|
|
6
|
+
import { CYAN } from "@intlayer/config/colors";
|
|
7
|
+
import { colorize, getAppLogger } from "@intlayer/config/logger";
|
|
8
|
+
import { useMemo } from "react";
|
|
9
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
10
|
+
import { jsx } from "react/jsx-runtime";
|
|
11
|
+
|
|
12
|
+
//#region src/IntlProvider.tsx
|
|
13
|
+
/**
|
|
14
|
+
* Drop-in for react-intl's `IntlProvider`.
|
|
15
|
+
*
|
|
16
|
+
* `messages`, `formats`, `timeZone`, `now`, `defaultRichTextElements`,
|
|
17
|
+
* and `onError`/`onWarn` are accepted for API compatibility but have no
|
|
18
|
+
* effect — Intlayer uses its own compiled dictionaries.
|
|
19
|
+
*
|
|
20
|
+
* The `locale` prop is forwarded to `IntlayerClientProvider`.
|
|
21
|
+
*/
|
|
22
|
+
const IntlProvider = ({ locale, children, messages: _messages, formats: _formats, timeZone: _timeZone, defaultRichTextElements: _defaultRichTextElements, onError: _onError, ...rest }) => {
|
|
23
|
+
const intlObject = useMemo(() => createIntlObject(locale), [locale]);
|
|
24
|
+
if (typeof _messages !== "undefined") getAppLogger({ log })(`${colorize("IntlProvider", CYAN)} do not pass the messages prop with intlayer. Messages are loaded automatically under the hood for bundle optimization reasons.`);
|
|
25
|
+
return /* @__PURE__ */ jsx(IntlContext.Provider, {
|
|
26
|
+
value: intlObject,
|
|
27
|
+
children: /* @__PURE__ */ jsx(IntlayerProvider, {
|
|
28
|
+
locale,
|
|
29
|
+
...rest,
|
|
30
|
+
children
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { IntlProvider };
|
|
37
|
+
//# sourceMappingURL=IntlProvider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IntlProvider.mjs","names":[],"sources":["../../src/IntlProvider.tsx"],"sourcesContent":["'use client';\n\nimport { log } from '@intlayer/config/built';\nimport { CYAN } from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { useMemo } from 'react';\nimport type { IntlProvider as _IntlProvider } from 'react-intl';\nimport { IntlayerProvider } from 'react-intlayer';\nimport { IntlContext } from './context';\nimport { createIntlObject } from './createIntlObject';\n\n/**\n * Drop-in for react-intl's `IntlProvider`.\n *\n * `messages`, `formats`, `timeZone`, `now`, `defaultRichTextElements`,\n * and `onError`/`onWarn` are accepted for API compatibility but have no\n * effect — Intlayer uses its own compiled dictionaries.\n *\n * The `locale` prop is forwarded to `IntlayerClientProvider`.\n */\nexport const IntlProvider: typeof _IntlProvider = ({\n locale,\n children,\n messages: _messages,\n formats: _formats,\n timeZone: _timeZone,\n defaultRichTextElements: _defaultRichTextElements,\n onError: _onError,\n ...rest\n}) => {\n const intlObject = useMemo(\n () => createIntlObject(locale as LocalesValues),\n [locale]\n );\n\n if (\n process.env.NODE_ENV === 'development' &&\n typeof _messages !== 'undefined'\n ) {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('IntlProvider', CYAN)} do not pass the messages prop with intlayer. Messages are loaded automatically under the hood for bundle optimization reasons.`\n );\n }\n\n return (\n <IntlContext.Provider value={intlObject}>\n <IntlayerProvider locale={locale as LocalesValues} {...(rest as object)}>\n {children}\n </IntlayerProvider>\n </IntlContext.Provider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,gBAAsC,EACjD,QACA,UACA,UAAU,WACV,SAAS,UACT,UAAU,WACV,yBAAyB,0BACzB,SAAS,UACT,GAAG,WACC;CACJ,MAAM,aAAa,cACX,iBAAiB,MAAuB,GAC9C,CAAC,MAAM,CACT;CAEA,IAEE,OAAO,cAAc,aAGrB,AADkB,aAAa,EAAE,IAAI,CAC7B,CAAC,CACP,GAAG,SAAS,gBAAgB,IAAI,EAAE,gIACpC;CAGF,OACE,oBAAC,YAAY,UAAb;EAAsB,OAAO;YAC3B,oBAAC,kBAAD;GAA0B;GAAyB,GAAK;GACrD;EACe;CACE;AAE1B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/context.tsx
|
|
4
|
+
/**
|
|
5
|
+
* React context holding the active intlayer-backed `IntlShape` instance.
|
|
6
|
+
* Populated by {@link IntlProvider}; consumed by {@link useIntl}.
|
|
7
|
+
*/
|
|
8
|
+
const IntlContext = createContext(null);
|
|
9
|
+
/** The raw `React.Provider<IntlShape>` — same as `IntlContext.Provider`. */
|
|
10
|
+
const RawIntlProvider = IntlContext.Provider;
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
export { IntlContext, RawIntlProvider };
|
|
14
|
+
//# sourceMappingURL=context.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.mjs","names":[],"sources":["../../src/context.tsx"],"sourcesContent":["import { createContext } from 'react';\nimport type { IntlShape } from 'react-intl';\n\n/**\n * React context holding the active intlayer-backed `IntlShape` instance.\n * Populated by {@link IntlProvider}; consumed by {@link useIntl}.\n */\nexport const IntlContext = createContext<IntlShape>(\n null as unknown as IntlShape\n);\n\n/** The raw `React.Provider<IntlShape>` — same as `IntlContext.Provider`. */\nexport const RawIntlProvider = IntlContext.Provider;\n"],"mappings":";;;;;;;AAOA,MAAa,cAAc,cACzB,IACF;;AAGA,MAAa,kBAAkB,YAAY"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createIntlObject } from "./createIntlObject.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/createIntl.ts
|
|
4
|
+
/**
|
|
5
|
+
* Drop-in for react-intl's `createIntlCache`.
|
|
6
|
+
*
|
|
7
|
+
* Returns an empty cache token. In the intlayer compat adapter, formatter
|
|
8
|
+
* instances are not pooled (all backed by native `Intl.*` constructors), so
|
|
9
|
+
* the cache object serves only as an API-compatibility token.
|
|
10
|
+
*
|
|
11
|
+
* @deprecated
|
|
12
|
+
* Has no practical effect with intlayer — no formatter pooling is needed.
|
|
13
|
+
*/
|
|
14
|
+
const createIntlCache = () => ({
|
|
15
|
+
dateTime: {},
|
|
16
|
+
number: {},
|
|
17
|
+
message: {},
|
|
18
|
+
relativeTime: {},
|
|
19
|
+
pluralRules: {},
|
|
20
|
+
list: {},
|
|
21
|
+
displayNames: {}
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Drop-in for react-intl's `createIntl`.
|
|
25
|
+
*
|
|
26
|
+
* Creates an `IntlShape` instance backed by intlayer compiled dictionaries
|
|
27
|
+
* for the given `locale`. Use this in non-React contexts (e.g. server-side
|
|
28
|
+
* route handlers).
|
|
29
|
+
*
|
|
30
|
+
* `messages`, `formats`, `timeZone`, `onError`, and `cache` are accepted for
|
|
31
|
+
* API compatibility but have no effect — Intlayer uses its own compiled
|
|
32
|
+
* dictionaries.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const intl = createIntl({ locale: 'en' });
|
|
37
|
+
* intl.formatMessage({ id: 'home.title' });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
const createIntl = ({ locale }, _cache) => createIntlObject(locale);
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
export { createIntl, createIntlCache };
|
|
44
|
+
//# sourceMappingURL=createIntl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createIntl.mjs","names":[],"sources":["../../src/createIntl.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport type {\n createIntl as _createIntl,\n createIntlCache as _createIntlCache,\n IntlCache,\n IntlConfig,\n IntlShape,\n} from 'react-intl';\nimport { createIntlObject } from './createIntlObject';\n\n/**\n * Drop-in for react-intl's `createIntlCache`.\n *\n * Returns an empty cache token. In the intlayer compat adapter, formatter\n * instances are not pooled (all backed by native `Intl.*` constructors), so\n * the cache object serves only as an API-compatibility token.\n *\n * @deprecated\n * Has no practical effect with intlayer — no formatter pooling is needed.\n */\nexport const createIntlCache: typeof _createIntlCache = (): IntlCache =>\n ({\n dateTime: {},\n number: {},\n message: {},\n relativeTime: {},\n pluralRules: {},\n list: {},\n displayNames: {},\n }) as IntlCache;\n\n/**\n * Drop-in for react-intl's `createIntl`.\n *\n * Creates an `IntlShape` instance backed by intlayer compiled dictionaries\n * for the given `locale`. Use this in non-React contexts (e.g. server-side\n * route handlers).\n *\n * `messages`, `formats`, `timeZone`, `onError`, and `cache` are accepted for\n * API compatibility but have no effect — Intlayer uses its own compiled\n * dictionaries.\n *\n * @example\n * ```ts\n * const intl = createIntl({ locale: 'en' });\n * intl.formatMessage({ id: 'home.title' });\n * ```\n */\nexport const createIntl: typeof _createIntl = (\n { locale }: IntlConfig,\n _cache?: IntlCache\n): IntlShape => createIntlObject(locale as LocalesValues);\n"],"mappings":";;;;;;;;;;;;;AAoBA,MAAa,yBACV;CACC,UAAU,CAAC;CACX,QAAQ,CAAC;CACT,SAAS,CAAC;CACV,cAAc,CAAC;CACf,aAAa,CAAC;CACd,MAAM,CAAC;CACP,cAAc,CAAC;AACjB;;;;;;;;;;;;;;;;;;AAmBF,MAAa,cACX,EAAE,UACF,WACc,iBAAiB,MAAuB"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Fragment } from "react";
|
|
2
|
+
import { getIntlayer } from "@intlayer/core/interpreter";
|
|
3
|
+
import { parseTaggedMessage, resolveMessage } from "@intlayer/core/messageFormat";
|
|
4
|
+
import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/createIntlObject.tsx
|
|
7
|
+
/** Splits a full dotted id into the dictionary key and remaining path. */
|
|
8
|
+
const splitId = (id) => {
|
|
9
|
+
const dotIndex = id.indexOf(".");
|
|
10
|
+
if (dotIndex === -1) return {
|
|
11
|
+
dictionaryKey: id,
|
|
12
|
+
path: ""
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
dictionaryKey: id.slice(0, dotIndex),
|
|
16
|
+
path: id.slice(dotIndex + 1)
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const navigatePath = (object, path) => {
|
|
20
|
+
if (!path) return object;
|
|
21
|
+
const parts = path.split(".");
|
|
22
|
+
let current = object;
|
|
23
|
+
for (const part of parts) {
|
|
24
|
+
if (current === null || current === void 0 || typeof current !== "object") return;
|
|
25
|
+
current = current[part];
|
|
26
|
+
}
|
|
27
|
+
return current;
|
|
28
|
+
};
|
|
29
|
+
/** Looks up a message value by full dotted id; first segment = dictionary key. */
|
|
30
|
+
const lookupMessage = (id, locale) => {
|
|
31
|
+
const { dictionaryKey, path } = splitId(id);
|
|
32
|
+
if (!dictionaryKey) return void 0;
|
|
33
|
+
try {
|
|
34
|
+
return navigatePath(getIntlayer(dictionaryKey, locale), path);
|
|
35
|
+
} catch {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
/** Maps tagged tokens to React nodes using the provided renderer functions. */
|
|
40
|
+
const renderRichTokens = (tokens, renderers) => tokens.map((token, tokenIndex) => {
|
|
41
|
+
if (typeof token === "string") return token;
|
|
42
|
+
const children = renderRichTokens(token.children, renderers);
|
|
43
|
+
const renderer = renderers[token.tag];
|
|
44
|
+
if (typeof renderer === "function") return /* @__PURE__ */ jsx(Fragment, { children: renderer(/* @__PURE__ */ jsx(Fragment$1, { children })) }, tokenIndex);
|
|
45
|
+
return /* @__PURE__ */ jsx(Fragment, { children }, tokenIndex);
|
|
46
|
+
});
|
|
47
|
+
/** Partitions values into scalar interpolation params and tag renderers. */
|
|
48
|
+
const splitRichValues = (values) => {
|
|
49
|
+
const scalarValues = {};
|
|
50
|
+
const renderers = {};
|
|
51
|
+
for (const [key, value] of Object.entries(values)) if (typeof value === "function") renderers[key] = value;
|
|
52
|
+
else scalarValues[key] = value;
|
|
53
|
+
return {
|
|
54
|
+
scalarValues,
|
|
55
|
+
renderers
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
const isRichValues = (values) => Object.values(values).some((value) => typeof value === "function");
|
|
59
|
+
/**
|
|
60
|
+
* Builds an intlayer-backed `IntlShape` object for the given locale.
|
|
61
|
+
*
|
|
62
|
+
* - Translation ids use the first dot-path segment as the dictionary key.
|
|
63
|
+
* - Full ICU MessageFormat syntax is supported via `@intlayer/core/messageFormat`.
|
|
64
|
+
* - Rich text tags (`<b>chunks</b>`) are resolved through render functions in `values`.
|
|
65
|
+
*/
|
|
66
|
+
const createIntlObject = (locale) => {
|
|
67
|
+
const localeString = locale;
|
|
68
|
+
const formatMessage = (descriptor, values) => {
|
|
69
|
+
const { id = "", defaultMessage } = descriptor;
|
|
70
|
+
const rawValue = lookupMessage(id, locale);
|
|
71
|
+
const messageTemplate = rawValue !== void 0 && rawValue !== null ? rawValue : typeof defaultMessage === "string" ? defaultMessage : id;
|
|
72
|
+
if (!values || !isRichValues(values)) return resolveMessage(messageTemplate, values ?? {}, locale, "icu") ?? id;
|
|
73
|
+
const { scalarValues, renderers } = splitRichValues(values);
|
|
74
|
+
return renderRichTokens(parseTaggedMessage(resolveMessage(messageTemplate, scalarValues, locale, "icu") ?? id), renderers);
|
|
75
|
+
};
|
|
76
|
+
const toDate = (value) => value instanceof Date ? value : new Date(value);
|
|
77
|
+
const formatDate = (value, options) => {
|
|
78
|
+
if (value === void 0 || value === null) return "";
|
|
79
|
+
return new Intl.DateTimeFormat(localeString, options).format(toDate(value));
|
|
80
|
+
};
|
|
81
|
+
const formatNumber = (value, options) => new Intl.NumberFormat(localeString, options).format(value);
|
|
82
|
+
const formatPlural = (value, options) => new Intl.PluralRules(localeString, options).select(value);
|
|
83
|
+
const formatList = (list, options) => {
|
|
84
|
+
const strings = Array.from(list).filter((item) => typeof item === "string");
|
|
85
|
+
return new Intl.ListFormat(localeString, options).format(strings);
|
|
86
|
+
};
|
|
87
|
+
const formatListToParts = (list, options) => {
|
|
88
|
+
const strings = Array.from(list).filter((item) => typeof item === "string");
|
|
89
|
+
return new Intl.ListFormat(localeString, options).formatToParts(strings);
|
|
90
|
+
};
|
|
91
|
+
const formatDisplayName = (value, options) => new Intl.DisplayNames([localeString], options ?? { type: "language" }).of(value);
|
|
92
|
+
const formatRelativeTime = (value, unit, options) => new Intl.RelativeTimeFormat(localeString, {
|
|
93
|
+
numeric: "auto",
|
|
94
|
+
...options
|
|
95
|
+
}).format(value, unit ?? "second");
|
|
96
|
+
const formatDateTimeRange = (from, to, options) => new Intl.DateTimeFormat(localeString, options).formatRange(toDate(from), toDate(to));
|
|
97
|
+
const formatDateToParts = (value, options) => new Intl.DateTimeFormat(localeString, options).formatToParts(typeof value === "string" ? new Date(value) : value);
|
|
98
|
+
const formatNumberToParts = (value, options) => new Intl.NumberFormat(localeString, options).formatToParts(value);
|
|
99
|
+
return {
|
|
100
|
+
locale: localeString,
|
|
101
|
+
defaultLocale: localeString,
|
|
102
|
+
messages: {},
|
|
103
|
+
formats: {},
|
|
104
|
+
defaultFormats: {},
|
|
105
|
+
timeZone: void 0,
|
|
106
|
+
textComponent: Fragment,
|
|
107
|
+
wrapRichTextChunksInFragment: false,
|
|
108
|
+
fallbackOnEmptyString: true,
|
|
109
|
+
onError: () => {},
|
|
110
|
+
onWarn: () => {},
|
|
111
|
+
formatters: {},
|
|
112
|
+
formatMessage,
|
|
113
|
+
$t: formatMessage,
|
|
114
|
+
formatDate,
|
|
115
|
+
formatTime: formatDate,
|
|
116
|
+
formatNumber,
|
|
117
|
+
formatPlural,
|
|
118
|
+
formatList,
|
|
119
|
+
formatListToParts,
|
|
120
|
+
formatDisplayName,
|
|
121
|
+
formatRelativeTime,
|
|
122
|
+
formatDateTimeRange,
|
|
123
|
+
formatDateToParts,
|
|
124
|
+
formatTimeToParts: formatDateToParts,
|
|
125
|
+
formatNumberToParts
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
export { createIntlObject };
|
|
131
|
+
//# sourceMappingURL=createIntlObject.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createIntlObject.mjs","names":[],"sources":["../../src/createIntlObject.tsx"],"sourcesContent":["import { getIntlayer } from '@intlayer/core/interpreter';\nimport {\n type MessageValues,\n parseTaggedMessage,\n resolveMessage,\n type TaggedMessageToken,\n} from '@intlayer/core/messageFormat';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { Fragment, type ReactNode } from 'react';\nimport type { IntlShape, MessageDescriptor } from 'react-intl';\n\ntype RichRenderer = (chunks: ReactNode) => ReactNode;\n\n/** Splits a full dotted id into the dictionary key and remaining path. */\nconst splitId = (id: string): { dictionaryKey: string; path: string } => {\n const dotIndex = id.indexOf('.');\n if (dotIndex === -1) return { dictionaryKey: id, path: '' };\n return {\n dictionaryKey: id.slice(0, dotIndex),\n path: id.slice(dotIndex + 1),\n };\n};\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/** Looks up a message value by full dotted id; first segment = dictionary key. */\nconst lookupMessage = (id: string, locale: LocalesValues): unknown => {\n const { dictionaryKey, path } = splitId(id);\n if (!dictionaryKey) return undefined;\n try {\n const dictionary = getIntlayer(dictionaryKey as DictionaryKeys, locale);\n return navigatePath(dictionary, path);\n } catch {\n return undefined;\n }\n};\n\n/** Maps tagged tokens to React nodes using the provided renderer functions. */\nconst renderRichTokens = (\n tokens: TaggedMessageToken[],\n renderers: Record<string, unknown>\n): ReactNode[] =>\n tokens.map((token, tokenIndex) => {\n if (typeof token === 'string') return token;\n const children = renderRichTokens(token.children, renderers);\n const renderer = renderers[token.tag];\n if (typeof renderer === 'function') {\n return (\n <Fragment key={tokenIndex}>\n {(renderer as RichRenderer)(<>{children}</>)}\n </Fragment>\n );\n }\n return <Fragment key={tokenIndex}>{children}</Fragment>;\n });\n\n/** Partitions values into scalar interpolation params and tag renderers. */\nconst splitRichValues = (\n values: Record<string, unknown>\n): { scalarValues: MessageValues; renderers: Record<string, unknown> } => {\n const scalarValues: MessageValues = {};\n const renderers: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(values)) {\n if (typeof value === 'function') renderers[key] = value;\n else scalarValues[key] = value as MessageValues[string];\n }\n return { scalarValues, renderers };\n};\n\nconst isRichValues = (values: Record<string, unknown>): boolean =>\n Object.values(values).some((value) => typeof value === 'function');\n\n/**\n * Builds an intlayer-backed `IntlShape` object for the given locale.\n *\n * - Translation ids use the first dot-path segment as the dictionary key.\n * - Full ICU MessageFormat syntax is supported via `@intlayer/core/messageFormat`.\n * - Rich text tags (`<b>chunks</b>`) are resolved through render functions in `values`.\n */\nexport const createIntlObject = (locale: LocalesValues): IntlShape => {\n const localeString = locale as string;\n\n const formatMessage = (\n descriptor: MessageDescriptor,\n values?: Record<string, unknown>\n ): string | ReactNode[] => {\n const { id = '', defaultMessage } = descriptor;\n const rawValue = lookupMessage(id, locale);\n const messageTemplate =\n rawValue !== undefined && rawValue !== null\n ? (rawValue as string)\n : typeof defaultMessage === 'string'\n ? defaultMessage\n : id;\n\n if (!values || !isRichValues(values)) {\n return (\n resolveMessage(\n messageTemplate,\n (values ?? {}) as MessageValues,\n locale,\n 'icu'\n ) ?? id\n );\n }\n\n const { scalarValues, renderers } = splitRichValues(values);\n const message =\n resolveMessage(messageTemplate, scalarValues, locale, 'icu') ?? id;\n return renderRichTokens(parseTaggedMessage(message), renderers);\n };\n\n const toDate = (value: Date | number | string): Date =>\n value instanceof Date ? value : new Date(value);\n\n const formatDate = (\n value: string | number | Date | undefined,\n options?: Intl.DateTimeFormatOptions\n ): string => {\n if (value === undefined || value === null) return '';\n return new Intl.DateTimeFormat(localeString, options).format(toDate(value));\n };\n\n const formatNumber = (\n value: number | bigint,\n options?: Intl.NumberFormatOptions\n ): string => new Intl.NumberFormat(localeString, options).format(value);\n\n const formatPlural = (\n value: number,\n options?: Intl.PluralRulesOptions\n ): Intl.LDMLPluralRule =>\n new Intl.PluralRules(localeString, options).select(value);\n\n const formatList = (\n list: Iterable<unknown> | readonly unknown[],\n options?: Intl.ListFormatOptions\n ): string => {\n const strings = Array.from(list).filter(\n (item): item is string => typeof item === 'string'\n );\n return new Intl.ListFormat(localeString, options).format(strings);\n };\n\n const formatListToParts = (\n list: Iterable<unknown> | readonly unknown[],\n options?: Intl.ListFormatOptions\n ): ReturnType<Intl.ListFormat['formatToParts']> => {\n const strings = Array.from(list).filter(\n (item): item is string => typeof item === 'string'\n );\n return new Intl.ListFormat(localeString, options).formatToParts(strings);\n };\n\n const formatDisplayName = (\n value: string,\n options?: Intl.DisplayNamesOptions\n ): string | undefined =>\n new Intl.DisplayNames([localeString], options ?? { type: 'language' }).of(\n value\n );\n\n const formatRelativeTime = (\n value: number,\n unit?: Intl.RelativeTimeFormatUnit,\n options?: Intl.RelativeTimeFormatOptions\n ): string =>\n new Intl.RelativeTimeFormat(localeString, {\n numeric: 'auto',\n ...options,\n }).format(value, unit ?? 'second');\n\n const formatDateTimeRange = (\n from: Date | number,\n to: Date | number,\n options?: Intl.DateTimeFormatOptions\n ): string =>\n new Intl.DateTimeFormat(localeString, options).formatRange(\n toDate(from),\n toDate(to)\n );\n\n const formatDateToParts = (\n value: Parameters<Intl.DateTimeFormat['format']>[0] | string,\n options?: Intl.DateTimeFormatOptions\n ): Intl.DateTimeFormatPart[] =>\n new Intl.DateTimeFormat(localeString, options).formatToParts(\n typeof value === 'string' ? new Date(value) : value\n );\n\n const formatNumberToParts = (\n value: number | bigint,\n options?: Intl.NumberFormatOptions\n ): Intl.NumberFormatPart[] =>\n new Intl.NumberFormat(localeString, options).formatToParts(value);\n\n /** Alias of `formatMessage` — provided for `@formatjs/intl` v4 compatibility. */\n const $t = formatMessage as IntlShape['$t'];\n\n return {\n locale: localeString,\n defaultLocale: localeString,\n messages: {},\n formats: {},\n defaultFormats: {},\n timeZone: undefined,\n textComponent: Fragment,\n wrapRichTextChunksInFragment: false,\n fallbackOnEmptyString: true,\n onError: () => {},\n onWarn: () => {},\n formatters: {} as IntlShape['formatters'],\n formatMessage: formatMessage as IntlShape['formatMessage'],\n $t,\n formatDate,\n formatTime: formatDate,\n formatNumber,\n formatPlural,\n formatList: formatList as IntlShape['formatList'],\n formatListToParts: formatListToParts as IntlShape['formatListToParts'],\n formatDisplayName: formatDisplayName as IntlShape['formatDisplayName'],\n formatRelativeTime,\n formatDateTimeRange,\n formatDateToParts: formatDateToParts as IntlShape['formatDateToParts'],\n formatTimeToParts: formatDateToParts as IntlShape['formatTimeToParts'],\n formatNumberToParts:\n formatNumberToParts as IntlShape['formatNumberToParts'],\n } as unknown as IntlShape;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/defineMessages.ts
|
|
2
|
+
/**
|
|
3
|
+
* Drop-in for react-intl's `defineMessages`.
|
|
4
|
+
* Identity function — returns the map unchanged.
|
|
5
|
+
* Exists so that IDEs and the intlayer analyzer can locate message ids
|
|
6
|
+
* at source-analysis time.
|
|
7
|
+
*/
|
|
8
|
+
const defineMessages = (messages) => messages;
|
|
9
|
+
/**
|
|
10
|
+
* Drop-in for react-intl's `defineMessage`.
|
|
11
|
+
* Identity function — returns the descriptor unchanged.
|
|
12
|
+
*/
|
|
13
|
+
const defineMessage = (message) => message;
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { defineMessage, defineMessages };
|
|
17
|
+
//# sourceMappingURL=defineMessages.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineMessages.mjs","names":[],"sources":["../../src/defineMessages.ts"],"sourcesContent":["import type {\n defineMessage as _defineMessage,\n defineMessages as _defineMessages,\n} from 'react-intl';\n\n/**\n * Drop-in for react-intl's `defineMessages`.\n * Identity function — returns the map unchanged.\n * Exists so that IDEs and the intlayer analyzer can locate message ids\n * at source-analysis time.\n */\nexport const defineMessages: typeof _defineMessages = (messages) => messages;\n\n/**\n * Drop-in for react-intl's `defineMessage`.\n * Identity function — returns the descriptor unchanged.\n */\nexport const defineMessage: typeof _defineMessage = (message) => message;\n"],"mappings":";;;;;;;AAWA,MAAa,kBAA0C,aAAa;;;;;AAMpE,MAAa,iBAAwC,YAAY"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/errors.ts
|
|
2
|
+
/**
|
|
3
|
+
* Error code enum matching react-intl's `ReactIntlErrorCode`.
|
|
4
|
+
*
|
|
5
|
+
* @deprecated These error codes are not raised by the intlayer compat adapter.
|
|
6
|
+
* Exported for API compatibility only.
|
|
7
|
+
*/
|
|
8
|
+
let ReactIntlErrorCode = /* @__PURE__ */ function(ReactIntlErrorCode) {
|
|
9
|
+
ReactIntlErrorCode["FORMAT_ERROR"] = "FORMAT_ERROR";
|
|
10
|
+
ReactIntlErrorCode["UNSUPPORTED_FORMATTER"] = "UNSUPPORTED_FORMATTER";
|
|
11
|
+
ReactIntlErrorCode["INVALID_CONFIG"] = "INVALID_CONFIG";
|
|
12
|
+
ReactIntlErrorCode["MISSING_DATA"] = "MISSING_DATA";
|
|
13
|
+
ReactIntlErrorCode["MISSING_TRANSLATION"] = "MISSING_TRANSLATION";
|
|
14
|
+
return ReactIntlErrorCode;
|
|
15
|
+
}({});
|
|
16
|
+
/**
|
|
17
|
+
* Base error class matching react-intl's `ReactIntlError` shape.
|
|
18
|
+
*
|
|
19
|
+
* @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.
|
|
20
|
+
*/
|
|
21
|
+
var ReactIntlError = class extends Error {
|
|
22
|
+
code;
|
|
23
|
+
constructor(code, message) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.name = "ReactIntlError";
|
|
26
|
+
this.code = code;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.
|
|
31
|
+
*/
|
|
32
|
+
var InvalidConfigError = class extends ReactIntlError {
|
|
33
|
+
constructor(message) {
|
|
34
|
+
super("INVALID_CONFIG", message);
|
|
35
|
+
this.name = "InvalidConfigError";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.
|
|
40
|
+
*/
|
|
41
|
+
var MessageFormatError = class extends ReactIntlError {
|
|
42
|
+
constructor(message) {
|
|
43
|
+
super("FORMAT_ERROR", message);
|
|
44
|
+
this.name = "MessageFormatError";
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.
|
|
49
|
+
*/
|
|
50
|
+
var MissingDataError = class extends ReactIntlError {
|
|
51
|
+
constructor(message) {
|
|
52
|
+
super("MISSING_DATA", message);
|
|
53
|
+
this.name = "MissingDataError";
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.
|
|
58
|
+
*/
|
|
59
|
+
var MissingTranslationError = class extends ReactIntlError {
|
|
60
|
+
constructor(message) {
|
|
61
|
+
super("MISSING_TRANSLATION", message);
|
|
62
|
+
this.name = "MissingTranslationError";
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.
|
|
67
|
+
*/
|
|
68
|
+
var UnsupportedFormatterError = class extends ReactIntlError {
|
|
69
|
+
constructor(message) {
|
|
70
|
+
super("UNSUPPORTED_FORMATTER", message);
|
|
71
|
+
this.name = "UnsupportedFormatterError";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
export { InvalidConfigError, MessageFormatError, MissingDataError, MissingTranslationError, ReactIntlError, ReactIntlErrorCode, UnsupportedFormatterError };
|
|
77
|
+
//# sourceMappingURL=errors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../../src/errors.ts"],"sourcesContent":["/**\n * Error code enum matching react-intl's `ReactIntlErrorCode`.\n *\n * @deprecated These error codes are not raised by the intlayer compat adapter.\n * Exported for API compatibility only.\n */\nexport enum ReactIntlErrorCode {\n FORMAT_ERROR = 'FORMAT_ERROR',\n UNSUPPORTED_FORMATTER = 'UNSUPPORTED_FORMATTER',\n INVALID_CONFIG = 'INVALID_CONFIG',\n MISSING_DATA = 'MISSING_DATA',\n MISSING_TRANSLATION = 'MISSING_TRANSLATION',\n}\n\n/**\n * Base error class matching react-intl's `ReactIntlError` shape.\n *\n * @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.\n */\nexport class ReactIntlError extends Error {\n public readonly code: ReactIntlErrorCode;\n\n constructor(code: ReactIntlErrorCode, message: string) {\n super(message);\n this.name = 'ReactIntlError';\n this.code = code;\n }\n}\n\n/**\n * @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.\n */\nexport class InvalidConfigError extends ReactIntlError {\n constructor(message: string) {\n super(ReactIntlErrorCode.INVALID_CONFIG, message);\n this.name = 'InvalidConfigError';\n }\n}\n\n/**\n * @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.\n */\nexport class MessageFormatError extends ReactIntlError {\n constructor(message: string) {\n super(ReactIntlErrorCode.FORMAT_ERROR, message);\n this.name = 'MessageFormatError';\n }\n}\n\n/**\n * @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.\n */\nexport class MissingDataError extends ReactIntlError {\n constructor(message: string) {\n super(ReactIntlErrorCode.MISSING_DATA, message);\n this.name = 'MissingDataError';\n }\n}\n\n/**\n * @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.\n */\nexport class MissingTranslationError extends ReactIntlError {\n constructor(message: string) {\n super(ReactIntlErrorCode.MISSING_TRANSLATION, message);\n this.name = 'MissingTranslationError';\n }\n}\n\n/**\n * @deprecated Not raised by the intlayer compat adapter. Exported for API compatibility only.\n */\nexport class UnsupportedFormatterError extends ReactIntlError {\n constructor(message: string) {\n super(ReactIntlErrorCode.UNSUPPORTED_FORMATTER, message);\n this.name = 'UnsupportedFormatterError';\n }\n}\n"],"mappings":";;;;;;;AAMA,IAAY,qBAAL;CACL;CACA;CACA;CACA;CACA;;AACF;;;;;;AAOA,IAAa,iBAAb,cAAoC,MAAM;CACxC,AAAgB;CAEhB,YAAY,MAA0B,SAAiB;EACrD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,qBAAb,cAAwC,eAAe;CACrD,YAAY,SAAiB;EAC3B,wBAAyC,OAAO;EAChD,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,qBAAb,cAAwC,eAAe;CACrD,YAAY,SAAiB;EAC3B,sBAAuC,OAAO;EAC9C,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,mBAAb,cAAsC,eAAe;CACnD,YAAY,SAAiB;EAC3B,sBAAuC,OAAO;EAC9C,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,0BAAb,cAA6C,eAAe;CAC1D,YAAY,SAAiB;EAC3B,6BAA8C,OAAO;EACrD,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,4BAAb,cAA+C,eAAe;CAC5D,YAAY,SAAiB;EAC3B,+BAAgD,OAAO;EACvD,KAAK,OAAO;CACd;AACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { IntlContext, RawIntlProvider } from "./context.mjs";
|
|
4
|
+
import { IntlProvider } from "./IntlProvider.mjs";
|
|
5
|
+
import { useIntl } from "./useIntl.mjs";
|
|
6
|
+
import { FormattedDate, FormattedDateParts, FormattedDateTimeRange, FormattedDisplayName, FormattedList, FormattedListParts, FormattedNumber, FormattedNumberParts, FormattedPlural, FormattedRelativeTime, FormattedTime, FormattedTimeParts } from "./FormattedComponents.mjs";
|
|
7
|
+
import { InvalidConfigError, MessageFormatError, MissingDataError, MissingTranslationError, ReactIntlError, ReactIntlErrorCode, UnsupportedFormatterError } from "./errors.mjs";
|
|
8
|
+
import { defineMessage, defineMessages } from "./defineMessages.mjs";
|
|
9
|
+
import { createIntl, createIntlCache } from "./createIntl.mjs";
|
|
10
|
+
import { FormattedMessage } from "./FormattedMessage.mjs";
|
|
11
|
+
|
|
12
|
+
export { FormattedDate, FormattedDateParts, FormattedDateTimeRange, FormattedDisplayName, FormattedList, FormattedListParts, FormattedMessage, FormattedNumber, FormattedNumberParts, FormattedPlural, FormattedRelativeTime, FormattedTime, FormattedTimeParts, IntlContext, IntlProvider, InvalidConfigError, MessageFormatError, MissingDataError, MissingTranslationError, RawIntlProvider, ReactIntlError, ReactIntlErrorCode, UnsupportedFormatterError, createIntl, createIntlCache, defineMessage, defineMessages, useIntl };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as ANSIColors from "@intlayer/config/colors";
|
|
2
|
+
import { colorize, getAppLogger } from "@intlayer/config/logger";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { runOnce } from "@intlayer/chokidar/utils";
|
|
5
|
+
import { getConfiguration } from "@intlayer/config/node";
|
|
6
|
+
import { intlayer } from "vite-intlayer";
|
|
7
|
+
|
|
8
|
+
//#region src/plugin/index.ts
|
|
9
|
+
/**
|
|
10
|
+
* Caller configuration for react-intl's `useIntl()`.
|
|
11
|
+
*
|
|
12
|
+
* Tracks the `useIntl` call so its return value (the intl object) is marked
|
|
13
|
+
* as the translation accessor for the current component. Field-level pruning
|
|
14
|
+
* via `formatMessage({id})` requires `namespace: { from: 'path-first-segment' }`
|
|
15
|
+
* which is not yet supported by the babel/swc analyser — it will be added in
|
|
16
|
+
* a future release. For now, the alias mapping is the primary compat mechanism.
|
|
17
|
+
*/
|
|
18
|
+
const REACT_INTL_COMPAT_CALLERS = [];
|
|
19
|
+
/**
|
|
20
|
+
* A Vite plugin for react-intl compat that wraps vite-intlayer
|
|
21
|
+
* and injects a resolve alias mapping `react-intl` to
|
|
22
|
+
* `@intlayer/react-intl`.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* // vite.config.ts
|
|
27
|
+
* import reactIntlVitePlugin from '@intlayer/react-intl/plugin';
|
|
28
|
+
*
|
|
29
|
+
* export default defineConfig({
|
|
30
|
+
* plugins: [reactIntlVitePlugin()],
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
const reactIntlVitePlugin = (options) => {
|
|
35
|
+
const intlayerConfig = getConfiguration();
|
|
36
|
+
const appLogger = getAppLogger(intlayerConfig);
|
|
37
|
+
runOnce(join(intlayerConfig.system.baseDir, ".intlayer", "cache", "intlayer-issues-invitation.lock"), () => {
|
|
38
|
+
appLogger([colorize("Please report any issues you met on GitHub:", ANSIColors.GREY), colorize("https://github.com/aymericzip/intlayer/issues", ANSIColors.GREY_LIGHT)]);
|
|
39
|
+
}, { cacheTimeoutMs: 1e3 * 60 * 60 });
|
|
40
|
+
const basePlugins = intlayer({
|
|
41
|
+
...options,
|
|
42
|
+
compatCallers: [...options?.compatCallers ?? [], ...REACT_INTL_COMPAT_CALLERS]
|
|
43
|
+
});
|
|
44
|
+
const compatPlugin = {
|
|
45
|
+
name: "vite-react-intl-compat-plugin",
|
|
46
|
+
config: () => ({ resolve: { alias: { "react-intl": "@intlayer/react-intl" } } })
|
|
47
|
+
};
|
|
48
|
+
return [...Array.isArray(basePlugins) ? basePlugins : [basePlugins], compatPlugin];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
export { reactIntlVitePlugin as default, reactIntlVitePlugin };
|
|
53
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"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 configuration for react-intl's `useIntl()`.\n *\n * Tracks the `useIntl` call so its return value (the intl object) is marked\n * as the translation accessor for the current component. Field-level pruning\n * via `formatMessage({id})` requires `namespace: { from: 'path-first-segment' }`\n * which is not yet supported by the babel/swc analyser — it will be added in\n * a future release. For now, the alias mapping is the primary compat mechanism.\n */\nconst REACT_INTL_COMPAT_CALLERS: CompatCallerConfig[] = [];\n\n/**\n * A Vite plugin for react-intl compat that wraps vite-intlayer\n * and injects a resolve alias mapping `react-intl` to\n * `@intlayer/react-intl`.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import reactIntlVitePlugin from '@intlayer/react-intl/plugin';\n *\n * export default defineConfig({\n * plugins: [reactIntlVitePlugin()],\n * });\n * ```\n */\nexport const reactIntlVitePlugin = (\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 ...REACT_INTL_COMPAT_CALLERS,\n ],\n });\n\n const compatPlugin: PluginOption = {\n name: 'vite-react-intl-compat-plugin',\n config: () => ({\n resolve: {\n alias: {\n 'react-intl': '@intlayer/react-intl',\n },\n },\n }),\n };\n\n return [\n ...(Array.isArray(basePlugins) ? basePlugins : [basePlugins]),\n compatPlugin,\n ];\n};\n\nexport default reactIntlVitePlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,MAAM,4BAAkD,CAAC;;;;;;;;;;;;;;;;AAiBzD,MAAa,uBACX,YACmB;CACnB,MAAM,iBAAiB,iBAAiB;CACxC,MAAM,YAAY,aAAa,cAAc;CAE7C,QACE,KACE,eAAe,OAAO,SACtB,aACA,SACA,iCACF,SACM;EACJ,UAAU,CACR,SACE,+CACA,WAAW,IACb,GACA,SACE,iDACA,WAAW,UACb,CACF,CAAC;CACH,GACA,EACE,gBAAgB,MAAO,KAAK,GAC9B,CACF;CAEA,MAAM,cAAc,SAAS;EAC3B,GAAG;EACH,eAAe,CACb,GAAI,SAAS,iBAAiB,CAAC,GAC/B,GAAG,yBACL;CACF,CAAC;CAED,MAAM,eAA6B;EACjC,MAAM;EACN,eAAe,EACb,SAAS,EACP,OAAO,EACL,cAAc,uBAChB,EACF,EACF;CACF;CAEA,OAAO,CACL,GAAI,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,WAAW,GAC3D,YACF;AACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { IntlContext } from "./context.mjs";
|
|
4
|
+
import { createIntlObject } from "./createIntlObject.mjs";
|
|
5
|
+
import { useContext, useMemo } from "react";
|
|
6
|
+
import { useLocale } from "react-intlayer";
|
|
7
|
+
|
|
8
|
+
//#region src/useIntl.ts
|
|
9
|
+
/**
|
|
10
|
+
* Drop-in for react-intl's `useIntl`.
|
|
11
|
+
*
|
|
12
|
+
* Returns the active `IntlShape` instance. When used inside an
|
|
13
|
+
* {@link IntlProvider} the instance comes from context; otherwise it is
|
|
14
|
+
* derived from `react-intlayer`'s locale context on the fly.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* const intl = useIntl();
|
|
19
|
+
* intl.formatMessage({ id: 'home.title' });
|
|
20
|
+
* intl.formatNumber(42, { style: 'currency', currency: 'USD' });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
const useIntl = () => {
|
|
24
|
+
const contextIntl = useContext(IntlContext);
|
|
25
|
+
const { locale } = useLocale();
|
|
26
|
+
const derivedIntl = useMemo(() => createIntlObject(locale), [locale]);
|
|
27
|
+
return contextIntl ?? derivedIntl;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { useIntl };
|
|
32
|
+
//# sourceMappingURL=useIntl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIntl.mjs","names":[],"sources":["../../src/useIntl.ts"],"sourcesContent":["'use client';\n\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { useContext, useMemo } from 'react';\nimport type { useIntl as _useIntl } from 'react-intl';\nimport { useLocale } from 'react-intlayer';\nimport { IntlContext } from './context';\nimport { createIntlObject } from './createIntlObject';\n\n/**\n * Drop-in for react-intl's `useIntl`.\n *\n * Returns the active `IntlShape` instance. When used inside an\n * {@link IntlProvider} the instance comes from context; otherwise it is\n * derived from `react-intlayer`'s locale context on the fly.\n *\n * @example\n * ```tsx\n * const intl = useIntl();\n * intl.formatMessage({ id: 'home.title' });\n * intl.formatNumber(42, { style: 'currency', currency: 'USD' });\n * ```\n */\nexport const useIntl: typeof _useIntl = () => {\n const contextIntl = useContext(IntlContext);\n const { locale } = useLocale();\n\n const derivedIntl = useMemo(\n () => createIntlObject(locale as LocalesValues),\n [locale]\n );\n\n return contextIntl ?? derivedIntl;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,gBAAiC;CAC5C,MAAM,cAAc,WAAW,WAAW;CAC1C,MAAM,EAAE,WAAW,UAAU;CAE7B,MAAM,cAAc,cACZ,iBAAiB,MAAuB,GAC9C,CAAC,MAAM,CACT;CAEA,OAAO,eAAe;AACxB"}
|