@intlayer/react-intl 9.0.0-canary.11 → 9.0.0-canary.13

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.
@@ -1,6 +1,6 @@
1
1
  import { Fragment } from "react";
2
2
  import { getIntlayer } from "@intlayer/core/interpreter";
3
- import { parseTaggedMessage, resolveMessage } from "@intlayer/core/messageFormat";
3
+ import { navigatePath, parseTaggedMessage, resolveMessage } from "@intlayer/core/messageFormat";
4
4
  import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
5
5
 
6
6
  //#region src/createIntlObject.tsx
@@ -16,16 +16,6 @@ const splitId = (id) => {
16
16
  path: id.slice(dotIndex + 1)
17
17
  };
18
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
19
  /** Looks up a message value by full dotted id; first segment = dictionary key. */
30
20
  const lookupMessage = (id, locale) => {
31
21
  const { dictionaryKey, path } = splitId(id);
@@ -62,12 +52,16 @@ const isRichValues = (values) => Object.values(values).some((value) => typeof va
62
52
  * - Translation ids use the first dot-path segment as the dictionary key.
63
53
  * - Full ICU MessageFormat syntax is supported via `@intlayer/core/messageFormat`.
64
54
  * - Rich text tags (`<b>chunks</b>`) are resolved through render functions in `values`.
55
+ *
56
+ * @param locale - The locale messages are resolved for.
57
+ * @param lookupOverride - Optional message lookup replacing the registry-based
58
+ * id resolution; used by the dictionary-bound `useDictionary` variant.
65
59
  */
66
- const createIntlObject = (locale) => {
60
+ const createIntlObject = (locale, lookupOverride) => {
67
61
  const localeString = locale;
68
62
  const formatMessage = (descriptor, values) => {
69
63
  const { id = "", defaultMessage } = descriptor;
70
- const rawValue = lookupMessage(id, locale);
64
+ const rawValue = lookupOverride ? lookupOverride(id) : lookupMessage(id, locale);
71
65
  const messageTemplate = rawValue !== void 0 && rawValue !== null ? rawValue : typeof defaultMessage === "string" ? defaultMessage : id;
72
66
  if (!values || !isRichValues(values)) return resolveMessage(messageTemplate, values ?? {}, locale, "icu") ?? id;
73
67
  const { scalarValues, renderers } = splitRichValues(values);
@@ -1 +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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"}
1
+ {"version":3,"file":"createIntlObject.mjs","names":[],"sources":["../../src/createIntlObject.tsx"],"sourcesContent":["import { getIntlayer } from '@intlayer/core/interpreter';\nimport {\n type MessageValues,\n navigatePath,\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\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 *\n * @param locale - The locale messages are resolved for.\n * @param lookupOverride - Optional message lookup replacing the registry-based\n * id resolution; used by the dictionary-bound `useDictionary` variant.\n */\nexport const createIntlObject = (\n locale: LocalesValues,\n lookupOverride?: (id: string) => unknown\n): 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 = lookupOverride\n ? lookupOverride(id)\n : 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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"}
File without changes
@@ -8,5 +8,7 @@ import { InvalidConfigError, MessageFormatError, MissingDataError, MissingTransl
8
8
  import { defineMessage, defineMessages } from "./defineMessages.mjs";
9
9
  import { createIntl, createIntlCache } from "./createIntl.mjs";
10
10
  import { FormattedMessage } from "./FormattedMessage.mjs";
11
+ import { useDictionary } from "./useDictionary.mjs";
12
+ import { useDictionaryDynamic } from "./useDictionaryDynamic.mjs";
11
13
 
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 };
14
+ 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, useDictionary, useDictionaryDynamic, useIntl };
@@ -1,46 +1,13 @@
1
1
  import * as ANSIColors from "@intlayer/config/colors";
2
2
  import { colorize, getAppLogger } from "@intlayer/config/logger";
3
3
  import { join } from "node:path";
4
- import { runOnce } from "@intlayer/chokidar/utils";
4
+ import { REACT_INTL_CALLERS } from "@intlayer/config/callers";
5
5
  import { getConfiguration } from "@intlayer/config/node";
6
+ import { runOnce } from "@intlayer/engine/utils";
6
7
  import { intlayer } from "vite-intlayer";
7
8
 
8
9
  //#region src/plugin/index.ts
9
10
  /**
10
- * Caller configurations for react-intl's two message APIs.
11
- *
12
- * react-intl encodes both the dictionary key and the field path in a single
13
- * dotted id string, so the `path-first-segment` namespace source extracts the
14
- * first segment as the dictionary key and `translationFunction: 'self'` records
15
- * the second segment as the consumed field:
16
- *
17
- * `'home.title'` → dictionaryKey='home', field='title'
18
- * `'greeting'` → dictionaryKey='greeting', field='all' (single segment)
19
- * dynamic id → unresolvable → skipped (all fields kept)
20
- *
21
- * Both call sites are tracked:
22
- * - `intl.formatMessage({ id })` — matched as a method on any object.
23
- * - `<FormattedMessage id />` — matched as a JSX element (import-gated).
24
- *
25
- * The JSX form is mandatory: the prune context is shared across all files, so
26
- * tracking only `formatMessage` would let a field referenced solely from
27
- * `<FormattedMessage>` be pruned away whenever the same dictionary is also read
28
- * through `formatMessage`.
29
- */
30
- const REACT_INTL_COMPAT_CALLERS = [{
31
- callerName: "formatMessage",
32
- importSources: ["react-intl", "@intlayer/react-intl"],
33
- matchAsMethod: true,
34
- namespace: { from: "path-first-segment" },
35
- translationFunction: "self"
36
- }, {
37
- callerName: "FormattedMessage",
38
- importSources: ["react-intl", "@intlayer/react-intl"],
39
- jsxIdAttribute: "id",
40
- namespace: { from: "path-first-segment" },
41
- translationFunction: "self"
42
- }];
43
- /**
44
11
  * A Vite plugin for react-intl compat that wraps vite-intlayer
45
12
  * and injects a resolve alias mapping `react-intl` to
46
13
  * `@intlayer/react-intl`.
@@ -63,7 +30,7 @@ const reactIntlVitePlugin = (options) => {
63
30
  }, { cacheTimeoutMs: 1e3 * 60 * 60 });
64
31
  const basePlugins = intlayer({
65
32
  ...options,
66
- compatCallers: [...options?.compatCallers ?? [], ...REACT_INTL_COMPAT_CALLERS]
33
+ compatCallers: [...options?.compatCallers ?? [], ...REACT_INTL_CALLERS]
67
34
  });
68
35
  const compatPlugin = {
69
36
  name: "vite-react-intl-compat-plugin",
@@ -1 +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 configurations for react-intl's two message APIs.\n *\n * react-intl encodes both the dictionary key and the field path in a single\n * dotted id string, so the `path-first-segment` namespace source extracts the\n * first segment as the dictionary key and `translationFunction: 'self'` records\n * the second segment as the consumed field:\n *\n * `'home.title'` → dictionaryKey='home', field='title'\n * `'greeting'` → dictionaryKey='greeting', field='all' (single segment)\n * dynamic id → unresolvable → skipped (all fields kept)\n *\n * Both call sites are tracked:\n * - `intl.formatMessage({ id })` — matched as a method on any object.\n * - `<FormattedMessage id />` — matched as a JSX element (import-gated).\n *\n * The JSX form is mandatory: the prune context is shared across all files, so\n * tracking only `formatMessage` would let a field referenced solely from\n * `<FormattedMessage>` be pruned away whenever the same dictionary is also read\n * through `formatMessage`.\n */\nconst REACT_INTL_COMPAT_CALLERS: CompatCallerConfig[] = [\n {\n callerName: 'formatMessage',\n importSources: ['react-intl', '@intlayer/react-intl'],\n matchAsMethod: true,\n namespace: { from: 'path-first-segment' },\n translationFunction: 'self',\n },\n // `<FormattedMessage id=\"home.title\" />` — the dominant react-intl API. This\n // JSX form MUST be tracked alongside `formatMessage`: the prune context is\n // global across files, so a field referenced only from JSX would otherwise be\n // pruned away when the same dictionary is also read via `formatMessage`.\n {\n callerName: 'FormattedMessage',\n importSources: ['react-intl', '@intlayer/react-intl'],\n jsxIdAttribute: 'id',\n namespace: { from: 'path-first-segment' },\n translationFunction: 'self',\n },\n];\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAM,4BAAkD,CACtD;CACE,YAAY;CACZ,eAAe,CAAC,cAAc,sBAAsB;CACpD,eAAe;CACf,WAAW,EAAE,MAAM,qBAAqB;CACxC,qBAAqB;AACvB,GAKA;CACE,YAAY;CACZ,eAAe,CAAC,cAAc,sBAAsB;CACpD,gBAAgB;CAChB,WAAW,EAAE,MAAM,qBAAqB;CACxC,qBAAqB;AACvB,CACF;;;;;;;;;;;;;;;;AAiBA,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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { REACT_INTL_CALLERS } from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { PluginOption } from 'vite';\nimport { intlayer } from 'vite-intlayer';\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: [...(options?.compatCallers ?? []), ...REACT_INTL_CALLERS],\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":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,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,CAAC,GAAI,SAAS,iBAAiB,CAAC,GAAI,GAAG,kBAAkB;CAC1E,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"}
File without changes
@@ -0,0 +1,45 @@
1
+ 'use client';
2
+
3
+ import { createIntlObject } from "./createIntlObject.mjs";
4
+ import { useMemo } from "react";
5
+ import { useDictionary as useDictionary$1, useLocale } from "react-intlayer";
6
+ import { navigatePath } from "@intlayer/core/messageFormat";
7
+
8
+ //#region src/useDictionary.ts
9
+ /**
10
+ * Builds the id lookup of a dictionary-bound intl object.
11
+ *
12
+ * react-intl ids encode the dictionary key as their first dot-segment
13
+ * (`'home.title'` → dictionary `home`, field `title`). When the content is
14
+ * supplied directly, the leading `<dictionaryKey>.` is stripped so both the
15
+ * absolute (`'home.title'`) and relative (`'title'`) forms resolve.
16
+ */
17
+ const createDictionaryLookup = (dictionaryKey, content) => (id) => {
18
+ return navigatePath(content, id.startsWith(`${dictionaryKey}.`) ? id.slice(dictionaryKey.length + 1) : id === dictionaryKey ? "" : id);
19
+ };
20
+ /**
21
+ * Dictionary-accepting variant of `useIntl`.
22
+ *
23
+ * Returns an `IntlShape` whose `formatMessage` resolves ids inside the
24
+ * supplied dictionary instead of the runtime registry, enabling tree-shaking
25
+ * of unused locale content. All `Intl`-backed formatters (`formatNumber`,
26
+ * `formatDate`, …) behave exactly like `useIntl()`.
27
+ *
28
+ * @example
29
+ * import _abc from '.intlayer/dictionaries/home.json' with { type: 'json' };
30
+ * const intl = useDictionary(_abc);
31
+ * intl.formatMessage({ id: 'home.title' }); // or { id: 'title' } — both typed
32
+ */
33
+ const useDictionary = (dictionary) => {
34
+ const content = useDictionary$1(dictionary);
35
+ const { locale } = useLocale();
36
+ return useMemo(() => createIntlObject(locale, createDictionaryLookup(dictionary.key, content)), [
37
+ locale,
38
+ dictionary.key,
39
+ content
40
+ ]);
41
+ };
42
+
43
+ //#endregion
44
+ export { createDictionaryLookup, useDictionary };
45
+ //# sourceMappingURL=useDictionary.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDictionary.mjs","names":["useDictionaryBase"],"sources":["../../src/useDictionary.ts"],"sourcesContent":["'use client';\n\nimport { navigatePath } from '@intlayer/core/messageFormat';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { useMemo } from 'react';\nimport { useDictionary as useDictionaryBase, useLocale } from 'react-intlayer';\nimport { createIntlObject } from './createIntlObject';\nimport type { DictionaryIntlShape } from './dictionaryIntlShape';\n\n/**\n * Builds the id lookup of a dictionary-bound intl object.\n *\n * react-intl ids encode the dictionary key as their first dot-segment\n * (`'home.title'` → dictionary `home`, field `title`). When the content is\n * supplied directly, the leading `<dictionaryKey>.` is stripped so both the\n * absolute (`'home.title'`) and relative (`'title'`) forms resolve.\n */\nexport const createDictionaryLookup =\n (dictionaryKey: string, content: unknown) =>\n (id: string): unknown => {\n const relativePath = id.startsWith(`${dictionaryKey}.`)\n ? id.slice(dictionaryKey.length + 1)\n : id === dictionaryKey\n ? ''\n : id;\n return navigatePath(content, relativePath);\n };\n\n/**\n * Dictionary-accepting variant of `useIntl`.\n *\n * Returns an `IntlShape` whose `formatMessage` resolves ids inside the\n * supplied dictionary instead of the runtime registry, enabling tree-shaking\n * of unused locale content. All `Intl`-backed formatters (`formatNumber`,\n * `formatDate`, …) behave exactly like `useIntl()`.\n *\n * @example\n * import _abc from '.intlayer/dictionaries/home.json' with { type: 'json' };\n * const intl = useDictionary(_abc);\n * intl.formatMessage({ id: 'home.title' }); // or { id: 'title' } — both typed\n */\nexport const useDictionary = <T extends Dictionary>(\n dictionary: T\n): DictionaryIntlShape<T['key'] & DictionaryKeys> => {\n const content = useDictionaryBase(dictionary);\n const { locale } = useLocale();\n\n return useMemo(\n () =>\n createIntlObject(\n locale as LocalesValues,\n createDictionaryLookup(dictionary.key, content)\n ) as DictionaryIntlShape<T['key'] & DictionaryKeys>,\n [locale, dictionary.key, content]\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAqBA,MAAa,0BACV,eAAuB,aACvB,OAAwB;CAMvB,OAAO,aAAa,SALC,GAAG,WAAW,GAAG,cAAc,EAAE,IAClD,GAAG,MAAM,cAAc,SAAS,CAAC,IACjC,OAAO,gBACL,KACA,EACmC;AAC3C;;;;;;;;;;;;;;AAeF,MAAa,iBACX,eACmD;CACnD,MAAM,UAAUA,gBAAkB,UAAU;CAC5C,MAAM,EAAE,WAAW,UAAU;CAE7B,OAAO,cAEH,iBACE,QACA,uBAAuB,WAAW,KAAK,OAAO,CAChD,GACF;EAAC;EAAQ,WAAW;EAAK;CAAO,CAClC;AACF"}
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+
3
+ import { createIntlObject } from "./createIntlObject.mjs";
4
+ import { createDictionaryLookup } from "./useDictionary.mjs";
5
+ import { useMemo } from "react";
6
+ import { useDictionaryDynamic as useDictionaryDynamic$1, useLocale } from "react-intlayer";
7
+
8
+ //#region src/useDictionaryDynamic.ts
9
+ /**
10
+ * Dynamic dictionary-accepting variant of `useIntl`.
11
+ *
12
+ * Counterpart to {@link useDictionary} for dictionaries imported lazily per
13
+ * locale. Used internally by the build-time optimization.
14
+ */
15
+ const useDictionaryDynamic = (dictionaryPromise, key) => {
16
+ const content = useDictionaryDynamic$1(dictionaryPromise, key);
17
+ const { locale } = useLocale();
18
+ return useMemo(() => createIntlObject(locale, createDictionaryLookup(key, content)), [
19
+ locale,
20
+ key,
21
+ content
22
+ ]);
23
+ };
24
+
25
+ //#endregion
26
+ export { useDictionaryDynamic };
27
+ //# sourceMappingURL=useDictionaryDynamic.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDictionaryDynamic.mjs","names":["useDictionaryDynamicBase"],"sources":["../../src/useDictionaryDynamic.ts"],"sourcesContent":["'use client';\n\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useMemo } from 'react';\nimport {\n useDictionaryDynamic as useDictionaryDynamicBase,\n useLocale,\n} from 'react-intlayer';\nimport { createIntlObject } from './createIntlObject';\nimport type { DictionaryIntlShape } from './dictionaryIntlShape';\nimport { createDictionaryLookup } from './useDictionary';\n\n/**\n * Dynamic dictionary-accepting variant of `useIntl`.\n *\n * Counterpart to {@link useDictionary} for dictionaries imported lazily per\n * locale. Used internally by the build-time optimization.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K\n): DictionaryIntlShape<K> => {\n const content = useDictionaryDynamicBase<T, K>(dictionaryPromise, key);\n const { locale } = useLocale();\n\n return useMemo(\n () =>\n createIntlObject(\n locale as LocalesValues,\n createDictionaryLookup(key, content)\n ) as DictionaryIntlShape<K>,\n [locale, key, content]\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AAuBA,MAAa,wBAIX,mBACA,QAC2B;CAC3B,MAAM,UAAUA,uBAA+B,mBAAmB,GAAG;CACrE,MAAM,EAAE,WAAW,UAAU;CAE7B,OAAO,cAEH,iBACE,QACA,uBAAuB,KAAK,OAAO,CACrC,GACF;EAAC;EAAQ;EAAK;CAAO,CACvB;AACF"}
@@ -8,8 +8,12 @@ import { LocalesValues } from "@intlayer/types/module_augmentation";
8
8
  * - Translation ids use the first dot-path segment as the dictionary key.
9
9
  * - Full ICU MessageFormat syntax is supported via `@intlayer/core/messageFormat`.
10
10
  * - Rich text tags (`<b>chunks</b>`) are resolved through render functions in `values`.
11
+ *
12
+ * @param locale - The locale messages are resolved for.
13
+ * @param lookupOverride - Optional message lookup replacing the registry-based
14
+ * id resolution; used by the dictionary-bound `useDictionary` variant.
11
15
  */
12
- declare const createIntlObject: (locale: LocalesValues) => IntlShape;
16
+ declare const createIntlObject: (locale: LocalesValues, lookupOverride?: (id: string) => unknown) => IntlShape;
13
17
  //#endregion
14
18
  export { createIntlObject };
15
19
  //# sourceMappingURL=createIntlObject.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createIntlObject.d.ts","names":[],"sources":["../../src/createIntlObject.tsx"],"mappings":";;;;;;AAiGA;;;;;cAAa,gBAAA,GAAoB,MAAA,EAAQ,aAAA,KAAgB,SAqJxD"}
1
+ {"version":3,"file":"createIntlObject.d.ts","names":[],"sources":["../../src/createIntlObject.tsx"],"mappings":";;;;;;AAqFA;;;;;;;;;cAAa,gBAAA,GACX,MAAA,EAAQ,aAAA,EACR,cAAA,IAAkB,EAAA,yBACjB,SAuJF"}
@@ -0,0 +1,54 @@
1
+ import { IntlShape, MessageDescriptor, PrimitiveType } from "react-intl";
2
+ import { DictionaryKeys } from "@intlayer/types/module_augmentation";
3
+ import { GetNestingResult } from "@intlayer/core/interpreter";
4
+ import { ValidDotPathsFor } from "@intlayer/core/transpiler";
5
+ import { ReactNode } from "react";
6
+
7
+ //#region src/dictionaryIntlShape.d.ts
8
+ /**
9
+ * The interpreter-resolved content type at dot-path `P` of dictionary `N` —
10
+ * the same type strength as the base `useIntlayer` hook.
11
+ */
12
+ type ContentAtPath<N extends DictionaryKeys, P> = GetNestingResult<N, P>;
13
+ /**
14
+ * The value returned by `formatMessage` for the path `P` of dictionary `N`:
15
+ * string literals declared in the dictionary keep their literal type, every
16
+ * other node resolves to `string` at runtime.
17
+ */
18
+ type TranslatedValue<N extends DictionaryKeys, P> = ContentAtPath<N, P> extends string ? ContentAtPath<N, P> : string;
19
+ /**
20
+ * Ids accepted by a dictionary-bound intl object: the dictionary's dot-paths,
21
+ * either relative (`'title'`) or absolute (`'home.title'`).
22
+ */
23
+ type DictionaryMessageIds<N extends DictionaryKeys> = ValidDotPathsFor<N> | `${N & string}.${ValidDotPathsFor<N> & string}`;
24
+ /**
25
+ * Resolves the translated value type for an id: the absolute form strips the
26
+ * leading `<dictionaryKey>.` first, matching the runtime lookup.
27
+ */
28
+ type MessageValueForId<N extends DictionaryKeys, Id extends string> = Id extends `${N & string}.${infer RelativePath}` ? TranslatedValue<N, RelativePath> : TranslatedValue<N, Id>;
29
+ /**
30
+ * `formatMessage` bound to dictionary `N`: ids are validated against the
31
+ * dictionary's dot-paths and the return type is resolved from the content at
32
+ * that path. With rich-text render functions in `values`, React nodes are
33
+ * returned.
34
+ */
35
+ type TypedFormatMessage<N extends DictionaryKeys> = {
36
+ <Id extends DictionaryMessageIds<N> & string>(descriptor: Omit<MessageDescriptor, 'id'> & {
37
+ id: Id;
38
+ }, values?: Record<string, PrimitiveType>): MessageValueForId<N, Id>;
39
+ <Id extends DictionaryMessageIds<N> & string>(descriptor: Omit<MessageDescriptor, 'id'> & {
40
+ id: Id;
41
+ }, values?: Record<string, ReactNode | PrimitiveType | ((chunks: ReactNode) => ReactNode)>): string | ReactNode[];
42
+ };
43
+ /**
44
+ * `IntlShape` whose `formatMessage` / `$t` are typed against the dictionary
45
+ * `N`. Returned by the dictionary-bound `useDictionary` /
46
+ * `useDictionaryDynamic` variants.
47
+ */
48
+ type DictionaryIntlShape<N extends DictionaryKeys> = Omit<IntlShape, 'formatMessage' | '$t'> & {
49
+ formatMessage: TypedFormatMessage<N>;
50
+ $t: TypedFormatMessage<N>;
51
+ };
52
+ //#endregion
53
+ export { DictionaryIntlShape, DictionaryMessageIds, MessageValueForId, TypedFormatMessage };
54
+ //# sourceMappingURL=dictionaryIntlShape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionaryIntlShape.d.ts","names":[],"sources":["../../src/dictionaryIntlShape.ts"],"mappings":";;;;;;;;;AAI8E;;KAMzE,aAAA,WAAwB,cAAA,OAAqB,gBAAA,CAAiB,CAAA,EAAG,CAAA;;;;;;KAOjE,eAAA,WAA0B,cAAA,OAC7B,aAAA,CAAc,CAAA,EAAG,CAAA,mBAAoB,aAAA,CAAc,CAAA,EAAG,CAAA;;;;;KAM5C,oBAAA,WAA+B,cAAA,IACvC,gBAAA,CAAiB,CAAA,OACd,CAAA,aAAc,gBAAA,CAAiB,CAAA;;;AAhBiC;AAAA;KAsB3D,iBAAA,WACA,cAAA,uBAER,EAAA,YAAc,CAAA,oCACd,eAAA,CAAgB,CAAA,EAAG,YAAA,IACnB,eAAA,CAAgB,CAAA,EAAG,EAAA;;;;;;;KAQX,kBAAA,WAA6B,cAAA;EAAA,YAC3B,oBAAA,CAAqB,CAAA,YAC/B,UAAA,EAAY,IAAA,CAAK,iBAAA;IAA6B,EAAA,EAAI,EAAA;EAAA,GAClD,MAAA,GAAS,MAAA,SAAe,aAAA,IACvB,iBAAA,CAAkB,CAAA,EAAG,EAAA;EAAA,YACZ,oBAAA,CAAqB,CAAA,YAC/B,UAAA,EAAY,IAAA,CAAK,iBAAA;IAA6B,EAAA,EAAI,EAAA;EAAA,GAClD,MAAA,GAAS,MAAA,SAEP,SAAA,GAAY,aAAA,KAAkB,MAAA,EAAQ,SAAA,KAAc,SAAA,cAE5C,SAAA;AAAA;;;;;;KAQF,mBAAA,WAA8B,cAAA,IAAkB,IAAA,CAC1D,SAAA;EAGA,aAAA,EAAe,kBAAA,CAAmB,CAAA;EAClC,EAAA,EAAI,kBAAA,CAAmB,CAAA;AAAA"}
@@ -4,7 +4,11 @@ import { IntlProvider } from "./IntlProvider.js";
4
4
  import { IntlContext, RawIntlProvider } from "./context.js";
5
5
  import { createIntl, createIntlCache } from "./createIntl.js";
6
6
  import { defineMessage, defineMessages } from "./defineMessages.js";
7
+ import { DictionaryIntlShape, DictionaryMessageIds, MessageValueForId, TypedFormatMessage } from "./dictionaryIntlShape.js";
7
8
  import { InvalidConfigError, MessageFormatError, MissingDataError, MissingTranslationError, ReactIntlError, ReactIntlErrorCode, UnsupportedFormatterError } from "./errors.js";
9
+ import { RootMessageIds } from "./typedMessageIds.js";
10
+ import { useDictionary } from "./useDictionary.js";
11
+ import { useDictionaryDynamic } from "./useDictionaryDynamic.js";
8
12
  import { useIntl } from "./useIntl.js";
9
13
  import { CustomFormats, FormatDateOptions, FormatDisplayNameOptions, FormatListOptions, FormatNumberOptions, FormatPluralOptions, FormatRelativeTimeOptions, Formatters, IntlCache, IntlConfig, IntlFormatters, IntlShape, MessageDescriptor, MessageFormatElement, PrimitiveType, ResolvedIntlConfig } from "react-intl";
10
- export { type CustomFormats, type FormatDateOptions, type FormatDisplayNameOptions, type FormatListOptions, type FormatNumberOptions, type FormatPluralOptions, type FormatRelativeTimeOptions, FormattedDate, FormattedDateParts, FormattedDateTimeRange, FormattedDisplayName, FormattedList, FormattedListParts, FormattedMessage, FormattedNumber, FormattedNumberParts, FormattedPlural, FormattedRelativeTime, FormattedTime, FormattedTimeParts, type Formatters, type IntlCache, type IntlConfig, IntlContext, type IntlFormatters, IntlProvider, type IntlShape, InvalidConfigError, type MessageDescriptor, type MessageFormatElement, MessageFormatError, MissingDataError, MissingTranslationError, type PrimitiveType, RawIntlProvider, ReactIntlError, ReactIntlErrorCode, type ResolvedIntlConfig, UnsupportedFormatterError, createIntl, createIntlCache, defineMessage, defineMessages, useIntl };
14
+ export { type CustomFormats, type DictionaryIntlShape, type DictionaryMessageIds, type FormatDateOptions, type FormatDisplayNameOptions, type FormatListOptions, type FormatNumberOptions, type FormatPluralOptions, type FormatRelativeTimeOptions, FormattedDate, FormattedDateParts, FormattedDateTimeRange, FormattedDisplayName, FormattedList, FormattedListParts, FormattedMessage, FormattedNumber, FormattedNumberParts, FormattedPlural, FormattedRelativeTime, FormattedTime, FormattedTimeParts, type Formatters, type IntlCache, type IntlConfig, IntlContext, type IntlFormatters, IntlProvider, type IntlShape, InvalidConfigError, type MessageDescriptor, type MessageFormatElement, MessageFormatError, type MessageValueForId, MissingDataError, MissingTranslationError, type PrimitiveType, RawIntlProvider, ReactIntlError, ReactIntlErrorCode, type ResolvedIntlConfig, type RootMessageIds, type TypedFormatMessage, UnsupportedFormatterError, createIntl, createIntlCache, defineMessage, defineMessages, useDictionary, useDictionaryDynamic, useIntl };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/plugin/index.ts"],"mappings":";;;;;;AAiEA;;;;;;;;;;;;;cAAa,mBAAA,GACX,OAAA,GAAU,UAAA,QAAkB,QAAA,SAC3B,YAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/plugin/index.ts"],"mappings":";;;;;;AAwBA;;;;;;;;;;;;;cAAa,mBAAA,GACX,OAAA,GAAU,UAAA,QAAkB,QAAA,SAC3B,YAAA"}
@@ -0,0 +1,26 @@
1
+ import { DictionaryKeys } from "@intlayer/types/module_augmentation";
2
+ import { ValidDotPathsFor } from "@intlayer/core/transpiler";
3
+
4
+ //#region src/typedMessageIds.d.ts
5
+ /**
6
+ * Every valid react-intl message id: `<dictionaryKey>.<dotPath>`, where the
7
+ * first segment designates the intlayer dictionary. Falls back to `string`
8
+ * when no dictionary registry is declared (e.g. before the first build).
9
+ */
10
+ type RootMessageIds = string extends DictionaryKeys ? string : { [K in DictionaryKeys]: `${K & string}.${ValidDotPathsFor<K> & string}` }[DictionaryKeys];
11
+ declare global {
12
+ namespace FormatjsIntl {
13
+ interface Message {
14
+ /**
15
+ * Types every react-intl message id (`formatMessage`,
16
+ * `<FormattedMessage>`, `defineMessages`, …) against the intlayer
17
+ * dictionary registry — the same strength as the base `useIntlayer`
18
+ * hook.
19
+ */
20
+ ids: RootMessageIds;
21
+ }
22
+ }
23
+ } //# sourceMappingURL=typedMessageIds.d.ts.map
24
+ //#endregion
25
+ export { RootMessageIds };
26
+ //# sourceMappingURL=typedMessageIds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typedMessageIds.d.ts","names":[],"sources":["../../src/typedMessageIds.ts"],"mappings":";;;;;;AAQA;;;KAAY,cAAA,kBAAgC,cAAA,oBAGhC,cAAA,MAAoB,CAAA,aAAc,gBAAA,CAAiB,CAAA,eACzD,cAAA;AAAA,QAEE,MAAA;EAAA,UACI,YAAA;IAAA,UACE,OAAA;MAJM;;;;;;MAWd,GAAA,EAAK,cAAc;IAAA;EAAA;AAAA"}
@@ -0,0 +1,31 @@
1
+ import { DictionaryIntlShape } from "./dictionaryIntlShape.js";
2
+ import { DictionaryKeys } from "@intlayer/types/module_augmentation";
3
+ import { Dictionary } from "@intlayer/types/dictionary";
4
+
5
+ //#region src/useDictionary.d.ts
6
+ /**
7
+ * Builds the id lookup of a dictionary-bound intl object.
8
+ *
9
+ * react-intl ids encode the dictionary key as their first dot-segment
10
+ * (`'home.title'` → dictionary `home`, field `title`). When the content is
11
+ * supplied directly, the leading `<dictionaryKey>.` is stripped so both the
12
+ * absolute (`'home.title'`) and relative (`'title'`) forms resolve.
13
+ */
14
+ declare const createDictionaryLookup: (dictionaryKey: string, content: unknown) => (id: string) => unknown;
15
+ /**
16
+ * Dictionary-accepting variant of `useIntl`.
17
+ *
18
+ * Returns an `IntlShape` whose `formatMessage` resolves ids inside the
19
+ * supplied dictionary instead of the runtime registry, enabling tree-shaking
20
+ * of unused locale content. All `Intl`-backed formatters (`formatNumber`,
21
+ * `formatDate`, …) behave exactly like `useIntl()`.
22
+ *
23
+ * @example
24
+ * import _abc from '.intlayer/dictionaries/home.json' with { type: 'json' };
25
+ * const intl = useDictionary(_abc);
26
+ * intl.formatMessage({ id: 'home.title' }); // or { id: 'title' } — both typed
27
+ */
28
+ declare const useDictionary: <T extends Dictionary>(dictionary: T) => DictionaryIntlShape<T["key"] & DictionaryKeys>;
29
+ //#endregion
30
+ export { createDictionaryLookup, useDictionary };
31
+ //# sourceMappingURL=useDictionary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDictionary.d.ts","names":[],"sources":["../../src/useDictionary.ts"],"mappings":";;;;;;;AAqBA;;;;;;cAAa,sBAAA,GACV,aAAA,UAAuB,OAAA,eACvB,EAAA;;AAAU;AAsBb;;;;;;;;;;;cAAa,aAAA,aAA2B,UAAA,EACtC,UAAA,EAAY,CAAA,KACX,mBAAA,CAAoB,CAAA,UAAW,cAAA"}
@@ -0,0 +1,15 @@
1
+ import { DictionaryIntlShape } from "./dictionaryIntlShape.js";
2
+ import { DictionaryKeys, StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
3
+ import { Dictionary } from "@intlayer/types/dictionary";
4
+
5
+ //#region src/useDictionaryDynamic.d.ts
6
+ /**
7
+ * Dynamic dictionary-accepting variant of `useIntl`.
8
+ *
9
+ * Counterpart to {@link useDictionary} for dictionaries imported lazily per
10
+ * locale. Used internally by the build-time optimization.
11
+ */
12
+ declare const useDictionaryDynamic: <const T extends Dictionary, const K extends DictionaryKeys>(dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>, key: K) => DictionaryIntlShape<K>;
13
+ //#endregion
14
+ export { useDictionaryDynamic };
15
+ //# sourceMappingURL=useDictionaryDynamic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDictionaryDynamic.d.ts","names":[],"sources":["../../src/useDictionaryDynamic.ts"],"mappings":";;;;;;;AAuBA;;;;cAAa,oBAAA,mBACK,UAAA,kBACA,cAAA,EAEhB,iBAAA,EAAmB,mBAAA,OAA0B,OAAA,CAAQ,CAAA,IACrD,GAAA,EAAK,CAAA,KACJ,mBAAA,CAAoB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/react-intl",
3
- "version": "9.0.0-canary.11",
3
+ "version": "9.0.0-canary.13",
4
4
  "private": false,
5
5
  "description": "react-intl API adapter for intlayer — drop-in compatibility layer",
6
6
  "keywords": [
@@ -74,13 +74,13 @@
74
74
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
75
75
  },
76
76
  "dependencies": {
77
- "@intlayer/chokidar": "9.0.0-canary.11",
78
- "@intlayer/config": "9.0.0-canary.11",
79
- "@intlayer/core": "9.0.0-canary.11",
80
- "@intlayer/dictionaries-entry": "9.0.0-canary.11",
81
- "@intlayer/types": "9.0.0-canary.11",
82
- "react-intlayer": "9.0.0-canary.11",
83
- "vite-intlayer": "9.0.0-canary.11"
77
+ "@intlayer/config": "9.0.0-canary.13",
78
+ "@intlayer/core": "9.0.0-canary.13",
79
+ "@intlayer/dictionaries-entry": "9.0.0-canary.13",
80
+ "@intlayer/engine": "9.0.0-canary.13",
81
+ "@intlayer/types": "9.0.0-canary.13",
82
+ "react-intlayer": "9.0.0-canary.13",
83
+ "vite-intlayer": "9.0.0-canary.13"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@types/node": "25.9.4",
@@ -92,7 +92,7 @@
92
92
  "rimraf": "6.1.3",
93
93
  "tsdown": "0.22.2",
94
94
  "typescript": "6.0.3",
95
- "vite": "8.1.0",
95
+ "vite": "8.1.3",
96
96
  "vitest": "4.1.9"
97
97
  },
98
98
  "peerDependencies": {