@intlayer/core 9.5.8 → 9.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/cjs/index.cjs +2 -0
  2. package/dist/cjs/interpreter/getContent/getContent.cjs +1 -0
  3. package/dist/cjs/interpreter/getContent/getContent.cjs.map +1 -1
  4. package/dist/cjs/interpreter/getContent/index.cjs +2 -0
  5. package/dist/cjs/interpreter/getContent/plugins.cjs +61 -5
  6. package/dist/cjs/interpreter/getContent/plugins.cjs.map +1 -1
  7. package/dist/cjs/interpreter/index.cjs +2 -0
  8. package/dist/esm/index.mjs +2 -2
  9. package/dist/esm/interpreter/getContent/getContent.mjs +2 -1
  10. package/dist/esm/interpreter/getContent/getContent.mjs.map +1 -1
  11. package/dist/esm/interpreter/getContent/index.mjs +2 -2
  12. package/dist/esm/interpreter/getContent/plugins.mjs +60 -6
  13. package/dist/esm/interpreter/getContent/plugins.mjs.map +1 -1
  14. package/dist/esm/interpreter/index.mjs +2 -2
  15. package/dist/types/index.d.ts +2 -2
  16. package/dist/types/interpreter/getContent/getContent.d.ts.map +1 -1
  17. package/dist/types/interpreter/getContent/index.d.ts +2 -2
  18. package/dist/types/interpreter/getContent/plugins.d.ts +25 -1
  19. package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
  20. package/dist/types/interpreter/index.d.ts +2 -2
  21. package/package.json +5 -5
  22. package/dist/cjs/dictionaryManipulator/qualifiedDictionary.test-d.cjs +0 -97
  23. package/dist/cjs/dictionaryManipulator/qualifiedDictionary.test-d.cjs.map +0 -1
  24. package/dist/cjs/interpreter/getIntlayer.test-d.cjs +0 -28
  25. package/dist/cjs/interpreter/getIntlayer.test-d.cjs.map +0 -1
  26. package/dist/cjs/localization/getCanonicalPath.test-d.cjs +0 -12
  27. package/dist/cjs/localization/getCanonicalPath.test-d.cjs.map +0 -1
  28. package/dist/cjs/localization/getLocalizedPath.test-d.cjs +0 -99
  29. package/dist/cjs/localization/getLocalizedPath.test-d.cjs.map +0 -1
  30. package/dist/cjs/localization/getLocalizedUrl.test-d.cjs +0 -78
  31. package/dist/cjs/localization/getLocalizedUrl.test-d.cjs.map +0 -1
  32. package/dist/cjs/localization/rewriteUtils.test-d.cjs +0 -43
  33. package/dist/cjs/localization/rewriteUtils.test-d.cjs.map +0 -1
  34. package/dist/esm/dictionaryManipulator/qualifiedDictionary.test-d.mjs +0 -97
  35. package/dist/esm/dictionaryManipulator/qualifiedDictionary.test-d.mjs.map +0 -1
  36. package/dist/esm/interpreter/getIntlayer.test-d.mjs +0 -28
  37. package/dist/esm/interpreter/getIntlayer.test-d.mjs.map +0 -1
  38. package/dist/esm/localization/getCanonicalPath.test-d.mjs +0 -12
  39. package/dist/esm/localization/getCanonicalPath.test-d.mjs.map +0 -1
  40. package/dist/esm/localization/getLocalizedPath.test-d.mjs +0 -99
  41. package/dist/esm/localization/getLocalizedPath.test-d.mjs.map +0 -1
  42. package/dist/esm/localization/getLocalizedUrl.test-d.mjs +0 -78
  43. package/dist/esm/localization/getLocalizedUrl.test-d.mjs.map +0 -1
  44. package/dist/esm/localization/rewriteUtils.test-d.mjs +0 -43
  45. package/dist/esm/localization/rewriteUtils.test-d.mjs.map +0 -1
  46. package/dist/types/dictionaryManipulator/qualifiedDictionary.test-d.d.ts +0 -1
  47. package/dist/types/interpreter/getIntlayer.test-d.d.ts +0 -1
  48. package/dist/types/localization/getCanonicalPath.test-d.d.ts +0 -1
  49. package/dist/types/localization/getLocalizedPath.test-d.d.ts +0 -1
  50. package/dist/types/localization/getLocalizedUrl.test-d.d.ts +0 -1
  51. package/dist/types/localization/rewriteUtils.test-d.d.ts +0 -1
@@ -203,6 +203,7 @@ exports.VOID_HTML_ELEMENTS = require_transpiler_html_validateHTML.VOID_HTML_ELEM
203
203
  exports.allowInline = require_markdown_utils.allowInline;
204
204
  exports.anyScopeRegex = require_markdown_utils.anyScopeRegex;
205
205
  exports.attributeValueToNodePropValue = require_markdown_utils.attributeValueToNodePropValue;
206
+ exports.bindInsertedValues = require_interpreter_getContent_plugins.bindInsertedValues;
206
207
  exports.bindIntl = require_utils_intl.bindIntl;
207
208
  exports.blockRegex = require_markdown_utils.blockRegex;
208
209
  exports.buildMaskPlugin = require_deepTransformPlugins_getMaskContent.buildMaskPlugin;
@@ -390,6 +391,7 @@ exports.renderNothing = require_markdown_utils.renderNothing;
390
391
  exports.resolveBrowserLocale = require_localization_resolveBrowserLocale.resolveBrowserLocale;
391
392
  exports.resolveDictionaryArgument = require_dictionaryManipulator_qualifiedDictionary.resolveDictionaryArgument;
392
393
  exports.resolveEffectiveVariantId = require_dictionaryManipulator_qualifiedDictionary.resolveEffectiveVariantId;
394
+ exports.resolveInsertedSelector = require_interpreter_getContent_plugins.resolveInsertedSelector;
393
395
  exports.resolveLocalizedPath = require_localization_rewriteUtils.resolveLocalizedPath;
394
396
  exports.resolveMessage = require_messageFormat_resolveMessage.resolveMessage;
395
397
  exports.resolveMessageNode = require_messageFormat_resolveMessage.resolveMessageNode;
@@ -7,6 +7,7 @@ let _intlayer_config_built = require("@intlayer/config/built");
7
7
  const getBasePlugins = (locale, fallback = true) => [
8
8
  require_interpreter_getContent_plugins.translationPlugin(locale ?? _intlayer_config_built.internationalization.defaultLocale, fallback ? _intlayer_config_built.internationalization.defaultLocale : void 0),
9
9
  require_interpreter_getContent_plugins.enumerationPlugin,
10
+ require_interpreter_getContent_plugins.pluralPlugin(locale ?? _intlayer_config_built.internationalization.defaultLocale),
10
11
  require_interpreter_getContent_plugins.conditionPlugin,
11
12
  require_interpreter_getContent_plugins.insertionPlugin,
12
13
  require_interpreter_getContent_plugins.nestedPlugin(locale ?? _intlayer_config_built.internationalization.defaultLocale),
@@ -1 +1 @@
1
- {"version":3,"file":"getContent.cjs","names":["translationPlugin","internationalization","enumerationPlugin","conditionPlugin","insertionPlugin","nestedPlugin","filePlugin","genderPlugin","selectPlugin","deepTransformNode"],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n selectPlugin,\n translationPlugin,\n} from './plugins';\n\nexport const getBasePlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] =>\n [\n translationPlugin(\n locale ?? internationalization.defaultLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n conditionPlugin,\n insertionPlugin,\n nestedPlugin(locale ?? internationalization.defaultLocale),\n filePlugin,\n genderPlugin,\n selectPlugin,\n ] as Plugins[];\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n const T extends ContentNode,\n const L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n plugins: Plugins[] = []\n) =>\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n"],"mappings":";;;;;;AAsBA,MAAa,kBACX,QACA,WAAoB,SAEpB;CACEA,yDACE,UAAUC,4CAAqB,eAC/B,WAAWA,4CAAqB,gBAAgB,MAClD;CACAC;CACAC;CACAC;CACAC,oDAAa,UAAUJ,4CAAqB,aAAa;CACzDK;CACAC;CACAC;AACF;;;;;;;AAQF,MAAa,cAIX,MACA,WACA,UAAqB,CAAC,MAEtBC,+DAAkB,MAAM;CACtB,GAAG;CACH;AACF,CAAC"}
1
+ {"version":3,"file":"getContent.cjs","names":["translationPlugin","internationalization","enumerationPlugin","pluralPlugin","conditionPlugin","insertionPlugin","nestedPlugin","filePlugin","genderPlugin","selectPlugin","deepTransformNode"],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n pluralPlugin,\n selectPlugin,\n translationPlugin,\n} from './plugins';\n\nexport const getBasePlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] =>\n [\n translationPlugin(\n locale ?? internationalization.defaultLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n pluralPlugin(locale ?? internationalization.defaultLocale),\n conditionPlugin,\n insertionPlugin,\n nestedPlugin(locale ?? internationalization.defaultLocale),\n filePlugin,\n genderPlugin,\n selectPlugin,\n ] as Plugins[];\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n const T extends ContentNode,\n const L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n plugins: Plugins[] = []\n) =>\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n"],"mappings":";;;;;;AAuBA,MAAa,kBACX,QACA,WAAoB,SAEpB;CACEA,yDACE,UAAUC,4CAAqB,eAC/B,WAAWA,4CAAqB,gBAAgB,MAClD;CACAC;CACAC,oDAAa,UAAUF,4CAAqB,aAAa;CACzDG;CACAC;CACAC,oDAAa,UAAUL,4CAAqB,aAAa;CACzDM;CACAC;CACAC;AACF;;;;;;;AAQF,MAAa,cAIX,MACA,WACA,UAAqB,CAAC,MAEtBC,+DAAkB,MAAM;CACtB,GAAG;CACH;AACF,CAAC"}
@@ -3,6 +3,7 @@ const require_interpreter_getContent_deepTransform = require('./deepTransform.cj
3
3
  const require_interpreter_getContent_plugins = require('./plugins.cjs');
4
4
  const require_interpreter_getContent_getContent = require('./getContent.cjs');
5
5
 
6
+ exports.bindInsertedValues = require_interpreter_getContent_plugins.bindInsertedValues;
6
7
  exports.conditionPlugin = require_interpreter_getContent_plugins.conditionPlugin;
7
8
  exports.deepTransformNode = require_interpreter_getContent_deepTransform.deepTransformNode;
8
9
  exports.enumerationPlugin = require_interpreter_getContent_plugins.enumerationPlugin;
@@ -14,5 +15,6 @@ exports.getContent = require_interpreter_getContent_getContent.getContent;
14
15
  exports.insertionPlugin = require_interpreter_getContent_plugins.insertionPlugin;
15
16
  exports.nestedPlugin = require_interpreter_getContent_plugins.nestedPlugin;
16
17
  exports.pluralPlugin = require_interpreter_getContent_plugins.pluralPlugin;
18
+ exports.resolveInsertedSelector = require_interpreter_getContent_plugins.resolveInsertedSelector;
17
19
  exports.selectPlugin = require_interpreter_getContent_plugins.selectPlugin;
18
20
  exports.translationPlugin = require_interpreter_getContent_plugins.translationPlugin;
@@ -82,22 +82,27 @@ const pluralPlugin = (locale) => process.env.INTLAYER_NODE_TYPE_PLURAL === "fals
82
82
  transform: (node, props, deepTransformNode) => {
83
83
  const original = node[_intlayer_types_nodeType.PLURAL];
84
84
  const result = {};
85
+ const branchPlugins = (props.plugins ?? []).filter((plugin) => plugin.id !== "insertion-string-plugin");
85
86
  /** String plugin for plural. Replaces string node with a component that renders the insertion. */
86
87
  const pluralStringPlugin = {
87
88
  id: "plural-string-plugin",
88
89
  canHandle: (node) => typeof node === "string" || require_interpreter_interpolableNode.isInterpolableWrapperNode(node),
89
90
  transform: (node, subProps, deepTransformNode) => {
90
- if (require_interpreter_interpolableNode.isInterpolableWrapperNode(node)) return (values) => require_interpreter_interpolableNode.transformInterpolableNode(node, values, subProps, props.plugins, deepTransformNode);
91
+ if (subProps.keyPath.slice(props.keyPath.length).some((keyPath) => keyPath.type === _intlayer_types_nodeType.INSERTION)) return deepTransformNode(node, {
92
+ ...subProps,
93
+ plugins: subProps.plugins?.filter((plugin) => plugin.id !== "plural-string-plugin")
94
+ });
95
+ if (require_interpreter_interpolableNode.isInterpolableWrapperNode(node)) return (values) => require_interpreter_interpolableNode.transformInterpolableNode(node, values, subProps, branchPlugins, deepTransformNode);
91
96
  const transformedResult = deepTransformNode(node, {
92
97
  ...subProps,
93
98
  children: node,
94
- plugins: [...(props.plugins ?? []).filter((plugin) => plugin.id !== "intlayer-node-plugin")]
99
+ plugins: [...branchPlugins.filter((plugin) => plugin.id !== "intlayer-node-plugin")]
95
100
  });
96
101
  return (values) => {
97
102
  const children = require_interpreter_getInsertion.getInsertion(transformedResult, values);
98
103
  return deepTransformNode(children, {
99
104
  ...subProps,
100
- plugins: props.plugins,
105
+ plugins: branchPlugins,
101
106
  children
102
107
  });
103
108
  };
@@ -112,7 +117,7 @@ const pluralPlugin = (locale) => process.env.INTLAYER_NODE_TYPE_PLURAL === "fals
112
117
  type: _intlayer_types_nodeType.PLURAL,
113
118
  key
114
119
  }],
115
- plugins: [pluralStringPlugin, ...props.plugins ?? []]
120
+ plugins: [pluralStringPlugin, ...branchPlugins]
116
121
  });
117
122
  }
118
123
  const effectiveLocale = String(locale ?? props.locale ?? "en");
@@ -179,14 +184,63 @@ const insertionPlugin = process.env.INTLAYER_NODE_TYPE_INSERTION === "false" ? f
179
184
  };
180
185
  }
181
186
  };
182
- return deepTransformNode(children, {
187
+ const result = deepTransformNode(children, {
183
188
  ...props,
184
189
  children,
185
190
  keyPath: newKeyPath,
186
191
  plugins: [insertionStringPlugin, ...props.plugins ?? []]
187
192
  });
193
+ return resolveInsertedSelector(children, result);
188
194
  }
189
195
  };
196
+ /** Container nodes resolved by a selector call: `enu(3)`, `cond(true)`, … */
197
+ const selectorNodeTypes = [
198
+ _intlayer_types_nodeType.ENUMERATION,
199
+ _intlayer_types_nodeType.CONDITION,
200
+ _intlayer_types_nodeType.PLURAL,
201
+ _intlayer_types_nodeType.GENDER,
202
+ _intlayer_types_nodeType.SELECT
203
+ ];
204
+ /**
205
+ * Binds the values of an `insert()` to the selector node it wraps, returning
206
+ * `(selector) => content`. Any other child result is returned unchanged.
207
+ *
208
+ * `areBranchesInterpolated` is set by frameworks that interpolate the branch
209
+ * strings as soon as the values are known: the selected branch is then final
210
+ * content and is never called with the values.
211
+ */
212
+ const bindInsertedValues = (children, result, values, areBranchesInterpolated = false) => {
213
+ const nodeType = children?.nodeType;
214
+ if (typeof result !== "function" || !nodeType || !selectorNodeTypes.includes(nodeType)) return result;
215
+ const isPlural = nodeType === _intlayer_types_nodeType.PLURAL;
216
+ const isEnumeration = nodeType === _intlayer_types_nodeType.ENUMERATION;
217
+ return (selector) => {
218
+ if (typeof selector === "object" && selector !== null) return result({
219
+ ...values,
220
+ ...selector
221
+ });
222
+ if (isPlural) return result({
223
+ ...values,
224
+ count: selector
225
+ });
226
+ if (isEnumeration && typeof selector === "number") {
227
+ const mergedValues = {
228
+ count: selector,
229
+ ...values
230
+ };
231
+ const selected = result(mergedValues);
232
+ return !areBranchesInterpolated && typeof selected === "function" ? selected(mergedValues) : selected;
233
+ }
234
+ const selected = result(selector);
235
+ return !areBranchesInterpolated && typeof selected === "function" ? selected(values) : selected;
236
+ };
237
+ };
238
+ /**
239
+ * Shapes the result of `insert()` wrapping a selector node as
240
+ * `(values) => (selector) => content`, so the values reach the selected
241
+ * branch. Any other child result is returned unchanged.
242
+ */
243
+ const resolveInsertedSelector = (children, result) => typeof result === "function" && selectorNodeTypes.includes(children?.nodeType ?? "") ? (values) => bindInsertedValues(children, result, values) : result;
190
244
  /** Gender plugin. Replaces node with a function that takes gender => string. */
191
245
  const genderPlugin = process.env.INTLAYER_NODE_TYPE_GENDER === "false" ? fallbackPlugin : {
192
246
  id: "gender-plugin",
@@ -264,6 +318,7 @@ const filePlugin = process.env.INTLAYER_NODE_TYPE_FILE === "false" ? fallbackPlu
264
318
  };
265
319
 
266
320
  //#endregion
321
+ exports.bindInsertedValues = bindInsertedValues;
267
322
  exports.conditionPlugin = conditionPlugin;
268
323
  exports.enumerationPlugin = enumerationPlugin;
269
324
  exports.fallbackPlugin = fallbackPlugin;
@@ -272,6 +327,7 @@ exports.genderPlugin = genderPlugin;
272
327
  exports.insertionPlugin = insertionPlugin;
273
328
  exports.nestedPlugin = nestedPlugin;
274
329
  exports.pluralPlugin = pluralPlugin;
330
+ exports.resolveInsertedSelector = resolveInsertedSelector;
275
331
  exports.selectPlugin = selectPlugin;
276
332
  exports.translationPlugin = translationPlugin;
277
333
  //# sourceMappingURL=plugins.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.cjs","names":["NodeTypes","getTranslation","getEnumeration","isInterpolableWrapperNode","transformInterpolableNode","getInsertion","getPlural","getCondition","getGender","getSelect","getNestingOptimized","getNesting"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport type {\n ConditionContent,\n EnumerationContent,\n FileContent,\n Gender,\n GenderContent,\n InsertionContent,\n NestedContent,\n PluralContent,\n PluralContentState,\n SelectContent,\n TranslationContent,\n} from '../../transpiler';\nimport { getCondition } from '../getCondition';\nimport { getEnumeration } from '../getEnumeration';\nimport { getGender } from '../getGender';\nimport { getInsertion } from '../getInsertion';\nimport { type GetNestingResult, getNesting } from '../getNesting';\nimport { getNesting as getNestingOptimized } from '../getNesting.optimized';\nimport { getPlural } from '../getPlural';\nimport { getSelect } from '../getSelect';\nimport { getTranslation } from '../getTranslation';\nimport {\n isInterpolableWrapperNode,\n transformInterpolableNode,\n} from '../interpolableNode';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\n/** ---------------------------------------------\n * PLUGIN DEFINITION\n * --------------------------------------------- */\n\n/**\n * A plugin/transformer that can optionally transform a node during a single DFS pass.\n * - `canHandle` decides if the node is transformable by this plugin.\n * - `transform` returns the transformed node (and does not recurse further).\n *\n * > `transformFn` is a function that can be used to deeply transform inside the plugin.\n */\nexport type Plugins = {\n id: string;\n canHandle: (node: any) => boolean;\n transform: (\n node: any,\n props: NodeProps,\n transformFn: (node: any, props: NodeProps) => any\n ) => any;\n};\n\n/** ---------------------------------------------\n * FALLBACK PLUGIN\n *\n * Used to fallback a tree-shaken plugin\n * --------------------------------------------- */\n\nexport const fallbackPlugin: Plugins = {\n id: 'fallback-plugin',\n canHandle: () => false,\n transform: (node) => node,\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type UnionKeys<T> = T extends unknown ? keyof T : never;\nexport type ValueAtKey<T, K> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.TRANSLATION]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? U[keyof U] extends Record<PropertyKey, unknown>\n ? {\n [K in UnionKeys<U[keyof U]>]: L extends keyof U\n ? K extends keyof U[L]\n ? U[L][K]\n : ValueAtKey<U[keyof U], K>\n : ValueAtKey<U[keyof U], K>;\n } extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : (L extends keyof U ? U[L] : U[keyof U]) extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins =>\n process.env.INTLAYER_NODE_TYPE_TRANSLATION === 'false'\n ? fallbackPlugin\n : {\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.TRANSLATION,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.TRANSLATION] ?? {};\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const childProps = {\n ...props,\n children: original[key as keyof typeof original],\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.TRANSLATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(\n original[key as keyof typeof original],\n childProps\n );\n }\n\n return getTranslation(result, locale, fallback);\n },\n };\n\n/** ---------------------------------------------\n * ENUMERATION PLUGIN\n * --------------------------------------------- */\n\nexport type EnumerationCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.ENUMERATION]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[typeof NodeTypes.ENUMERATION][keyof T[typeof NodeTypes.ENUMERATION]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_ENUMERATION === 'false'\n ? fallbackPlugin\n : {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.ENUMERATION,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.ENUMERATION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as unknown as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ENUMERATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: number | { count: number }) => {\n const quantity = typeof arg === 'number' ? arg : arg.count;\n const subResult = getEnumeration(result, quantity);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * PLURAL PLUGIN\n * --------------------------------------------- */\n\nexport type PluralCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.PLURAL]: object;\n}\n ? (\n arg: number | { count: number; [key: string]: unknown }\n ) => DeepTransformContent<\n T[typeof NodeTypes.PLURAL][keyof T[typeof NodeTypes.PLURAL]],\n S\n >\n : never;\n\ntype SubResultFunction = (values: Record<string, string | number>) => string;\n\n/**\n * Plural plugin. Replaces node with a function that takes a count (or\n * `{ count, ...values }`) => string, picking the matching CLDR plural form\n * for the active locale and interpolating `{{count}}` (and other values).\n */\nexport const pluralPlugin = (locale?: LocalesValues): Plugins =>\n process.env.INTLAYER_NODE_TYPE_PLURAL === 'false'\n ? fallbackPlugin\n : {\n id: 'plural-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.PLURAL,\n transform: (node: PluralContent, props, deepTransformNode) => {\n const original = node[NodeTypes.PLURAL];\n const result: Record<string, any> = {};\n\n /** String plugin for plural. Replaces string node with a component that renders the insertion. */\n const pluralStringPlugin: Plugins = {\n id: 'plural-string-plugin',\n canHandle: (node) =>\n typeof node === 'string' || isInterpolableWrapperNode(node),\n transform: (node, subProps, deepTransformNode) => {\n // `html()`/`markdown()` nodes carry their `{{count}}` placeholders\n // inside a raw string. Interpolate into that string, then re-run\n // the transform so the html/markdown renderer applies afterwards.\n if (isInterpolableWrapperNode(node)) {\n return (values: { [k: string]: string | number }) =>\n transformInterpolableNode(\n node,\n values,\n subProps,\n props.plugins,\n deepTransformNode\n );\n }\n\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (values: { [k: string]: string | number }) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.PLURAL, key } as KeyPath,\n ],\n plugins: [pluralStringPlugin, ...(props.plugins ?? [])],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n const effectiveLocale = String(locale ?? props.locale ?? 'en');\n\n return (arg: number | { count: number; [key: string]: unknown }) => {\n const count = typeof arg === 'number' ? arg : arg.count;\n const values =\n typeof arg === 'number'\n ? { count: arg }\n : (arg as { count: number; [key: string]: unknown });\n\n const subResult: string | SubResultFunction = getPlural(\n result as PluralContent['plural'] as PluralContentState<string>,\n count,\n effectiveLocale\n );\n\n if (typeof subResult === 'function') {\n return (subResult as SubResultFunction)(values);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.CONDITION]: object;\n}\n ? (\n value: boolean | { value: boolean }\n ) => DeepTransformContent<\n T[typeof NodeTypes.CONDITION][keyof T[typeof NodeTypes.CONDITION]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_CONDITION === 'false'\n ? fallbackPlugin\n : {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.CONDITION,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const original = node[NodeTypes.CONDITION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.CONDITION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: boolean | { value: boolean }) => {\n const value = typeof arg === 'boolean' ? arg : arg.value;\n const subResult = getCondition(result as any, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? (\n values: {\n [K in T['fields'][number]]: string | number;\n }\n ) => I extends string\n ? DeepTransformContent<string, S>\n : DeepTransformContent<I, S>\n : never;\n\n/** Insertion plugin. Replaces node with a function that takes quantity => string. */\nexport const insertionPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_INSERTION === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.INSERTION];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) =>\n typeof node === 'string' || isInterpolableWrapperNode(node),\n transform: (node, subProps, deepTransformNode) => {\n // `html()`/`markdown()` nodes carry their `{{ … }}` placeholders\n // inside a raw string. Interpolate into that string, then re-run\n // the transform so the html/markdown renderer applies afterwards.\n if (isInterpolableWrapperNode(node)) {\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) =>\n transformInterpolableNode(\n node,\n values,\n subProps,\n props.plugins,\n deepTransformNode\n );\n }\n\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n };\n\n/** ---------------------------------------------\n * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.GENDER]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<\n T[typeof NodeTypes.GENDER][keyof T[typeof NodeTypes.GENDER]],\n S\n >\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_GENDER === 'false'\n ? fallbackPlugin\n : {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.GENDER,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const original = node[NodeTypes.GENDER];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.GENDER, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (value: Gender) => getGender(result as any, value);\n },\n };\n\n/** ---------------------------------------------\n * SELECT PLUGIN\n * --------------------------------------------- */\n\n/**\n * Accepted selector for a select node.\n *\n * When the node declares a `fallback` case, any string is accepted (the\n * fallback covers the unmatched values) while the declared cases still\n * autocomplete. Without a `fallback`, only the declared cases are accepted.\n */\nexport type SelectSelector<States> = 'fallback' extends keyof States\n ? Exclude<keyof States & string, 'fallback'> | (string & {})\n : keyof States & string;\n\nexport type SelectCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.SELECT]: object;\n}\n ? (\n value:\n | SelectSelector<T[typeof NodeTypes.SELECT]>\n | { value: SelectSelector<T[typeof NodeTypes.SELECT]> }\n ) => DeepTransformContent<\n T[typeof NodeTypes.SELECT][keyof T[typeof NodeTypes.SELECT]],\n S\n >\n : never;\n\n/** Select plugin. Replaces node with a function that takes a string => content. */\nexport const selectPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_SELECT === 'false'\n ? fallbackPlugin\n : {\n id: 'select-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.SELECT,\n transform: (node: SelectContent, props, deepTransformNode) => {\n const original = node[NodeTypes.SELECT];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.SELECT, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: string | { value: string }) => {\n const value = typeof arg === 'string' ? arg : arg?.value;\n const subResult = getSelect(result, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.NESTED]: infer U;\n}\n ? U extends {\n dictionaryKey: infer K extends DictionaryKeys;\n path?: infer P;\n }\n ? GetNestingResult<K, P, S>\n : never\n : never;\n\n/**\n * Resolver used to turn a nested node into content.\n *\n * Optimized builds set `INTLAYER_OPTIMIZED_NESTING` so bundlers fold this to\n * the local resolver and dead-code-eliminate the registry-based one — together\n * with its `getIntlayer` import, and therefore the whole\n * `@intlayer/dictionaries-entry` module. That is what allows the dictionaries\n * entry to be emptied while `nest()` keeps working.\n */\nconst resolveNesting =\n process.env.INTLAYER_OPTIMIZED_NESTING === 'true'\n ? getNestingOptimized\n : getNesting;\n\n/** Nested plugin. Replaces node with the result of `getNesting`. */\nexport const nestedPlugin = (locale?: LocalesValues): Plugins =>\n process.env.INTLAYER_NODE_TYPE_NESTED === 'false'\n ? fallbackPlugin\n : {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n (node?.nodeType === NodeTypes.NESTED || node?.nodeType === 'n'),\n transform: (node: NestedContent, props) =>\n resolveNesting(\n node[NodeTypes.NESTED].dictionaryKey,\n node[NodeTypes.NESTED].path,\n {\n ...props,\n locale: (locale ?? props.locale) as Locale,\n }\n ),\n };\n\n/** ---------------------------------------------\n * FILE PLUGIN\n * --------------------------------------------- */\n\nexport type FileCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.FILE]: string;\n content?: string;\n}\n ? DeepTransformContent<string, S>\n : never;\n\n/** File plugin. Replaces node with the result of `getNesting`. */\nexport const filePlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_FILE === 'false'\n ? fallbackPlugin\n : {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.FILE,\n transform: (node: FileContent, props, deepTransform) =>\n deepTransform(node.content, {\n ...props,\n children: node.content,\n }),\n };\n\n/**\n * PLUGIN RESULT\n */\n\n/**\n * Interface that defines the properties of a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface NodeProps {\n dictionaryKey: string;\n keyPath: KeyPath[];\n plugins?: Plugins[];\n locale?: Locale;\n dictionaryPath?: string;\n children?: any;\n /**\n * Dictionaries referenced through `nest()`, attached to the consuming\n * dictionary by the build optimization and threaded down by\n * `deepTransformNode`.\n *\n * Present only in optimized builds, where the global dictionary registry is\n * stripped and `getNesting` resolves from this map instead. See\n * `getNesting.optimized.ts`.\n */\n nestedDictionaries?: Record<string, unknown>;\n /**\n * Forces eager traversal of plain objects in `deepTransformNode`. By default\n * traversal is lazy (property getters), so callers that discard the returned\n * value never trigger plugins on nested nodes. Set this when running plugins\n * for their side effects only (e.g. missing-locale detection).\n */\n eager?: boolean;\n}\n\n/**\n * Interface that defines the plugins that can be used to transform a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface IInterpreterPlugin<T, S, L extends LocalesValues> {\n translation: TranslationCond<T, S, L>;\n enumeration: EnumerationCond<T, S, L>;\n plural: PluralCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n gender: GenderCond<T, S, L>;\n select: SelectCond<T, S, L>;\n nested: NestedCond<T, S, L>;\n file: FileCond<T, S, L>;\n}\n\n/**\n * Allow to avoid overwriting import from `intlayer` package when `IInterpreterPlugin<T>` interface is augmented in another package, such as `react-intlayer`.\n */\nexport type IInterpreterPluginState = {\n translation: true;\n enumeration: true;\n plural: true;\n condition: true;\n insertion: true;\n gender: true;\n select: true;\n nested: true;\n file: true;\n};\n\n/**\n * Utility type to check if a plugin can be applied to a node.\n */\ntype CheckApplyPlugin<\n T,\n K extends keyof IInterpreterPlugin<T, S, L>,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = K extends keyof S // Test if the key is a key of S.\n ? // Test if the key of S is true. Then the plugin can be applied.\n S[K] extends true\n ? // Test if the key of S exist\n IInterpreterPlugin<T, S, L>[K] extends never\n ? never\n : // Test if the plugin condition is true (if it's not, the plugin is skipped for this node)\n IInterpreterPlugin<T, S, L>[K]\n : never\n : never;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\ntype Traverse<T, S, L extends LocalesValues = DeclaredLocales> =\n T extends ReadonlyArray<infer U> // Turn any read-only array into a plain mutable array\n ? Array<DeepTransformContent<U, S, L>>\n : T extends object\n ? { [K in keyof T]: DeepTransformContent<T[K], S, L> }\n : T;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\nexport type DeepTransformContent<\n T,\n S = IInterpreterPluginState,\n L extends LocalesValues = DeclaredLocales,\n> =\n IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L> extends never // Check if there is a plugin for T:\n ? // No plugin was found, so try to transform T recursively:\n Traverse<T, S, L>\n : // A plugin was found – use the plugin's transformation.\n CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugins.cjs","names":["NodeTypes","getTranslation","getEnumeration","isInterpolableWrapperNode","transformInterpolableNode","getInsertion","getPlural","getCondition","getGender","getSelect","getNestingOptimized","getNesting"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport type {\n ConditionContent,\n EnumerationContent,\n FileContent,\n Gender,\n GenderContent,\n InsertionContent,\n NestedContent,\n PluralContent,\n PluralContentState,\n SelectContent,\n TranslationContent,\n} from '../../transpiler';\nimport { getCondition } from '../getCondition';\nimport { getEnumeration } from '../getEnumeration';\nimport { getGender } from '../getGender';\nimport { getInsertion } from '../getInsertion';\nimport { type GetNestingResult, getNesting } from '../getNesting';\nimport { getNesting as getNestingOptimized } from '../getNesting.optimized';\nimport { getPlural } from '../getPlural';\nimport { getSelect } from '../getSelect';\nimport { getTranslation } from '../getTranslation';\nimport {\n isInterpolableWrapperNode,\n transformInterpolableNode,\n} from '../interpolableNode';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\n/** ---------------------------------------------\n * PLUGIN DEFINITION\n * --------------------------------------------- */\n\n/**\n * A plugin/transformer that can optionally transform a node during a single DFS pass.\n * - `canHandle` decides if the node is transformable by this plugin.\n * - `transform` returns the transformed node (and does not recurse further).\n *\n * > `transformFn` is a function that can be used to deeply transform inside the plugin.\n */\nexport type Plugins = {\n id: string;\n canHandle: (node: any) => boolean;\n transform: (\n node: any,\n props: NodeProps,\n transformFn: (node: any, props: NodeProps) => any\n ) => any;\n};\n\n/** ---------------------------------------------\n * FALLBACK PLUGIN\n *\n * Used to fallback a tree-shaken plugin\n * --------------------------------------------- */\n\nexport const fallbackPlugin: Plugins = {\n id: 'fallback-plugin',\n canHandle: () => false,\n transform: (node) => node,\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type UnionKeys<T> = T extends unknown ? keyof T : never;\nexport type ValueAtKey<T, K> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.TRANSLATION]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? U[keyof U] extends Record<PropertyKey, unknown>\n ? {\n [K in UnionKeys<U[keyof U]>]: L extends keyof U\n ? K extends keyof U[L]\n ? U[L][K]\n : ValueAtKey<U[keyof U], K>\n : ValueAtKey<U[keyof U], K>;\n } extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : (L extends keyof U ? U[L] : U[keyof U]) extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins =>\n process.env.INTLAYER_NODE_TYPE_TRANSLATION === 'false'\n ? fallbackPlugin\n : {\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.TRANSLATION,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.TRANSLATION] ?? {};\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const childProps = {\n ...props,\n children: original[key as keyof typeof original],\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.TRANSLATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(\n original[key as keyof typeof original],\n childProps\n );\n }\n\n return getTranslation(result, locale, fallback);\n },\n };\n\n/** ---------------------------------------------\n * ENUMERATION PLUGIN\n * --------------------------------------------- */\n\nexport type EnumerationCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.ENUMERATION]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[typeof NodeTypes.ENUMERATION][keyof T[typeof NodeTypes.ENUMERATION]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_ENUMERATION === 'false'\n ? fallbackPlugin\n : {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.ENUMERATION,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.ENUMERATION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as unknown as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ENUMERATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: number | { count: number }) => {\n const quantity = typeof arg === 'number' ? arg : arg.count;\n const subResult = getEnumeration(result, quantity);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * PLURAL PLUGIN\n * --------------------------------------------- */\n\n/**\n * A plural branch wrapped in an `insertion` node (auto-transformed\n * `{{count}}`) resolves to its inner content: the plural applies the values.\n */\ntype PluralBranch<Branch> = Branch extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer InsertionContent;\n fields: readonly string[];\n}\n ? InsertionContent\n : Branch;\n\nexport type PluralCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.PLURAL]: object;\n}\n ? (\n arg: number | { count: number; [key: string]: unknown }\n ) => DeepTransformContent<\n PluralBranch<\n T[typeof NodeTypes.PLURAL][keyof T[typeof NodeTypes.PLURAL]]\n >,\n S\n >\n : never;\n\ntype SubResultFunction = (values: Record<string, string | number>) => string;\n\n/**\n * Plural plugin. Replaces node with a function that takes a count (or\n * `{ count, ...values }`) => string, picking the matching CLDR plural form\n * for the active locale and interpolating `{{count}}` (and other values).\n */\nexport const pluralPlugin = (locale?: LocalesValues): Plugins =>\n process.env.INTLAYER_NODE_TYPE_PLURAL === 'false'\n ? fallbackPlugin\n : {\n id: 'plural-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.PLURAL,\n transform: (node: PluralContent, props, deepTransformNode) => {\n const original = node[NodeTypes.PLURAL];\n const result: Record<string, any> = {};\n // The plural interpolates its own branches. A string plugin from an\n // enclosing `insert()` would turn them into functions first.\n const branchPlugins = (props.plugins ?? []).filter(\n (plugin) => plugin.id !== 'insertion-string-plugin'\n );\n\n /** String plugin for plural. Replaces string node with a component that renders the insertion. */\n const pluralStringPlugin: Plugins = {\n id: 'plural-string-plugin',\n canHandle: (node) =>\n typeof node === 'string' || isInterpolableWrapperNode(node),\n transform: (node, subProps, deepTransformNode) => {\n // An `insertion` node below the plural (e.g. auto-transformed\n // `{{count}}` branches) already returns `(values) => …`. Leave its\n // strings untouched, or its template would become a function.\n const isInsideInsertion = subProps.keyPath\n .slice(props.keyPath.length)\n .some((keyPath) => keyPath.type === NodeTypes.INSERTION);\n\n if (isInsideInsertion) {\n return deepTransformNode(node, {\n ...subProps,\n plugins: subProps.plugins?.filter(\n (plugin) => plugin.id !== 'plural-string-plugin'\n ),\n });\n }\n\n // `html()`/`markdown()` nodes carry their `{{count}}` placeholders\n // inside a raw string. Interpolate into that string, then re-run\n // the transform so the html/markdown renderer applies afterwards.\n if (isInterpolableWrapperNode(node)) {\n return (values: { [k: string]: string | number }) =>\n transformInterpolableNode(\n node,\n values,\n subProps,\n branchPlugins,\n deepTransformNode\n );\n }\n\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...branchPlugins.filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (values: { [k: string]: string | number }) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: branchPlugins,\n children,\n });\n };\n },\n };\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.PLURAL, key } as KeyPath,\n ],\n plugins: [pluralStringPlugin, ...branchPlugins],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n const effectiveLocale = String(locale ?? props.locale ?? 'en');\n\n return (arg: number | { count: number; [key: string]: unknown }) => {\n const count = typeof arg === 'number' ? arg : arg.count;\n const values =\n typeof arg === 'number'\n ? { count: arg }\n : (arg as { count: number; [key: string]: unknown });\n\n const subResult: string | SubResultFunction = getPlural(\n result as PluralContent['plural'] as PluralContentState<string>,\n count,\n effectiveLocale\n );\n\n if (typeof subResult === 'function') {\n return (subResult as SubResultFunction)(values);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.CONDITION]: object;\n}\n ? (\n value: boolean | { value: boolean }\n ) => DeepTransformContent<\n T[typeof NodeTypes.CONDITION][keyof T[typeof NodeTypes.CONDITION]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_CONDITION === 'false'\n ? fallbackPlugin\n : {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.CONDITION,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const original = node[NodeTypes.CONDITION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.CONDITION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: boolean | { value: boolean }) => {\n const value = typeof arg === 'boolean' ? arg : arg.value;\n const subResult = getCondition(result as any, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? (\n values: {\n [K in T['fields'][number]]: string | number;\n }\n ) => I extends string\n ? DeepTransformContent<string, S>\n : DeepTransformContent<I, S>\n : never;\n\n/** Insertion plugin. Replaces node with a function that takes quantity => string. */\nexport const insertionPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_INSERTION === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.INSERTION];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) =>\n typeof node === 'string' || isInterpolableWrapperNode(node),\n transform: (node, subProps, deepTransformNode) => {\n // `html()`/`markdown()` nodes carry their `{{ … }}` placeholders\n // inside a raw string. Interpolate into that string, then re-run\n // the transform so the html/markdown renderer applies afterwards.\n if (isInterpolableWrapperNode(node)) {\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) =>\n transformInterpolableNode(\n node,\n values,\n subProps,\n props.plugins,\n deepTransformNode\n );\n }\n\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n const result = deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n\n return resolveInsertedSelector(children, result);\n },\n };\n\n/** Container nodes resolved by a selector call: `enu(3)`, `cond(true)`, … */\nconst selectorNodeTypes: string[] = [\n NodeTypes.ENUMERATION,\n NodeTypes.CONDITION,\n NodeTypes.PLURAL,\n NodeTypes.GENDER,\n NodeTypes.SELECT,\n];\n\n/**\n * Binds the values of an `insert()` to the selector node it wraps, returning\n * `(selector) => content`. Any other child result is returned unchanged.\n *\n * `areBranchesInterpolated` is set by frameworks that interpolate the branch\n * strings as soon as the values are known: the selected branch is then final\n * content and is never called with the values.\n */\nexport const bindInsertedValues = (\n children: unknown,\n result: unknown,\n values: Record<string, unknown>,\n areBranchesInterpolated = false\n): unknown => {\n const nodeType = (children as { nodeType?: string })?.nodeType;\n if (\n typeof result !== 'function' ||\n !nodeType ||\n !selectorNodeTypes.includes(nodeType)\n ) {\n return result;\n }\n\n const isPlural = nodeType === NodeTypes.PLURAL;\n const isEnumeration = nodeType === NodeTypes.ENUMERATION;\n\n return (selector: unknown) => {\n // Object selectors (`{ count }`, `{ value }`) carry the values along.\n if (typeof selector === 'object' && selector !== null) {\n return result({ ...values, ...selector });\n }\n\n // Plural interpolates its own branches, `{{count}}` included.\n if (isPlural) {\n return result({ ...values, count: selector });\n }\n\n // Enumeration selector is a numeric count (or count range)\n if (isEnumeration && typeof selector === 'number') {\n const mergedValues = { count: selector, ...values };\n const selected = result(mergedValues);\n\n return !areBranchesInterpolated && typeof selected === 'function'\n ? selected(mergedValues)\n : selected;\n }\n\n const selected = result(selector);\n\n return !areBranchesInterpolated && typeof selected === 'function'\n ? selected(values)\n : selected;\n };\n};\n\n/**\n * Shapes the result of `insert()` wrapping a selector node as\n * `(values) => (selector) => content`, so the values reach the selected\n * branch. Any other child result is returned unchanged.\n */\nexport const resolveInsertedSelector = (\n children: unknown,\n result: unknown\n): unknown =>\n typeof result === 'function' &&\n selectorNodeTypes.includes(\n (children as { nodeType?: string })?.nodeType ?? ''\n )\n ? (values: Record<string, unknown>) =>\n bindInsertedValues(children, result, values)\n : result;\n\n/** ---------------------------------------------\n * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.GENDER]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<\n T[typeof NodeTypes.GENDER][keyof T[typeof NodeTypes.GENDER]],\n S\n >\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_GENDER === 'false'\n ? fallbackPlugin\n : {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.GENDER,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const original = node[NodeTypes.GENDER];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.GENDER, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (value: Gender) => getGender(result as any, value);\n },\n };\n\n/** ---------------------------------------------\n * SELECT PLUGIN\n * --------------------------------------------- */\n\n/**\n * Accepted selector for a select node.\n *\n * When the node declares a `fallback` case, any string is accepted (the\n * fallback covers the unmatched values) while the declared cases still\n * autocomplete. Without a `fallback`, only the declared cases are accepted.\n */\nexport type SelectSelector<States> = 'fallback' extends keyof States\n ? Exclude<keyof States & string, 'fallback'> | (string & {})\n : keyof States & string;\n\nexport type SelectCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.SELECT]: object;\n}\n ? (\n value:\n | SelectSelector<T[typeof NodeTypes.SELECT]>\n | { value: SelectSelector<T[typeof NodeTypes.SELECT]> }\n ) => DeepTransformContent<\n T[typeof NodeTypes.SELECT][keyof T[typeof NodeTypes.SELECT]],\n S\n >\n : never;\n\n/** Select plugin. Replaces node with a function that takes a string => content. */\nexport const selectPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_SELECT === 'false'\n ? fallbackPlugin\n : {\n id: 'select-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.SELECT,\n transform: (node: SelectContent, props, deepTransformNode) => {\n const original = node[NodeTypes.SELECT];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.SELECT, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: string | { value: string }) => {\n const value = typeof arg === 'string' ? arg : arg?.value;\n const subResult = getSelect(result, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.NESTED]: infer U;\n}\n ? U extends {\n dictionaryKey: infer K extends DictionaryKeys;\n path?: infer P;\n }\n ? GetNestingResult<K, P, S>\n : never\n : never;\n\n/**\n * Resolver used to turn a nested node into content.\n *\n * Optimized builds set `INTLAYER_OPTIMIZED_NESTING` so bundlers fold this to\n * the local resolver and dead-code-eliminate the registry-based one — together\n * with its `getIntlayer` import, and therefore the whole\n * `@intlayer/dictionaries-entry` module. That is what allows the dictionaries\n * entry to be emptied while `nest()` keeps working.\n */\nconst resolveNesting =\n process.env.INTLAYER_OPTIMIZED_NESTING === 'true'\n ? getNestingOptimized\n : getNesting;\n\n/** Nested plugin. Replaces node with the result of `getNesting`. */\nexport const nestedPlugin = (locale?: LocalesValues): Plugins =>\n process.env.INTLAYER_NODE_TYPE_NESTED === 'false'\n ? fallbackPlugin\n : {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n (node?.nodeType === NodeTypes.NESTED || node?.nodeType === 'n'),\n transform: (node: NestedContent, props) =>\n resolveNesting(\n node[NodeTypes.NESTED].dictionaryKey,\n node[NodeTypes.NESTED].path,\n {\n ...props,\n locale: (locale ?? props.locale) as Locale,\n }\n ),\n };\n\n/** ---------------------------------------------\n * FILE PLUGIN\n * --------------------------------------------- */\n\nexport type FileCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.FILE]: string;\n content?: string;\n}\n ? DeepTransformContent<string, S>\n : never;\n\n/** File plugin. Replaces node with the result of `getNesting`. */\nexport const filePlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_FILE === 'false'\n ? fallbackPlugin\n : {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.FILE,\n transform: (node: FileContent, props, deepTransform) =>\n deepTransform(node.content, {\n ...props,\n children: node.content,\n }),\n };\n\n/**\n * PLUGIN RESULT\n */\n\n/**\n * Interface that defines the properties of a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface NodeProps {\n dictionaryKey: string;\n keyPath: KeyPath[];\n plugins?: Plugins[];\n locale?: Locale;\n dictionaryPath?: string;\n children?: any;\n /**\n * Dictionaries referenced through `nest()`, attached to the consuming\n * dictionary by the build optimization and threaded down by\n * `deepTransformNode`.\n *\n * Present only in optimized builds, where the global dictionary registry is\n * stripped and `getNesting` resolves from this map instead. See\n * `getNesting.optimized.ts`.\n */\n nestedDictionaries?: Record<string, unknown>;\n /**\n * Forces eager traversal of plain objects in `deepTransformNode`. By default\n * traversal is lazy (property getters), so callers that discard the returned\n * value never trigger plugins on nested nodes. Set this when running plugins\n * for their side effects only (e.g. missing-locale detection).\n */\n eager?: boolean;\n}\n\n/**\n * Interface that defines the plugins that can be used to transform a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface IInterpreterPlugin<T, S, L extends LocalesValues> {\n translation: TranslationCond<T, S, L>;\n enumeration: EnumerationCond<T, S, L>;\n plural: PluralCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n gender: GenderCond<T, S, L>;\n select: SelectCond<T, S, L>;\n nested: NestedCond<T, S, L>;\n file: FileCond<T, S, L>;\n}\n\n/**\n * Allow to avoid overwriting import from `intlayer` package when `IInterpreterPlugin<T>` interface is augmented in another package, such as `react-intlayer`.\n */\nexport type IInterpreterPluginState = {\n translation: true;\n enumeration: true;\n plural: true;\n condition: true;\n insertion: true;\n gender: true;\n select: true;\n nested: true;\n file: true;\n};\n\n/**\n * Utility type to check if a plugin can be applied to a node.\n */\ntype CheckApplyPlugin<\n T,\n K extends keyof IInterpreterPlugin<T, S, L>,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = K extends keyof S // Test if the key is a key of S.\n ? // Test if the key of S is true. Then the plugin can be applied.\n S[K] extends true\n ? // Test if the key of S exist\n IInterpreterPlugin<T, S, L>[K] extends never\n ? never\n : // Test if the plugin condition is true (if it's not, the plugin is skipped for this node)\n IInterpreterPlugin<T, S, L>[K]\n : never\n : never;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\ntype Traverse<T, S, L extends LocalesValues = DeclaredLocales> =\n T extends ReadonlyArray<infer U> // Turn any read-only array into a plain mutable array\n ? Array<DeepTransformContent<U, S, L>>\n : T extends object\n ? { [K in keyof T]: DeepTransformContent<T[K], S, L> }\n : T;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\nexport type DeepTransformContent<\n T,\n S = IInterpreterPluginState,\n L extends LocalesValues = DeclaredLocales,\n> =\n IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L> extends never // Check if there is a plugin for T:\n ? // No plugin was found, so try to transform T recursively:\n Traverse<T, S, L>\n : // A plugin was found – use the plugin's transformation.\n CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmEA,MAAa,iBAA0B;CACrC,IAAI;CACJ,iBAAiB;CACjB,YAAY,SAAS;AACvB;;AAmCA,MAAa,qBACX,QACA,aAEA,QAAQ,IAAI,mCAAmC,UAC3C,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaA,yBAAU;CAC3D,YAAY,MAA0B,OAAO,sBAAsB;EACjE,MAAM,WAAW,KAAKA,yBAAU,gBAAgB,CAAC;EACjD,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,aAAa;IACjB,GAAG;IACH,UAAU,SAAS;IACnB,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAa;IAAI,CACrC;GACF;GACA,OAAO,OAAO,kBACZ,SAAS,MACT,UACF;EACF;EAEA,OAAOC,kDAAe,QAAQ,QAAQ,QAAQ;CAChD;AACF;;AAmBN,MAAa,oBACX,QAAQ,IAAI,mCAAmC,UAC3C,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaD,yBAAU;CAC3D,YAAY,MAA0B,OAAO,sBAAsB;EACjE,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;GASvB,OAAO,OAAO,kBAAkB,OAAO;IAPrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAa;IAAI,CACrC;GAE8C,CAAC;EACnD;EAEA,QAAQ,QAAoC;GAC1C,MAAM,WAAW,OAAO,QAAQ,WAAW,MAAM,IAAI;GACrD,MAAM,YAAYE,kDAAe,QAAQ,QAAQ;GAEjD,IAAI,OAAO,cAAc,cAAc,OAAO,QAAQ,UACpD,OAAO,UAAU,GAAG;GAGtB,OAAO;EACT;CACF;AACF;;;;;;AAuCN,MAAa,gBAAgB,WAC3B,QAAQ,IAAI,8BAA8B,UACtC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaF,yBAAU;CAC3D,YAAY,MAAqB,OAAO,sBAAsB;EAC5D,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,CAAC;EAGrC,MAAM,iBAAiB,MAAM,WAAW,CAAC,EAAC,CAAE,QACzC,WAAW,OAAO,OAAO,yBAC5B;;EAGA,MAAM,qBAA8B;GAClC,IAAI;GACJ,YAAY,SACV,OAAO,SAAS,YAAYG,+DAA0B,IAAI;GAC5D,YAAY,MAAM,UAAU,sBAAsB;IAQhD,IAJ0B,SAAS,QAChC,MAAM,MAAM,QAAQ,MAAM,CAAC,CAC3B,MAAM,YAAY,QAAQ,SAASH,yBAAU,SAE5B,GAClB,OAAO,kBAAkB,MAAM;KAC7B,GAAG;KACH,SAAS,SAAS,SAAS,QACxB,WAAW,OAAO,OAAO,sBAC5B;IACF,CAAC;IAMH,IAAIG,+DAA0B,IAAI,GAChC,QAAQ,WACNC,+DACE,MACA,QACA,UACA,eACA,iBACF;IAGJ,MAAM,oBAAoB,kBAAkB,MAAM;KAChD,GAAG;KACH,UAAU;KACV,SAAS,CACP,GAAG,cAAc,QACd,WAAW,OAAO,OAAO,sBAC5B,CACF;IACF,CAAC;IAED,QAAQ,WAA6C;KACnD,MAAM,WAAWC,8CAAa,mBAAmB,MAAM;KAEvD,OAAO,kBAAkB,UAAU;MACjC,GAAG;MACH,SAAS;MACT;KACF,CAAC;IACH;GACF;EACF;EAEA,KAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;GAUvB,OAAO,OAAO,kBAAkB,OAAO;IARrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAML,yBAAU;KAAQ;IAAI,CAChC;IACA,SAAS,CAAC,oBAAoB,GAAG,aAAa;GAEA,CAAC;EACnD;EAEA,MAAM,kBAAkB,OAAO,UAAU,MAAM,UAAU,IAAI;EAE7D,QAAQ,QAA4D;GAClE,MAAM,QAAQ,OAAO,QAAQ,WAAW,MAAM,IAAI;GAClD,MAAM,SACJ,OAAO,QAAQ,WACX,EAAE,OAAO,IAAI,IACZ;GAEP,MAAM,YAAwCM,wCAC5C,QACA,OACA,eACF;GAEA,IAAI,OAAO,cAAc,YACvB,OAAQ,UAAgC,MAAM;GAGhD,OAAO;EACT;CACF;AACF;;AAmBN,MAAa,kBACX,QAAQ,IAAI,iCAAiC,UACzC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaN,yBAAU;CAC3D,YAAY,MAAwB,OAAO,sBAAsB;EAC/D,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;GASvB,OAAO,OAAO,kBAAkB,OAAO;IAPrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAW;IAAI,CACnC;GAE8C,CAAC;EACnD;EAEA,QAAQ,QAAsC;GAC5C,MAAM,QAAQ,OAAO,QAAQ,YAAY,MAAM,IAAI;GACnD,MAAM,YAAYO,8CAAa,QAAe,KAAK;GAEnD,IAAI,OAAO,cAAc,cAAc,OAAO,QAAQ,UACpD,OAAO,UAAU,GAAG;GAGtB,OAAO;EACT;CACF;AACF;;AAqBN,MAAa,kBACX,QAAQ,IAAI,iCAAiC,UACzC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaP,yBAAU;CAC3D,YAAY,MAAwB,OAAO,sBAAsB;EAC/D,MAAM,aAAwB,CAC5B,GAAG,MAAM,SACT,EACE,MAAMA,yBAAU,UAClB,CACF;EAEA,MAAM,WAAW,KAAKA,yBAAU;;EAGhC,MAAM,wBAAiC;GACrC,IAAI;GACJ,YAAY,SACV,OAAO,SAAS,YAAYG,+DAA0B,IAAI;GAC5D,YAAY,MAAM,UAAU,sBAAsB;IAIhD,IAAIA,+DAA0B,IAAI,GAChC,QACE,WAIAC,+DACE,MACA,QACA,UACA,MAAM,SACN,iBACF;IAGJ,MAAM,oBAAoB,kBAAkB,MAAM;KAChD,GAAG;KACH,UAAU;KACV,SAAS,CACP,IAAI,MAAM,WAAY,CAAC,EAAe,CAAE,QACrC,WAAW,OAAO,OAAO,sBAC5B,CACF;IACF,CAAC;IAED,QACE,WAGG;KACH,MAAM,WAAWC,8CAAa,mBAAmB,MAAM;KAEvD,OAAO,kBAAkB,UAAU;MACjC,GAAG;MACH,SAAS,MAAM;MACf;KACF,CAAC;IACH;GACF;EACF;EAEA,MAAM,SAAS,kBAAkB,UAAU;GACzC,GAAG;GACH;GACA,SAAS;GACT,SAAS,CAAC,uBAAuB,GAAI,MAAM,WAAW,CAAC,CAAE;EAC3D,CAAC;EAED,OAAO,wBAAwB,UAAU,MAAM;CACjD;AACF;;AAGN,MAAM,oBAA8B;CAClCL,yBAAU;CACVA,yBAAU;CACVA,yBAAU;CACVA,yBAAU;CACVA,yBAAU;AACZ;;;;;;;;;AAUA,MAAa,sBACX,UACA,QACA,QACA,0BAA0B,UACd;CACZ,MAAM,WAAY,UAAoC;CACtD,IACE,OAAO,WAAW,cAClB,CAAC,YACD,CAAC,kBAAkB,SAAS,QAAQ,GAEpC,OAAO;CAGT,MAAM,WAAW,aAAaA,yBAAU;CACxC,MAAM,gBAAgB,aAAaA,yBAAU;CAE7C,QAAQ,aAAsB;EAE5B,IAAI,OAAO,aAAa,YAAY,aAAa,MAC/C,OAAO,OAAO;GAAE,GAAG;GAAQ,GAAG;EAAS,CAAC;EAI1C,IAAI,UACF,OAAO,OAAO;GAAE,GAAG;GAAQ,OAAO;EAAS,CAAC;EAI9C,IAAI,iBAAiB,OAAO,aAAa,UAAU;GACjD,MAAM,eAAe;IAAE,OAAO;IAAU,GAAG;GAAO;GAClD,MAAM,WAAW,OAAO,YAAY;GAEpC,OAAO,CAAC,2BAA2B,OAAO,aAAa,aACnD,SAAS,YAAY,IACrB;EACN;EAEA,MAAM,WAAW,OAAO,QAAQ;EAEhC,OAAO,CAAC,2BAA2B,OAAO,aAAa,aACnD,SAAS,MAAM,IACf;CACN;AACF;;;;;;AAOA,MAAa,2BACX,UACA,WAEA,OAAO,WAAW,cAClB,kBAAkB,SACf,UAAoC,YAAY,EACnD,KACK,WACC,mBAAmB,UAAU,QAAQ,MAAM,IAC7C;;AAmBN,MAAa,eACX,QAAQ,IAAI,8BAA8B,UACtC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaA,yBAAU;CAC3D,YAAY,MAAqB,OAAO,sBAAsB;EAC5D,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;GASvB,OAAO,OAAO,kBAAkB,OAAO;IAPrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAQ;IAAI,CAChC;GAE8C,CAAC;EACnD;EAEA,QAAQ,UAAkBQ,wCAAU,QAAe,KAAK;CAC1D;AACF;;AAgCN,MAAa,eACX,QAAQ,IAAI,8BAA8B,UACtC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaR,yBAAU;CAC3D,YAAY,MAAqB,OAAO,sBAAsB;EAC5D,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;GASvB,OAAO,OAAO,kBAAkB,OAAO;IAPrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAQ;IAAI,CAChC;GAE8C,CAAC;EACnD;EAEA,QAAQ,QAAoC;GAC1C,MAAM,QAAQ,OAAO,QAAQ,WAAW,MAAM,KAAK;GACnD,MAAM,YAAYS,wCAAU,QAAQ,KAAK;GAEzC,IAAI,OAAO,cAAc,cAAc,OAAO,QAAQ,UACpD,OAAO,UAAU,GAAG;GAGtB,OAAO;EACT;CACF;AACF;;;;;;;;;;AA2BN,MAAM,iBACJ,QAAQ,IAAI,+BAA+B,SACvCC,sDACAC;;AAGN,MAAa,gBAAgB,WAC3B,QAAQ,IAAI,8BAA8B,UACtC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,aACf,MAAM,aAAaX,yBAAU,UAAU,MAAM,aAAa;CAC7D,YAAY,MAAqB,UAC/B,eACE,KAAKA,yBAAU,OAAO,CAAC,eACvB,KAAKA,yBAAU,OAAO,CAAC,MACvB;EACE,GAAG;EACH,QAAS,UAAU,MAAM;CAC3B,CACF;AACJ;;AAeN,MAAa,aACX,QAAQ,IAAI,4BAA4B,UACpC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaA,yBAAU;CAC3D,YAAY,MAAmB,OAAO,kBACpC,cAAc,KAAK,SAAS;EAC1B,GAAG;EACH,UAAU,KAAK;CACjB,CAAC;AACL"}
@@ -19,6 +19,7 @@ const require_interpreter_getHTML = require('./getHTML.cjs');
19
19
  const require_interpreter_getIntlayerAsync = require('./getIntlayerAsync.cjs');
20
20
  const require_interpreter_splitAndJoinInsertion = require('./splitAndJoinInsertion.cjs');
21
21
 
22
+ exports.bindInsertedValues = require_interpreter_getContent_plugins.bindInsertedValues;
22
23
  exports.conditionPlugin = require_interpreter_getContent_plugins.conditionPlugin;
23
24
  exports.deepTransformNode = require_interpreter_getContent_deepTransform.deepTransformNode;
24
25
  exports.enumerationPlugin = require_interpreter_getContent_plugins.enumerationPlugin;
@@ -50,6 +51,7 @@ exports.nestedPlugin = require_interpreter_getContent_plugins.nestedPlugin;
50
51
  exports.pluralPlugin = require_interpreter_getContent_plugins.pluralPlugin;
51
52
  exports.readTransformCache = require_interpreter_dictionaryTransformCache.readTransformCache;
52
53
  exports.rebuildInterpolableContent = require_interpreter_interpolableNode.rebuildInterpolableContent;
54
+ exports.resolveInsertedSelector = require_interpreter_getContent_plugins.resolveInsertedSelector;
53
55
  exports.selectPlugin = require_interpreter_getContent_plugins.selectPlugin;
54
56
  exports.splitInsertionTemplate = require_interpreter_splitAndJoinInsertion.splitInsertionTemplate;
55
57
  exports.transformInterpolableNode = require_interpreter_interpolableNode.transformInterpolableNode;
@@ -22,7 +22,7 @@ import { getPlural } from "./interpreter/getPlural.mjs";
22
22
  import { getSelect } from "./interpreter/getSelect.mjs";
23
23
  import { getTranslation } from "./interpreter/getTranslation.mjs";
24
24
  import { getInterpolableContent, isInterpolableWrapperNode, rebuildInterpolableContent, transformInterpolableNode } from "./interpreter/interpolableNode.mjs";
25
- import { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, selectPlugin, translationPlugin } from "./interpreter/getContent/plugins.mjs";
25
+ import { bindInsertedValues, conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, resolveInsertedSelector, selectPlugin, translationPlugin } from "./interpreter/getContent/plugins.mjs";
26
26
  import { getBasePlugins, getContent } from "./interpreter/getContent/getContent.mjs";
27
27
  import { PRELOADED_DYNAMIC_KEY, getPreloadedDictionary } from "./dictionaryManipulator/preloadedDynamicLoader.mjs";
28
28
  import { QUALIFIER_DYNAMIC_TYPES_KEY, isQualifiedDynamicLoaderMap, resolveQualifiedDynamicContent, resolveQualifiedDynamicContentAsync } from "./dictionaryManipulator/qualifiedDynamicLoader.mjs";
@@ -114,4 +114,4 @@ import { createMessageResolver, interpolateMessage, parseTaggedMessage, resolveM
114
114
  import { isSameKeyPath } from "./utils/isSameKeyPath.mjs";
115
115
  import { stringifyYaml } from "./utils/stringifyYaml.mjs";
116
116
 
117
- export { ATTRIBUTES_TO_SANITIZE, ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, CAPTURE_LETTER_AFTER_HYPHEN, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, COMPOSITE_ID_SEPARATOR, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CachedIntl, CachedIntl as Intl, DEFAULT_VARIANT_ID, DO_NOT_PROCESS_HTML_ELEMENTS, FENCE_DELIMITER_R, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, GFM_TASK_R, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_TAGS, INLINE_SKIP_R, INTERPOLATION_R, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LOOKAHEAD, LocaleStorage, LocaleStorageClient, LocaleStorageServer, NAMED_CODES_TO_UNICODE, NP_TABLE_R, ORDERED, ORDERED_LIST_BULLET, ORDERED_LIST_ITEM_PREFIX, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, PARAGRAPH_R, PRELOADED_DYNAMIC_KEY, Priority, QUALIFIER_DYNAMIC_TYPES_KEY, QUALIFIER_ORDER, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, RuleScope, RuleType, SCOPE_BLOCK, SCOPE_BOTH, SCOPE_INLINE, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, TABLE_CENTER_ALIGN, TABLE_LEFT_ALIGN, TABLE_RIGHT_ALIGN, TABLE_TRIM_PIPES, TAB_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, UNESCAPE_R, UNORDERED, UNORDERED_LIST_BULLET, UNORDERED_LIST_ITEM_PREFIX, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R, VOID_HTML_ELEMENTS, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, comparePaths, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createMessageResolver, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, findPlainDynamicLoader, formatProxyEnabledMessage, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getDictionaryAsync, getDictionaryCompositeIds, getDictionaryQualifierIds, getDictionaryQualifierTypes, getDictionarySelectorCacheKey, getDictionaryTransformCacheKey, getDomainHostname, getDomainOrigin, getEditedContent, getEditedDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getGender, getHTML, getHTMLTextDir, getInsertion, getInsertionValues, getInternalPath, getInterpolableContent, getIntlayer, getIntlayerAsync, getLocale, getLocaleFromDomain, getLocaleFromPath, getLocaleFromRequest, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNestedDictionaryGraph, getNestedDictionaryKeys, getNestedDictionaryReferences, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPluginsCacheKey, getPlural, getPrefix, getPreloadLocale, getPreloadedDictionary, getReplacedValuesContent, getRewritePath, getRewriteRules, getRuleSet, getSelect, getSplittedContent, getSplittedDictionaryContent, getTranslation, getVariantIds, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, isDeclaredLocale, isInterpolableWrapperNode, isLocaleExclusiveOnDomain, isProxyStorageLocaleEnabled, isQualifiedDictionaryGroup, isQualifiedDynamicLoaderMap, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, mergeQualifiedDictionaries, navigatePath, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizePath, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseDictionarySelector, parseInline, parseMarkdown, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseTaggedMessage, parseYaml, parserFor, percentage, plural, pluralPlugin, portableObjectToIntlayerFormatter, presets, qualifies, readTransformCache, rebuildInterpolableContent, reconstructQualifiedEntry, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderMarkdownAst, renderNothing, resolveBrowserLocale, resolveDictionaryArgument, resolveEffectiveVariantId, resolveLocalizedPath, resolveMessage, resolveMessageNode, resolveMessageNodeToString, resolvePlainDynamicLoader, resolveProviderVariant, resolveProxyMode, resolveQualifiedDictionary, resolveQualifiedDynamicContent, resolveQualifiedDynamicContentAsync, sanitizer, select, selectPlugin, serializeVariant, serializeVariantChain, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, stringifyYaml, translation as t, transformInterpolableNode, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter, writeTransformCache };
117
+ export { ATTRIBUTES_TO_SANITIZE, ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, CAPTURE_LETTER_AFTER_HYPHEN, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, COMPOSITE_ID_SEPARATOR, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CachedIntl, CachedIntl as Intl, DEFAULT_VARIANT_ID, DO_NOT_PROCESS_HTML_ELEMENTS, FENCE_DELIMITER_R, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, GFM_TASK_R, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_TAGS, INLINE_SKIP_R, INTERPOLATION_R, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LOOKAHEAD, LocaleStorage, LocaleStorageClient, LocaleStorageServer, NAMED_CODES_TO_UNICODE, NP_TABLE_R, ORDERED, ORDERED_LIST_BULLET, ORDERED_LIST_ITEM_PREFIX, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, PARAGRAPH_R, PRELOADED_DYNAMIC_KEY, Priority, QUALIFIER_DYNAMIC_TYPES_KEY, QUALIFIER_ORDER, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, RuleScope, RuleType, SCOPE_BLOCK, SCOPE_BOTH, SCOPE_INLINE, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, TABLE_CENTER_ALIGN, TABLE_LEFT_ALIGN, TABLE_RIGHT_ALIGN, TABLE_TRIM_PIPES, TAB_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, UNESCAPE_R, UNORDERED, UNORDERED_LIST_BULLET, UNORDERED_LIST_ITEM_PREFIX, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R, VOID_HTML_ELEMENTS, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindInsertedValues, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, comparePaths, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createMessageResolver, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, findPlainDynamicLoader, formatProxyEnabledMessage, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getDictionaryAsync, getDictionaryCompositeIds, getDictionaryQualifierIds, getDictionaryQualifierTypes, getDictionarySelectorCacheKey, getDictionaryTransformCacheKey, getDomainHostname, getDomainOrigin, getEditedContent, getEditedDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getGender, getHTML, getHTMLTextDir, getInsertion, getInsertionValues, getInternalPath, getInterpolableContent, getIntlayer, getIntlayerAsync, getLocale, getLocaleFromDomain, getLocaleFromPath, getLocaleFromRequest, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNestedDictionaryGraph, getNestedDictionaryKeys, getNestedDictionaryReferences, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPluginsCacheKey, getPlural, getPrefix, getPreloadLocale, getPreloadedDictionary, getReplacedValuesContent, getRewritePath, getRewriteRules, getRuleSet, getSelect, getSplittedContent, getSplittedDictionaryContent, getTranslation, getVariantIds, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, isDeclaredLocale, isInterpolableWrapperNode, isLocaleExclusiveOnDomain, isProxyStorageLocaleEnabled, isQualifiedDictionaryGroup, isQualifiedDynamicLoaderMap, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, mergeQualifiedDictionaries, navigatePath, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizePath, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseDictionarySelector, parseInline, parseMarkdown, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseTaggedMessage, parseYaml, parserFor, percentage, plural, pluralPlugin, portableObjectToIntlayerFormatter, presets, qualifies, readTransformCache, rebuildInterpolableContent, reconstructQualifiedEntry, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderMarkdownAst, renderNothing, resolveBrowserLocale, resolveDictionaryArgument, resolveEffectiveVariantId, resolveInsertedSelector, resolveLocalizedPath, resolveMessage, resolveMessageNode, resolveMessageNodeToString, resolvePlainDynamicLoader, resolveProviderVariant, resolveProxyMode, resolveQualifiedDictionary, resolveQualifiedDynamicContent, resolveQualifiedDynamicContentAsync, sanitizer, select, selectPlugin, serializeVariant, serializeVariantChain, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, stringifyYaml, translation as t, transformInterpolableNode, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter, writeTransformCache };
@@ -1,11 +1,12 @@
1
1
  import { deepTransformNode } from "./deepTransform.mjs";
2
- import { conditionPlugin, enumerationPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, selectPlugin, translationPlugin } from "./plugins.mjs";
2
+ import { conditionPlugin, enumerationPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, selectPlugin, translationPlugin } from "./plugins.mjs";
3
3
  import { internationalization } from "@intlayer/config/built";
4
4
 
5
5
  //#region src/interpreter/getContent/getContent.ts
6
6
  const getBasePlugins = (locale, fallback = true) => [
7
7
  translationPlugin(locale ?? internationalization.defaultLocale, fallback ? internationalization.defaultLocale : void 0),
8
8
  enumerationPlugin,
9
+ pluralPlugin(locale ?? internationalization.defaultLocale),
9
10
  conditionPlugin,
10
11
  insertionPlugin,
11
12
  nestedPlugin(locale ?? internationalization.defaultLocale),
@@ -1 +1 @@
1
- {"version":3,"file":"getContent.mjs","names":[],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n selectPlugin,\n translationPlugin,\n} from './plugins';\n\nexport const getBasePlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] =>\n [\n translationPlugin(\n locale ?? internationalization.defaultLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n conditionPlugin,\n insertionPlugin,\n nestedPlugin(locale ?? internationalization.defaultLocale),\n filePlugin,\n genderPlugin,\n selectPlugin,\n ] as Plugins[];\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n const T extends ContentNode,\n const L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n plugins: Plugins[] = []\n) =>\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n"],"mappings":";;;;;AAsBA,MAAa,kBACX,QACA,WAAoB,SAEpB;CACE,kBACE,UAAU,qBAAqB,eAC/B,WAAW,qBAAqB,gBAAgB,MAClD;CACA;CACA;CACA;CACA,aAAa,UAAU,qBAAqB,aAAa;CACzD;CACA;CACA;AACF;;;;;;;AAQF,MAAa,cAIX,MACA,WACA,UAAqB,CAAC,MAEtB,kBAAkB,MAAM;CACtB,GAAG;CACH;AACF,CAAC"}
1
+ {"version":3,"file":"getContent.mjs","names":[],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n pluralPlugin,\n selectPlugin,\n translationPlugin,\n} from './plugins';\n\nexport const getBasePlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] =>\n [\n translationPlugin(\n locale ?? internationalization.defaultLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n pluralPlugin(locale ?? internationalization.defaultLocale),\n conditionPlugin,\n insertionPlugin,\n nestedPlugin(locale ?? internationalization.defaultLocale),\n filePlugin,\n genderPlugin,\n selectPlugin,\n ] as Plugins[];\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n const T extends ContentNode,\n const L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n plugins: Plugins[] = []\n) =>\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n"],"mappings":";;;;;AAuBA,MAAa,kBACX,QACA,WAAoB,SAEpB;CACE,kBACE,UAAU,qBAAqB,eAC/B,WAAW,qBAAqB,gBAAgB,MAClD;CACA;CACA,aAAa,UAAU,qBAAqB,aAAa;CACzD;CACA;CACA,aAAa,UAAU,qBAAqB,aAAa;CACzD;CACA;CACA;AACF;;;;;;;AAQF,MAAa,cAIX,MACA,WACA,UAAqB,CAAC,MAEtB,kBAAkB,MAAM;CACtB,GAAG;CACH;AACF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { deepTransformNode } from "./deepTransform.mjs";
2
- import { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, selectPlugin, translationPlugin } from "./plugins.mjs";
2
+ import { bindInsertedValues, conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, resolveInsertedSelector, selectPlugin, translationPlugin } from "./plugins.mjs";
3
3
  import { getBasePlugins, getContent } from "./getContent.mjs";
4
4
 
5
- export { conditionPlugin, deepTransformNode, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, getBasePlugins, getContent, insertionPlugin, nestedPlugin, pluralPlugin, selectPlugin, translationPlugin };
5
+ export { bindInsertedValues, conditionPlugin, deepTransformNode, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, getBasePlugins, getContent, insertionPlugin, nestedPlugin, pluralPlugin, resolveInsertedSelector, selectPlugin, translationPlugin };
@@ -79,22 +79,27 @@ const pluralPlugin = (locale) => process.env.INTLAYER_NODE_TYPE_PLURAL === "fals
79
79
  transform: (node, props, deepTransformNode) => {
80
80
  const original = node[NodeTypes.PLURAL];
81
81
  const result = {};
82
+ const branchPlugins = (props.plugins ?? []).filter((plugin) => plugin.id !== "insertion-string-plugin");
82
83
  /** String plugin for plural. Replaces string node with a component that renders the insertion. */
83
84
  const pluralStringPlugin = {
84
85
  id: "plural-string-plugin",
85
86
  canHandle: (node) => typeof node === "string" || isInterpolableWrapperNode(node),
86
87
  transform: (node, subProps, deepTransformNode) => {
87
- if (isInterpolableWrapperNode(node)) return (values) => transformInterpolableNode(node, values, subProps, props.plugins, deepTransformNode);
88
+ if (subProps.keyPath.slice(props.keyPath.length).some((keyPath) => keyPath.type === NodeTypes.INSERTION)) return deepTransformNode(node, {
89
+ ...subProps,
90
+ plugins: subProps.plugins?.filter((plugin) => plugin.id !== "plural-string-plugin")
91
+ });
92
+ if (isInterpolableWrapperNode(node)) return (values) => transformInterpolableNode(node, values, subProps, branchPlugins, deepTransformNode);
88
93
  const transformedResult = deepTransformNode(node, {
89
94
  ...subProps,
90
95
  children: node,
91
- plugins: [...(props.plugins ?? []).filter((plugin) => plugin.id !== "intlayer-node-plugin")]
96
+ plugins: [...branchPlugins.filter((plugin) => plugin.id !== "intlayer-node-plugin")]
92
97
  });
93
98
  return (values) => {
94
99
  const children = getInsertion(transformedResult, values);
95
100
  return deepTransformNode(children, {
96
101
  ...subProps,
97
- plugins: props.plugins,
102
+ plugins: branchPlugins,
98
103
  children
99
104
  });
100
105
  };
@@ -109,7 +114,7 @@ const pluralPlugin = (locale) => process.env.INTLAYER_NODE_TYPE_PLURAL === "fals
109
114
  type: NodeTypes.PLURAL,
110
115
  key
111
116
  }],
112
- plugins: [pluralStringPlugin, ...props.plugins ?? []]
117
+ plugins: [pluralStringPlugin, ...branchPlugins]
113
118
  });
114
119
  }
115
120
  const effectiveLocale = String(locale ?? props.locale ?? "en");
@@ -176,14 +181,63 @@ const insertionPlugin = process.env.INTLAYER_NODE_TYPE_INSERTION === "false" ? f
176
181
  };
177
182
  }
178
183
  };
179
- return deepTransformNode(children, {
184
+ const result = deepTransformNode(children, {
180
185
  ...props,
181
186
  children,
182
187
  keyPath: newKeyPath,
183
188
  plugins: [insertionStringPlugin, ...props.plugins ?? []]
184
189
  });
190
+ return resolveInsertedSelector(children, result);
185
191
  }
186
192
  };
193
+ /** Container nodes resolved by a selector call: `enu(3)`, `cond(true)`, … */
194
+ const selectorNodeTypes = [
195
+ NodeTypes.ENUMERATION,
196
+ NodeTypes.CONDITION,
197
+ NodeTypes.PLURAL,
198
+ NodeTypes.GENDER,
199
+ NodeTypes.SELECT
200
+ ];
201
+ /**
202
+ * Binds the values of an `insert()` to the selector node it wraps, returning
203
+ * `(selector) => content`. Any other child result is returned unchanged.
204
+ *
205
+ * `areBranchesInterpolated` is set by frameworks that interpolate the branch
206
+ * strings as soon as the values are known: the selected branch is then final
207
+ * content and is never called with the values.
208
+ */
209
+ const bindInsertedValues = (children, result, values, areBranchesInterpolated = false) => {
210
+ const nodeType = children?.nodeType;
211
+ if (typeof result !== "function" || !nodeType || !selectorNodeTypes.includes(nodeType)) return result;
212
+ const isPlural = nodeType === NodeTypes.PLURAL;
213
+ const isEnumeration = nodeType === NodeTypes.ENUMERATION;
214
+ return (selector) => {
215
+ if (typeof selector === "object" && selector !== null) return result({
216
+ ...values,
217
+ ...selector
218
+ });
219
+ if (isPlural) return result({
220
+ ...values,
221
+ count: selector
222
+ });
223
+ if (isEnumeration && typeof selector === "number") {
224
+ const mergedValues = {
225
+ count: selector,
226
+ ...values
227
+ };
228
+ const selected = result(mergedValues);
229
+ return !areBranchesInterpolated && typeof selected === "function" ? selected(mergedValues) : selected;
230
+ }
231
+ const selected = result(selector);
232
+ return !areBranchesInterpolated && typeof selected === "function" ? selected(values) : selected;
233
+ };
234
+ };
235
+ /**
236
+ * Shapes the result of `insert()` wrapping a selector node as
237
+ * `(values) => (selector) => content`, so the values reach the selected
238
+ * branch. Any other child result is returned unchanged.
239
+ */
240
+ const resolveInsertedSelector = (children, result) => typeof result === "function" && selectorNodeTypes.includes(children?.nodeType ?? "") ? (values) => bindInsertedValues(children, result, values) : result;
187
241
  /** Gender plugin. Replaces node with a function that takes gender => string. */
188
242
  const genderPlugin = process.env.INTLAYER_NODE_TYPE_GENDER === "false" ? fallbackPlugin : {
189
243
  id: "gender-plugin",
@@ -261,5 +315,5 @@ const filePlugin = process.env.INTLAYER_NODE_TYPE_FILE === "false" ? fallbackPlu
261
315
  };
262
316
 
263
317
  //#endregion
264
- export { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, selectPlugin, translationPlugin };
318
+ export { bindInsertedValues, conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, resolveInsertedSelector, selectPlugin, translationPlugin };
265
319
  //# sourceMappingURL=plugins.mjs.map