@intlayer/core 8.7.14 → 8.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs +3 -3
  2. package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs.map +1 -1
  3. package/dist/cjs/dictionaryManipulator/getContentNodeByKeyPath.cjs +1 -1
  4. package/dist/cjs/dictionaryManipulator/getContentNodeByKeyPath.cjs.map +1 -1
  5. package/dist/cjs/dictionaryManipulator/getDefaultNode.cjs +7 -0
  6. package/dist/cjs/dictionaryManipulator/getDefaultNode.cjs.map +1 -1
  7. package/dist/cjs/dictionaryManipulator/getEmptyNode.cjs +1 -1
  8. package/dist/cjs/dictionaryManipulator/getEmptyNode.cjs.map +1 -1
  9. package/dist/cjs/dictionaryManipulator/getNodeChildren.cjs +1 -1
  10. package/dist/cjs/dictionaryManipulator/getNodeChildren.cjs.map +1 -1
  11. package/dist/cjs/dictionaryManipulator/getNodeType.cjs +1 -0
  12. package/dist/cjs/dictionaryManipulator/getNodeType.cjs.map +1 -1
  13. package/dist/cjs/dictionaryManipulator/removeContentNodeByKeyPath.cjs +1 -1
  14. package/dist/cjs/dictionaryManipulator/removeContentNodeByKeyPath.cjs.map +1 -1
  15. package/dist/cjs/dictionaryManipulator/renameContentNodeByKeyPath.cjs +1 -1
  16. package/dist/cjs/dictionaryManipulator/renameContentNodeByKeyPath.cjs.map +1 -1
  17. package/dist/cjs/dictionaryManipulator/updateNodeChildren.cjs +1 -1
  18. package/dist/cjs/dictionaryManipulator/updateNodeChildren.cjs.map +1 -1
  19. package/dist/cjs/index.cjs +14 -9
  20. package/dist/cjs/interpreter/getContent/index.cjs +1 -0
  21. package/dist/cjs/interpreter/getContent/plugins.cjs +55 -0
  22. package/dist/cjs/interpreter/getContent/plugins.cjs.map +1 -1
  23. package/dist/cjs/interpreter/getIntlayer.cjs +8 -4
  24. package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
  25. package/dist/cjs/interpreter/getPlural.cjs +26 -0
  26. package/dist/cjs/interpreter/getPlural.cjs.map +1 -0
  27. package/dist/cjs/interpreter/index.cjs +3 -0
  28. package/dist/cjs/transpiler/index.cjs +2 -0
  29. package/dist/cjs/transpiler/plural/index.cjs +4 -0
  30. package/dist/cjs/transpiler/plural/plural.cjs +33 -0
  31. package/dist/cjs/transpiler/plural/plural.cjs.map +1 -0
  32. package/dist/cjs/utils/index.cjs +1 -1
  33. package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs +3 -3
  34. package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs.map +1 -1
  35. package/dist/esm/dictionaryManipulator/getContentNodeByKeyPath.mjs +1 -1
  36. package/dist/esm/dictionaryManipulator/getContentNodeByKeyPath.mjs.map +1 -1
  37. package/dist/esm/dictionaryManipulator/getDefaultNode.mjs +7 -0
  38. package/dist/esm/dictionaryManipulator/getDefaultNode.mjs.map +1 -1
  39. package/dist/esm/dictionaryManipulator/getEmptyNode.mjs +1 -1
  40. package/dist/esm/dictionaryManipulator/getEmptyNode.mjs.map +1 -1
  41. package/dist/esm/dictionaryManipulator/getNodeChildren.mjs +1 -1
  42. package/dist/esm/dictionaryManipulator/getNodeChildren.mjs.map +1 -1
  43. package/dist/esm/dictionaryManipulator/getNodeType.mjs +1 -0
  44. package/dist/esm/dictionaryManipulator/getNodeType.mjs.map +1 -1
  45. package/dist/esm/dictionaryManipulator/removeContentNodeByKeyPath.mjs +1 -1
  46. package/dist/esm/dictionaryManipulator/removeContentNodeByKeyPath.mjs.map +1 -1
  47. package/dist/esm/dictionaryManipulator/renameContentNodeByKeyPath.mjs +1 -1
  48. package/dist/esm/dictionaryManipulator/renameContentNodeByKeyPath.mjs.map +1 -1
  49. package/dist/esm/dictionaryManipulator/updateNodeChildren.mjs +1 -1
  50. package/dist/esm/dictionaryManipulator/updateNodeChildren.mjs.map +1 -1
  51. package/dist/esm/index.mjs +13 -11
  52. package/dist/esm/interpreter/getContent/index.mjs +2 -2
  53. package/dist/esm/interpreter/getContent/plugins.mjs +55 -1
  54. package/dist/esm/interpreter/getContent/plugins.mjs.map +1 -1
  55. package/dist/esm/interpreter/getIntlayer.mjs +8 -4
  56. package/dist/esm/interpreter/getIntlayer.mjs.map +1 -1
  57. package/dist/esm/interpreter/getPlural.mjs +25 -0
  58. package/dist/esm/interpreter/getPlural.mjs.map +1 -0
  59. package/dist/esm/interpreter/index.mjs +3 -2
  60. package/dist/esm/transpiler/index.mjs +2 -1
  61. package/dist/esm/transpiler/plural/index.mjs +3 -0
  62. package/dist/esm/transpiler/plural/plural.mjs +31 -0
  63. package/dist/esm/transpiler/plural/plural.mjs.map +1 -0
  64. package/dist/esm/utils/index.mjs +1 -1
  65. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +12 -12
  66. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts.map +1 -1
  67. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +12 -12
  68. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts.map +1 -1
  69. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +10 -10
  70. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts.map +1 -1
  71. package/dist/types/dictionaryManipulator/getNodeType.d.ts.map +1 -1
  72. package/dist/types/index.d.ts +4 -2
  73. package/dist/types/interpreter/getContent/index.d.ts +2 -2
  74. package/dist/types/interpreter/getContent/plugins.d.ts +19 -1
  75. package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
  76. package/dist/types/interpreter/getIntlayer.d.ts.map +1 -1
  77. package/dist/types/interpreter/getPlural.d.ts +24 -0
  78. package/dist/types/interpreter/getPlural.d.ts.map +1 -0
  79. package/dist/types/interpreter/index.d.ts +3 -2
  80. package/dist/types/transpiler/index.d.ts +2 -1
  81. package/dist/types/transpiler/plural/index.d.ts +2 -0
  82. package/dist/types/transpiler/plural/plural.d.ts +35 -0
  83. package/dist/types/transpiler/plural/plural.d.ts.map +1 -0
  84. package/package.json +6 -6
@@ -0,0 +1,26 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_utils_intl = require('../utils/intl.cjs');
3
+
4
+ //#region src/interpreter/getPlural.ts
5
+ /**
6
+ * Picks content from a plural map based on a count and locale, using CLDR
7
+ * pluralization rules (`Intl.PluralRules`).
8
+ *
9
+ * Falls back to the `other` category when no specific category matches.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * getPlural({
14
+ * one: 'one item',
15
+ * other: '{{count}} items',
16
+ * }, 5, 'en');
17
+ * // '{{count}} items'
18
+ * ```
19
+ */
20
+ const getPlural = (pluralContent, count, locale) => {
21
+ return pluralContent[require_utils_intl.getCachedIntl(Intl.PluralRules, locale).select(count)] ?? pluralContent.other;
22
+ };
23
+
24
+ //#endregion
25
+ exports.getPlural = getPlural;
26
+ //# sourceMappingURL=getPlural.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getPlural.cjs","names":["getCachedIntl"],"sources":["../../../src/interpreter/getPlural.ts"],"sourcesContent":["import type { DeclaredLocales } from '@intlayer/types';\nimport type { LocalesValues } from 'intlayer';\nimport { getCachedIntl } from '../formatters';\nimport type {\n PluralCategory,\n PluralContentState,\n} from '../transpiler/plural/plural';\n\n/**\n * Picks content from a plural map based on a count and locale, using CLDR\n * pluralization rules (`Intl.PluralRules`).\n *\n * Falls back to the `other` category when no specific category matches.\n *\n * @example\n * ```ts\n * getPlural({\n * one: 'one item',\n * other: '{{count}} items',\n * }, 5, 'en');\n * // '{{count}} items'\n * ```\n */\nexport const getPlural = <L extends LocalesValues = DeclaredLocales>(\n pluralContent: PluralContentState<string>,\n count: number,\n locale: L\n): string => {\n const category = getCachedIntl(Intl.PluralRules, locale).select(\n count\n ) as PluralCategory;\n\n return pluralContent[category] ?? pluralContent.other;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAuBA,MAAa,aACX,eACA,OACA,WACW;AAKX,QAAO,cAJUA,iCAAc,KAAK,aAAa,OAAO,CAAC,OACvD,MAG2B,KAAK,cAAc"}
@@ -5,6 +5,7 @@ const require_interpreter_getEnumeration = require('./getEnumeration.cjs');
5
5
  const require_interpreter_getDictionary = require('./getDictionary.cjs');
6
6
  const require_interpreter_getIntlayer = require('./getIntlayer.cjs');
7
7
  const require_interpreter_getNesting = require('./getNesting.cjs');
8
+ const require_interpreter_getPlural = require('./getPlural.cjs');
8
9
  const require_interpreter_getTranslation = require('./getTranslation.cjs');
9
10
  const require_interpreter_getContent_plugins = require('./getContent/plugins.cjs');
10
11
  const require_interpreter_getContent_getContent = require('./getContent/getContent.cjs');
@@ -26,8 +27,10 @@ exports.getEnumeration = require_interpreter_getEnumeration.getEnumeration;
26
27
  exports.getHTML = require_interpreter_getHTML.getHTML;
27
28
  exports.getIntlayer = require_interpreter_getIntlayer.getIntlayer;
28
29
  exports.getNesting = require_interpreter_getNesting.getNesting;
30
+ exports.getPlural = require_interpreter_getPlural.getPlural;
29
31
  exports.getTranslation = require_interpreter_getTranslation.getTranslation;
30
32
  exports.insertionPlugin = require_interpreter_getContent_plugins.insertionPlugin;
31
33
  exports.nestedPlugin = require_interpreter_getContent_plugins.nestedPlugin;
34
+ exports.pluralPlugin = require_interpreter_getContent_plugins.pluralPlugin;
32
35
  exports.splitInsertionTemplate = require_interpreter_splitAndJoinInsertion.splitInsertionTemplate;
33
36
  exports.translationPlugin = require_interpreter_getContent_plugins.translationPlugin;
@@ -11,6 +11,7 @@ const require_transpiler_markdown_getMarkdownMetadata = require('./markdown/getM
11
11
  const require_transpiler_markdown_validateMarkdown = require('./markdown/validateMarkdown.cjs');
12
12
  const require_transpiler_markdown_markdown = require('./markdown/markdown.cjs');
13
13
  const require_transpiler_nesting_nesting = require('./nesting/nesting.cjs');
14
+ const require_transpiler_plural_plural = require('./plural/plural.cjs');
14
15
  const require_transpiler_translation_translation = require('./translation/translation.cjs');
15
16
 
16
17
  exports.HTML_TAGS = require_transpiler_html_htmlTags.HTML_TAGS;
@@ -24,6 +25,7 @@ exports.html = require_transpiler_html_html.html;
24
25
  exports.insert = require_transpiler_insertion_insertion.insert;
25
26
  exports.md = require_transpiler_markdown_markdown.md;
26
27
  exports.nest = require_transpiler_nesting_nesting.nest;
28
+ exports.plural = require_transpiler_plural_plural.plural;
27
29
  exports.t = require_transpiler_translation_translation.t;
28
30
  exports.validateHTML = require_transpiler_html_validateHTML.validateHTML;
29
31
  exports.validateMarkdown = require_transpiler_markdown_validateMarkdown.validateMarkdown;
@@ -0,0 +1,4 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_transpiler_plural_plural = require('./plural.cjs');
3
+
4
+ exports.plural = require_transpiler_plural_plural.plural;
@@ -0,0 +1,33 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
3
+ let _intlayer_types_nodeType = require("@intlayer/types/nodeType");
4
+
5
+ //#region src/transpiler/plural/plural.ts
6
+ /**
7
+ * Function intended to be used to build intlayer dictionaries.
8
+ *
9
+ * Allow to pick a content based on a quantity using CLDR pluralization rules
10
+ * (`Intl.PluralRules`). The selected category depends on the active locale.
11
+ *
12
+ * Supported categories: `zero`, `one`, `two`, `few`, `many`, `other`.
13
+ * `other` is required as the fallback.
14
+ *
15
+ * The string content can include a `{{count}}` placeholder, which is
16
+ * automatically replaced with the provided count.
17
+ *
18
+ * Usage:
19
+ *
20
+ * ```ts
21
+ * plural({
22
+ * one: '{{count}} вакансия',
23
+ * few: '{{count}} вакансии',
24
+ * many: '{{count}} вакансий',
25
+ * other: '{{count}} вакансий',
26
+ * });
27
+ * ```
28
+ */
29
+ const plural = (content) => (0, _intlayer_types_nodeType.formatNodeType)(_intlayer_types_nodeType.PLURAL, content);
30
+
31
+ //#endregion
32
+ exports.plural = plural;
33
+ //# sourceMappingURL=plural.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plural.cjs","names":["PLURAL"],"sources":["../../../../src/transpiler/plural/plural.ts"],"sourcesContent":["import type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { formatNodeType, PLURAL } from '@intlayer/types/nodeType';\n\nexport type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';\n\nexport type PluralContentState<Content> = Partial<\n Record<PluralCategory, Content>\n> & {\n other: Content;\n};\n\nexport type PluralContent<Content = unknown> = TypedNodeModel<\n typeof PLURAL,\n PluralContentState<Content>\n>;\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow to pick a content based on a quantity using CLDR pluralization rules\n * (`Intl.PluralRules`). The selected category depends on the active locale.\n *\n * Supported categories: `zero`, `one`, `two`, `few`, `many`, `other`.\n * `other` is required as the fallback.\n *\n * The string content can include a `{{count}}` placeholder, which is\n * automatically replaced with the provided count.\n *\n * Usage:\n *\n * ```ts\n * plural({\n * one: '{{count}} вакансия',\n * few: '{{count}} вакансии',\n * many: '{{count}} вакансий',\n * other: '{{count}} вакансий',\n * });\n * ```\n */\nconst plural = <Content = unknown>(\n content: PluralContentState<Content>\n): PluralContent<Content> => formatNodeType(PLURAL, content);\n\nexport { plural };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAM,UACJ,yDAC0CA,iCAAQ,QAAQ"}
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_utils_intl = require('./intl.cjs');
2
3
  const require_utils_parseYaml = require('./parseYaml.cjs');
3
4
  const require_utils_isValidReactElement = require('./isValidReactElement.cjs');
4
- const require_utils_intl = require('./intl.cjs');
5
5
  const require_utils_checkIsURLAbsolute = require('./checkIsURLAbsolute.cjs');
6
6
  const require_utils_getCookie = require('./getCookie.cjs');
7
7
  const require_utils_localeStorage = require('./localeStorage.cjs');
@@ -15,14 +15,14 @@ const editDictionaryByKeyPath = (dictionaryContent, keyPath, newValue) => {
15
15
  if (!currentValue[keyObj.key] || typeof currentValue[keyObj.key] !== "object") currentValue[keyObj.key] = {};
16
16
  currentValue = currentValue[keyObj.key];
17
17
  }
18
- if (keyObj.type === NodeTypes.TRANSLATION || keyObj.type === NodeTypes.ENUMERATION) {
18
+ if (keyObj.type === NodeTypes.TRANSLATION || keyObj.type === NodeTypes.ENUMERATION || keyObj.type === NodeTypes.PLURAL) {
19
19
  lastKeys = [keyObj.type, keyObj.key];
20
20
  if (!currentValue[keyObj.type] || typeof currentValue[keyObj.type] !== "object") currentValue[keyObj.type] = {};
21
21
  if (!currentValue[keyObj.type][keyObj.key] || typeof currentValue[keyObj.type][keyObj.key] !== "object") currentValue[keyObj.type][keyObj.key] = {};
22
22
  currentValue = currentValue[keyObj.type][keyObj.key];
23
23
  }
24
- if (keyObj.type === NodeTypes.ENUMERATION || keyObj.type === NodeTypes.CONDITION) {
25
- if (keyObj.type !== NodeTypes.ENUMERATION) {
24
+ if (keyObj.type === NodeTypes.ENUMERATION || keyObj.type === NodeTypes.PLURAL || keyObj.type === NodeTypes.CONDITION) {
25
+ if (keyObj.type !== NodeTypes.ENUMERATION && keyObj.type !== NodeTypes.PLURAL) {
26
26
  lastKeys = [keyObj.type, keyObj.key];
27
27
  currentValue = currentValue[keyObj.type][keyObj.key];
28
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"editDictionaryByKeyPath.mjs","names":[],"sources":["../../../src/dictionaryManipulator/editDictionaryByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\ntype LastKeyType = string | number;\n\nexport const editDictionaryByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[],\n newValue: ContentNode\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKeys: LastKeyType[] = [];\n\n if (keyPath.length === 0) {\n return newValue;\n }\n\n try {\n for (let i = 0; i < keyPath.length; i++) {\n const keyObj = keyPath[i];\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKeys = [keyObj.key];\n\n if (\n !currentValue[keyObj.key] ||\n typeof currentValue[keyObj.key] !== 'object'\n ) {\n currentValue[keyObj.key] = {};\n }\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION\n ) {\n lastKeys = [keyObj.type, keyObj.key];\n\n if (\n !currentValue[keyObj.type] ||\n typeof currentValue[keyObj.type] !== 'object'\n ) {\n currentValue[keyObj.type] = {};\n }\n\n if (\n !currentValue[keyObj.type][keyObj.key] ||\n typeof currentValue[keyObj.type][keyObj.key] !== 'object'\n ) {\n currentValue[keyObj.type][keyObj.key] = {};\n }\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n // Note: Logic above already handles Enumeration, ensure no duplication in your actual file\n // or keep the specific block if your logic differs.\n // The important part is below in the final update block.\n\n // Assuming this block runs for Condition/Gender/etc:\n\n if (keyObj.type !== NodeTypes.ENUMERATION) {\n lastKeys = [keyObj.type, keyObj.key];\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION\n ) {\n lastKeys = [keyObj.type];\n\n if (\n !currentValue[keyObj.type] ||\n typeof currentValue[keyObj.type] !== 'object'\n ) {\n currentValue[keyObj.type] = '';\n }\n currentValue = currentValue[keyObj.type];\n }\n\n if (keyObj.type === NodeTypes.FILE) {\n lastKeys = ['content'];\n currentValue = currentValue.content;\n }\n\n // Only update the value when processing the last key in the keyPath.\n\n if (i === keyPath.length - 1 && parentValue && lastKeys.length > 0) {\n let target = parentValue;\n\n // Drill down to the container holding the value to be changed\n for (const key of lastKeys.slice(0, -1)) {\n target = target[key];\n }\n\n const finalKey = lastKeys[lastKeys.length - 1];\n\n if (typeof newValue === 'undefined') {\n // Use splice for arrays to re-index the list, use delete for objects\n\n if (Array.isArray(target)) {\n const index = Number(finalKey);\n\n if (!Number.isNaN(index) && index >= 0 && index < target.length) {\n target.splice(index, 1);\n }\n } else {\n delete target[finalKey];\n }\n } else {\n target[finalKey] = newValue;\n }\n }\n }\n\n return dictionaryContent;\n } catch (error) {\n console.error(\n 'Cannot edit dictionary by key path',\n { dictionaryContent, keyPath, newValue },\n error\n );\n return dictionaryContent;\n }\n};\n"],"mappings":";;;AAMA,MAAa,2BACX,mBACA,SACA,aACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,WAA0B,EAAE;AAEhC,KAAI,QAAQ,WAAW,EACrB,QAAO;AAGT,KAAI;AACF,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;AACvB,iBAAc;AAEd,OAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,OAAO;AACvE,eAAW,CAAC,OAAO,IAAI;AAEvB,QACE,CAAC,aAAa,OAAO,QACrB,OAAO,aAAa,OAAO,SAAS,SAEpC,cAAa,OAAO,OAAO,EAAE;AAE/B,mBAAe,aAAa,OAAO;;AAGrC,OACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,aAC1B;AACA,eAAW,CAAC,OAAO,MAAM,OAAO,IAAI;AAEpC,QACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,SAErC,cAAa,OAAO,QAAQ,EAAE;AAGhC,QACE,CAAC,aAAa,OAAO,MAAM,OAAO,QAClC,OAAO,aAAa,OAAO,MAAM,OAAO,SAAS,SAEjD,cAAa,OAAO,MAAM,OAAO,OAAO,EAAE;AAE5C,mBAAe,aAAa,OAAO,MAAM,OAAO;;AAGlD,OACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,WAQ1B;QAAI,OAAO,SAAS,UAAU,aAAa;AACzC,gBAAW,CAAC,OAAO,MAAM,OAAO,IAAI;AACpC,oBAAe,aAAa,OAAO,MAAM,OAAO;;;AAIpD,OACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,WAC1B;AACA,eAAW,CAAC,OAAO,KAAK;AAExB,QACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,SAErC,cAAa,OAAO,QAAQ;AAE9B,mBAAe,aAAa,OAAO;;AAGrC,OAAI,OAAO,SAAS,UAAU,MAAM;AAClC,eAAW,CAAC,UAAU;AACtB,mBAAe,aAAa;;AAK9B,OAAI,MAAM,QAAQ,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;IAClE,IAAI,SAAS;AAGb,SAAK,MAAM,OAAO,SAAS,MAAM,GAAG,GAAG,CACrC,UAAS,OAAO;IAGlB,MAAM,WAAW,SAAS,SAAS,SAAS;AAE5C,QAAI,OAAO,aAAa,YAGtB,KAAI,MAAM,QAAQ,OAAO,EAAE;KACzB,MAAM,QAAQ,OAAO,SAAS;AAE9B,SAAI,CAAC,OAAO,MAAM,MAAM,IAAI,SAAS,KAAK,QAAQ,OAAO,OACvD,QAAO,OAAO,OAAO,EAAE;UAGzB,QAAO,OAAO;QAGhB,QAAO,YAAY;;;AAKzB,SAAO;UACA,OAAO;AACd,UAAQ,MACN,sCACA;GAAE;GAAmB;GAAS;GAAU,EACxC,MACD;AACD,SAAO"}
1
+ {"version":3,"file":"editDictionaryByKeyPath.mjs","names":[],"sources":["../../../src/dictionaryManipulator/editDictionaryByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\ntype LastKeyType = string | number;\n\nexport const editDictionaryByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[],\n newValue: ContentNode\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKeys: LastKeyType[] = [];\n\n if (keyPath.length === 0) {\n return newValue;\n }\n\n try {\n for (let i = 0; i < keyPath.length; i++) {\n const keyObj = keyPath[i];\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKeys = [keyObj.key];\n\n if (\n !currentValue[keyObj.key] ||\n typeof currentValue[keyObj.key] !== 'object'\n ) {\n currentValue[keyObj.key] = {};\n }\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL\n ) {\n lastKeys = [keyObj.type, keyObj.key];\n\n if (\n !currentValue[keyObj.type] ||\n typeof currentValue[keyObj.type] !== 'object'\n ) {\n currentValue[keyObj.type] = {};\n }\n\n if (\n !currentValue[keyObj.type][keyObj.key] ||\n typeof currentValue[keyObj.type][keyObj.key] !== 'object'\n ) {\n currentValue[keyObj.type][keyObj.key] = {};\n }\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n // Note: Logic above already handles Enumeration/Plural, ensure no duplication in your actual file\n // or keep the specific block if your logic differs.\n // The important part is below in the final update block.\n\n // Assuming this block runs for Condition/Gender/etc:\n\n if (\n keyObj.type !== NodeTypes.ENUMERATION &&\n keyObj.type !== NodeTypes.PLURAL\n ) {\n lastKeys = [keyObj.type, keyObj.key];\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION\n ) {\n lastKeys = [keyObj.type];\n\n if (\n !currentValue[keyObj.type] ||\n typeof currentValue[keyObj.type] !== 'object'\n ) {\n currentValue[keyObj.type] = '';\n }\n currentValue = currentValue[keyObj.type];\n }\n\n if (keyObj.type === NodeTypes.FILE) {\n lastKeys = ['content'];\n currentValue = currentValue.content;\n }\n\n // Only update the value when processing the last key in the keyPath.\n\n if (i === keyPath.length - 1 && parentValue && lastKeys.length > 0) {\n let target = parentValue;\n\n // Drill down to the container holding the value to be changed\n for (const key of lastKeys.slice(0, -1)) {\n target = target[key];\n }\n\n const finalKey = lastKeys[lastKeys.length - 1];\n\n if (typeof newValue === 'undefined') {\n // Use splice for arrays to re-index the list, use delete for objects\n\n if (Array.isArray(target)) {\n const index = Number(finalKey);\n\n if (!Number.isNaN(index) && index >= 0 && index < target.length) {\n target.splice(index, 1);\n }\n } else {\n delete target[finalKey];\n }\n } else {\n target[finalKey] = newValue;\n }\n }\n }\n\n return dictionaryContent;\n } catch (error) {\n console.error(\n 'Cannot edit dictionary by key path',\n { dictionaryContent, keyPath, newValue },\n error\n );\n return dictionaryContent;\n }\n};\n"],"mappings":";;;AAMA,MAAa,2BACX,mBACA,SACA,aACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,WAA0B,EAAE;AAEhC,KAAI,QAAQ,WAAW,EACrB,QAAO;AAGT,KAAI;AACF,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;AACvB,iBAAc;AAEd,OAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,OAAO;AACvE,eAAW,CAAC,OAAO,IAAI;AAEvB,QACE,CAAC,aAAa,OAAO,QACrB,OAAO,aAAa,OAAO,SAAS,SAEpC,cAAa,OAAO,OAAO,EAAE;AAE/B,mBAAe,aAAa,OAAO;;AAGrC,OACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,QAC1B;AACA,eAAW,CAAC,OAAO,MAAM,OAAO,IAAI;AAEpC,QACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,SAErC,cAAa,OAAO,QAAQ,EAAE;AAGhC,QACE,CAAC,aAAa,OAAO,MAAM,OAAO,QAClC,OAAO,aAAa,OAAO,MAAM,OAAO,SAAS,SAEjD,cAAa,OAAO,MAAM,OAAO,OAAO,EAAE;AAE5C,mBAAe,aAAa,OAAO,MAAM,OAAO;;AAGlD,OACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,UAC1B,OAAO,SAAS,UAAU,WAQ1B;QACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,QAC1B;AACA,gBAAW,CAAC,OAAO,MAAM,OAAO,IAAI;AACpC,oBAAe,aAAa,OAAO,MAAM,OAAO;;;AAIpD,OACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,WAC1B;AACA,eAAW,CAAC,OAAO,KAAK;AAExB,QACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,SAErC,cAAa,OAAO,QAAQ;AAE9B,mBAAe,aAAa,OAAO;;AAGrC,OAAI,OAAO,SAAS,UAAU,MAAM;AAClC,eAAW,CAAC,UAAU;AACtB,mBAAe,aAAa;;AAK9B,OAAI,MAAM,QAAQ,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;IAClE,IAAI,SAAS;AAGb,SAAK,MAAM,OAAO,SAAS,MAAM,GAAG,GAAG,CACrC,UAAS,OAAO;IAGlB,MAAM,WAAW,SAAS,SAAS,SAAS;AAE5C,QAAI,OAAO,aAAa,YAGtB,KAAI,MAAM,QAAQ,OAAO,EAAE;KACzB,MAAM,QAAQ,OAAO,SAAS;AAE9B,SAAI,CAAC,OAAO,MAAM,MAAM,IAAI,SAAS,KAAK,QAAQ,OAAO,OACvD,QAAO,OAAO,OAAO,EAAE;UAGzB,QAAO,OAAO;QAGhB,QAAO,YAAY;;;AAKzB,SAAO;UACA,OAAO;AACd,UAAQ,MACN,sCACA;GAAE;GAAmB;GAAS;GAAU,EACxC,MACD;AACD,SAAO"}
@@ -6,7 +6,7 @@ const getContentNodeByKeyPath = (dictionaryContent, keyPath, fallbackLocale) =>
6
6
  for (const keyObj of keyPath) {
7
7
  if (fallbackLocale && currentValue?.nodeType === NodeTypes.TRANSLATION) currentValue = currentValue?.[NodeTypes.TRANSLATION]?.[fallbackLocale];
8
8
  if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) currentValue = currentValue?.[keyObj.key];
9
- if (keyObj.type === NodeTypes.TRANSLATION || keyObj.type === NodeTypes.CONDITION || keyObj.type === NodeTypes.ENUMERATION) currentValue = currentValue?.[keyObj.type]?.[keyObj.key];
9
+ if (keyObj.type === NodeTypes.TRANSLATION || keyObj.type === NodeTypes.CONDITION || keyObj.type === NodeTypes.ENUMERATION || keyObj.type === NodeTypes.PLURAL) currentValue = currentValue?.[keyObj.type]?.[keyObj.key];
10
10
  if (keyObj.type === NodeTypes.MARKDOWN || keyObj.type === NodeTypes.HTML || keyObj.type === NodeTypes.INSERTION || keyObj.type === NodeTypes.FILE) currentValue = currentValue?.[keyObj.type];
11
11
  }
12
12
  return currentValue;
@@ -1 +1 @@
1
- {"version":3,"file":"getContentNodeByKeyPath.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const getContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[],\n fallbackLocale?: LocalesValues\n): ContentNode => {\n let currentValue: any = structuredClone(dictionaryContent);\n\n for (const keyObj of keyPath) {\n // Auto-resolve translation nodes when fallbackLocale is provided\n if (fallbackLocale && currentValue?.nodeType === NodeTypes.TRANSLATION) {\n currentValue = currentValue?.[NodeTypes.TRANSLATION]?.[fallbackLocale];\n }\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n currentValue = currentValue?.[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.CONDITION ||\n keyObj.type === NodeTypes.ENUMERATION\n ) {\n currentValue = currentValue?.[keyObj.type]?.[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n currentValue = currentValue?.[keyObj.type];\n }\n }\n\n return currentValue as ContentNode;\n};\n"],"mappings":";;;AAKA,MAAa,2BACX,mBACA,SACA,mBACgB;CAChB,IAAI,eAAoB,gBAAgB,kBAAkB;AAE1D,MAAK,MAAM,UAAU,SAAS;AAE5B,MAAI,kBAAkB,cAAc,aAAa,UAAU,YACzD,gBAAe,eAAe,UAAU,eAAe;AAGzD,MAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,MAChE,gBAAe,eAAe,OAAO;AAGvC,MACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,aAC1B,OAAO,SAAS,UAAU,YAE1B,gBAAe,eAAe,OAAO,QAAQ,OAAO;AAGtD,MACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,aAC1B,OAAO,SAAS,UAAU,KAE1B,gBAAe,eAAe,OAAO;;AAIzC,QAAO"}
1
+ {"version":3,"file":"getContentNodeByKeyPath.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const getContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[],\n fallbackLocale?: LocalesValues\n): ContentNode => {\n let currentValue: any = structuredClone(dictionaryContent);\n\n for (const keyObj of keyPath) {\n // Auto-resolve translation nodes when fallbackLocale is provided\n if (fallbackLocale && currentValue?.nodeType === NodeTypes.TRANSLATION) {\n currentValue = currentValue?.[NodeTypes.TRANSLATION]?.[fallbackLocale];\n }\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n currentValue = currentValue?.[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.CONDITION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL\n ) {\n currentValue = currentValue?.[keyObj.type]?.[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n currentValue = currentValue?.[keyObj.type];\n }\n }\n\n return currentValue as ContentNode;\n};\n"],"mappings":";;;AAKA,MAAa,2BACX,mBACA,SACA,mBACgB;CAChB,IAAI,eAAoB,gBAAgB,kBAAkB;AAE1D,MAAK,MAAM,UAAU,SAAS;AAE5B,MAAI,kBAAkB,cAAc,aAAa,UAAU,YACzD,gBAAe,eAAe,UAAU,eAAe;AAGzD,MAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,MAChE,gBAAe,eAAe,OAAO;AAGvC,MACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,aAC1B,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,OAE1B,gBAAe,eAAe,OAAO,QAAQ,OAAO;AAGtD,MACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,aAC1B,OAAO,SAAS,UAAU,KAE1B,gBAAe,eAAe,OAAO;;AAIzC,QAAO"}
@@ -12,6 +12,13 @@ const getDefaultNode = (nodeType, locales, content) => {
12
12
  nodeType: NodeTypes.ENUMERATION,
13
13
  [NodeTypes.ENUMERATION]: { "1": clonedContent ?? "" }
14
14
  };
15
+ case NodeTypes.PLURAL: return {
16
+ nodeType: NodeTypes.PLURAL,
17
+ [NodeTypes.PLURAL]: {
18
+ one: clonedContent ?? "",
19
+ other: clonedContent ?? ""
20
+ }
21
+ };
15
22
  case NodeTypes.CONDITION: return {
16
23
  nodeType: NodeTypes.CONDITION,
17
24
  [NodeTypes.CONDITION]: {
@@ -1 +1 @@
1
- {"version":3,"file":"getDefaultNode.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getDefaultNode.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const getDefaultNode = (\n nodeType: NodeType,\n locales: LocalesValues[],\n content?: ContentNode\n): ContentNode => {\n const clonedContent = structuredClone(content);\n switch (nodeType) {\n case NodeTypes.TRANSLATION:\n return {\n nodeType: NodeTypes.TRANSLATION,\n [NodeTypes.TRANSLATION]: Object.assign(\n {},\n ...locales.map((locale) => ({\n [locale]: structuredClone(clonedContent) ?? '',\n }))\n ),\n } as ContentNode;\n\n case NodeTypes.ENUMERATION:\n return {\n nodeType: NodeTypes.ENUMERATION,\n [NodeTypes.ENUMERATION]: {\n '1': clonedContent ?? '',\n },\n } as ContentNode;\n\n case NodeTypes.CONDITION:\n return {\n nodeType: NodeTypes.CONDITION,\n [NodeTypes.CONDITION]: {\n true: clonedContent ?? '',\n false: clonedContent ?? '',\n },\n } as ContentNode;\n\n case NodeTypes.INSERTION:\n return {\n nodeType: NodeTypes.INSERTION,\n [NodeTypes.INSERTION]: {\n insertion: clonedContent ?? '',\n },\n } as unknown as ContentNode;\n\n case NodeTypes.NESTED:\n return {\n nodeType: NodeTypes.NESTED,\n [NodeTypes.NESTED]: {\n dictionaryKey: '',\n },\n } as ContentNode;\n\n case NodeTypes.MARKDOWN:\n return {\n nodeType: NodeTypes.MARKDOWN,\n [NodeTypes.MARKDOWN]: clonedContent ?? '',\n } as ContentNode;\n\n case NodeTypes.HTML:\n return {\n nodeType: NodeTypes.HTML,\n [NodeTypes.HTML]: clonedContent ?? '',\n customComponents: [],\n } as ContentNode;\n\n case NodeTypes.FILE:\n return {\n nodeType: NodeTypes.FILE,\n [NodeTypes.FILE]: clonedContent ?? '',\n } as ContentNode;\n\n case NodeTypes.OBJECT:\n return {\n newKey: clonedContent ?? '',\n } as unknown as ContentNode;\n\n case NodeTypes.ARRAY:\n return [clonedContent ?? ''] as unknown as ContentNode;\n\n case NodeTypes.TEXT:\n return clonedContent ?? '';\n\n case NodeTypes.NUMBER:\n return clonedContent ?? 0;\n\n case NodeTypes.BOOLEAN:\n return clonedContent ?? true;\n\n default:\n return clonedContent ?? '';\n }\n};\n"],"mappings":";;;AAMA,MAAa,kBACX,UACA,SACA,YACgB;CAChB,MAAM,gBAAgB,gBAAgB,QAAQ;AAC9C,SAAQ,UAAR;EACE,KAAK,UAAU,YACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,cAAc,OAAO,OAC9B,EAAE,EACF,GAAG,QAAQ,KAAK,YAAY,GACzB,SAAS,gBAAgB,cAAc,IAAI,IAC7C,EAAE,CACJ;GACF;EAEH,KAAK,UAAU,YACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,cAAc,EACvB,KAAK,iBAAiB,IACvB;GACF;EAEH,KAAK,UAAU,UACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,YAAY;IACrB,MAAM,iBAAiB;IACvB,OAAO,iBAAiB;IACzB;GACF;EAEH,KAAK,UAAU,UACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,YAAY,EACrB,WAAW,iBAAiB,IAC7B;GACF;EAEH,KAAK,UAAU,OACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,SAAS,EAClB,eAAe,IAChB;GACF;EAEH,KAAK,UAAU,SACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,WAAW,iBAAiB;GACxC;EAEH,KAAK,UAAU,KACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,OAAO,iBAAiB;GACnC,kBAAkB,EAAE;GACrB;EAEH,KAAK,UAAU,KACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,OAAO,iBAAiB;GACpC;EAEH,KAAK,UAAU,OACb,QAAO,EACL,QAAQ,iBAAiB,IAC1B;EAEH,KAAK,UAAU,MACb,QAAO,CAAC,iBAAiB,GAAG;EAE9B,KAAK,UAAU,KACb,QAAO,iBAAiB;EAE1B,KAAK,UAAU,OACb,QAAO,iBAAiB;EAE1B,KAAK,UAAU,QACb,QAAO,iBAAiB;EAE1B,QACE,QAAO,iBAAiB"}
1
+ {"version":3,"file":"getDefaultNode.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getDefaultNode.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const getDefaultNode = (\n nodeType: NodeType,\n locales: LocalesValues[],\n content?: ContentNode\n): ContentNode => {\n const clonedContent = structuredClone(content);\n switch (nodeType) {\n case NodeTypes.TRANSLATION:\n return {\n nodeType: NodeTypes.TRANSLATION,\n [NodeTypes.TRANSLATION]: Object.assign(\n {},\n ...locales.map((locale) => ({\n [locale]: structuredClone(clonedContent) ?? '',\n }))\n ),\n } as ContentNode;\n\n case NodeTypes.ENUMERATION:\n return {\n nodeType: NodeTypes.ENUMERATION,\n [NodeTypes.ENUMERATION]: {\n '1': clonedContent ?? '',\n },\n } as ContentNode;\n\n case NodeTypes.PLURAL:\n return {\n nodeType: NodeTypes.PLURAL,\n [NodeTypes.PLURAL]: {\n one: clonedContent ?? '',\n other: clonedContent ?? '',\n },\n } as ContentNode;\n\n case NodeTypes.CONDITION:\n return {\n nodeType: NodeTypes.CONDITION,\n [NodeTypes.CONDITION]: {\n true: clonedContent ?? '',\n false: clonedContent ?? '',\n },\n } as ContentNode;\n\n case NodeTypes.INSERTION:\n return {\n nodeType: NodeTypes.INSERTION,\n [NodeTypes.INSERTION]: {\n insertion: clonedContent ?? '',\n },\n } as unknown as ContentNode;\n\n case NodeTypes.NESTED:\n return {\n nodeType: NodeTypes.NESTED,\n [NodeTypes.NESTED]: {\n dictionaryKey: '',\n },\n } as ContentNode;\n\n case NodeTypes.MARKDOWN:\n return {\n nodeType: NodeTypes.MARKDOWN,\n [NodeTypes.MARKDOWN]: clonedContent ?? '',\n } as ContentNode;\n\n case NodeTypes.HTML:\n return {\n nodeType: NodeTypes.HTML,\n [NodeTypes.HTML]: clonedContent ?? '',\n customComponents: [],\n } as ContentNode;\n\n case NodeTypes.FILE:\n return {\n nodeType: NodeTypes.FILE,\n [NodeTypes.FILE]: clonedContent ?? '',\n } as ContentNode;\n\n case NodeTypes.OBJECT:\n return {\n newKey: clonedContent ?? '',\n } as unknown as ContentNode;\n\n case NodeTypes.ARRAY:\n return [clonedContent ?? ''] as unknown as ContentNode;\n\n case NodeTypes.TEXT:\n return clonedContent ?? '';\n\n case NodeTypes.NUMBER:\n return clonedContent ?? 0;\n\n case NodeTypes.BOOLEAN:\n return clonedContent ?? true;\n\n default:\n return clonedContent ?? '';\n }\n};\n"],"mappings":";;;AAMA,MAAa,kBACX,UACA,SACA,YACgB;CAChB,MAAM,gBAAgB,gBAAgB,QAAQ;AAC9C,SAAQ,UAAR;EACE,KAAK,UAAU,YACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,cAAc,OAAO,OAC9B,EAAE,EACF,GAAG,QAAQ,KAAK,YAAY,GACzB,SAAS,gBAAgB,cAAc,IAAI,IAC7C,EAAE,CACJ;GACF;EAEH,KAAK,UAAU,YACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,cAAc,EACvB,KAAK,iBAAiB,IACvB;GACF;EAEH,KAAK,UAAU,OACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,SAAS;IAClB,KAAK,iBAAiB;IACtB,OAAO,iBAAiB;IACzB;GACF;EAEH,KAAK,UAAU,UACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,YAAY;IACrB,MAAM,iBAAiB;IACvB,OAAO,iBAAiB;IACzB;GACF;EAEH,KAAK,UAAU,UACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,YAAY,EACrB,WAAW,iBAAiB,IAC7B;GACF;EAEH,KAAK,UAAU,OACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,SAAS,EAClB,eAAe,IAChB;GACF;EAEH,KAAK,UAAU,SACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,WAAW,iBAAiB;GACxC;EAEH,KAAK,UAAU,KACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,OAAO,iBAAiB;GACnC,kBAAkB,EAAE;GACrB;EAEH,KAAK,UAAU,KACb,QAAO;GACL,UAAU,UAAU;IACnB,UAAU,OAAO,iBAAiB;GACpC;EAEH,KAAK,UAAU,OACb,QAAO,EACL,QAAQ,iBAAiB,IAC1B;EAEH,KAAK,UAAU,MACb,QAAO,CAAC,iBAAiB,GAAG;EAE9B,KAAK,UAAU,KACb,QAAO,iBAAiB;EAE1B,KAAK,UAAU,OACb,QAAO,iBAAiB;EAE1B,KAAK,UAAU,QACb,QAAO,iBAAiB;EAE1B,QACE,QAAO,iBAAiB"}
@@ -8,7 +8,7 @@ const getEmptyNode = (section) => {
8
8
  if (typeof section?.nodeType === "string") {
9
9
  const typedNode = section;
10
10
  const content = typedNode[typedNode.nodeType];
11
- if (typedNode.nodeType === NodeTypes.TRANSLATION || typedNode.nodeType === NodeTypes.ENUMERATION || typedNode.nodeType === NodeTypes.CONDITION || typedNode.nodeType === NodeTypes.INSERTION || typedNode.nodeType === NodeTypes.HTML) return getEmptyNode(content);
11
+ if (typedNode.nodeType === NodeTypes.TRANSLATION || typedNode.nodeType === NodeTypes.ENUMERATION || typedNode.nodeType === NodeTypes.PLURAL || typedNode.nodeType === NodeTypes.CONDITION || typedNode.nodeType === NodeTypes.INSERTION || typedNode.nodeType === NodeTypes.HTML) return getEmptyNode(content);
12
12
  if (typedNode.nodeType === NodeTypes.NESTED) return "dictionary-key";
13
13
  if (typedNode.nodeType === NodeTypes.FILE) return "file/path";
14
14
  if (typedNode.nodeType === NodeTypes.MARKDOWN) return getEmptyNode(typedNode);
@@ -1 +1 @@
1
- {"version":3,"file":"getEmptyNode.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getEmptyNode.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const getEmptyNode = (section: ContentNode): ContentNode => {\n if (typeof section === 'string') {\n return '';\n }\n if (typeof section === 'number') {\n return 0;\n }\n if (typeof section === 'boolean') {\n return true;\n }\n if (typeof (section as TypedNode)?.nodeType === 'string') {\n const typedNode = section as TypedNode;\n const content =\n typedNode[typedNode.nodeType as unknown as keyof typeof typedNode];\n\n if (\n typedNode.nodeType === NodeTypes.TRANSLATION ||\n typedNode.nodeType === NodeTypes.ENUMERATION ||\n typedNode.nodeType === NodeTypes.CONDITION ||\n typedNode.nodeType === NodeTypes.INSERTION ||\n typedNode.nodeType === NodeTypes.HTML\n ) {\n return getEmptyNode(content as ContentNode);\n }\n\n if (typedNode.nodeType === NodeTypes.NESTED) {\n return 'dictionary-key';\n }\n\n if (typedNode.nodeType === NodeTypes.FILE) {\n return 'file/path';\n }\n\n if (typedNode.nodeType === NodeTypes.MARKDOWN) {\n return getEmptyNode(typedNode);\n }\n\n return content;\n }\n\n if (!section || typeof section !== 'object') {\n return section;\n }\n\n if (Array.isArray(section)) {\n return (section as ContentNode[]).map(\n getEmptyNode\n ) as unknown as ContentNode;\n }\n\n const mappedSectionObject = Object.entries(section).map(([key, value]) => [\n key,\n getEmptyNode(value as ContentNode),\n ]);\n\n const mappedSectionArray = Object.fromEntries(mappedSectionObject);\n\n return mappedSectionArray;\n};\n"],"mappings":";;;AAIA,MAAa,gBAAgB,YAAsC;AACjE,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,UACrB,QAAO;AAET,KAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;AAEtB,MACE,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,KAEjC,QAAO,aAAa,QAAuB;AAG7C,MAAI,UAAU,aAAa,UAAU,OACnC,QAAO;AAGT,MAAI,UAAU,aAAa,UAAU,KACnC,QAAO;AAGT,MAAI,UAAU,aAAa,UAAU,SACnC,QAAO,aAAa,UAAU;AAGhC,SAAO;;AAGT,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;AAGT,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAQ,QAA0B,IAChC,aACD;CAGH,MAAM,sBAAsB,OAAO,QAAQ,QAAQ,CAAC,KAAK,CAAC,KAAK,WAAW,CACxE,KACA,aAAa,MAAqB,CACnC,CAAC;AAIF,QAF2B,OAAO,YAAY,oBAErB"}
1
+ {"version":3,"file":"getEmptyNode.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getEmptyNode.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const getEmptyNode = (section: ContentNode): ContentNode => {\n if (typeof section === 'string') {\n return '';\n }\n if (typeof section === 'number') {\n return 0;\n }\n if (typeof section === 'boolean') {\n return true;\n }\n if (typeof (section as TypedNode)?.nodeType === 'string') {\n const typedNode = section as TypedNode;\n const content =\n typedNode[typedNode.nodeType as unknown as keyof typeof typedNode];\n\n if (\n typedNode.nodeType === NodeTypes.TRANSLATION ||\n typedNode.nodeType === NodeTypes.ENUMERATION ||\n typedNode.nodeType === NodeTypes.PLURAL ||\n typedNode.nodeType === NodeTypes.CONDITION ||\n typedNode.nodeType === NodeTypes.INSERTION ||\n typedNode.nodeType === NodeTypes.HTML\n ) {\n return getEmptyNode(content as ContentNode);\n }\n\n if (typedNode.nodeType === NodeTypes.NESTED) {\n return 'dictionary-key';\n }\n\n if (typedNode.nodeType === NodeTypes.FILE) {\n return 'file/path';\n }\n\n if (typedNode.nodeType === NodeTypes.MARKDOWN) {\n return getEmptyNode(typedNode);\n }\n\n return content;\n }\n\n if (!section || typeof section !== 'object') {\n return section;\n }\n\n if (Array.isArray(section)) {\n return (section as ContentNode[]).map(\n getEmptyNode\n ) as unknown as ContentNode;\n }\n\n const mappedSectionObject = Object.entries(section).map(([key, value]) => [\n key,\n getEmptyNode(value as ContentNode),\n ]);\n\n const mappedSectionArray = Object.fromEntries(mappedSectionObject);\n\n return mappedSectionArray;\n};\n"],"mappings":";;;AAIA,MAAa,gBAAgB,YAAsC;AACjE,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,UACrB,QAAO;AAET,KAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;AAEtB,MACE,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,UACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,KAEjC,QAAO,aAAa,QAAuB;AAG7C,MAAI,UAAU,aAAa,UAAU,OACnC,QAAO;AAGT,MAAI,UAAU,aAAa,UAAU,KACnC,QAAO;AAGT,MAAI,UAAU,aAAa,UAAU,SACnC,QAAO,aAAa,UAAU;AAGhC,SAAO;;AAGT,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;AAGT,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAQ,QAA0B,IAChC,aACD;CAGH,MAAM,sBAAsB,OAAO,QAAQ,QAAQ,CAAC,KAAK,CAAC,KAAK,WAAW,CACxE,KACA,aAAa,MAAqB,CACnC,CAAC;AAIF,QAF2B,OAAO,YAAY,oBAErB"}
@@ -8,7 +8,7 @@ const getNodeChildren = (section) => {
8
8
  if (typeof section?.nodeType === "string") {
9
9
  const typedNode = section;
10
10
  const content = typedNode[typedNode.nodeType];
11
- if (typedNode.nodeType === NodeTypes.TRANSLATION || typedNode.nodeType === NodeTypes.ENUMERATION || typedNode.nodeType === NodeTypes.CONDITION || typedNode.nodeType === NodeTypes.INSERTION || typedNode.nodeType === NodeTypes.GENDER || typedNode.nodeType === NodeTypes.FILE || typedNode.nodeType === NodeTypes.MARKDOWN || typedNode.nodeType === NodeTypes.HTML) return content[Object.keys(content)[0]];
11
+ if (typedNode.nodeType === NodeTypes.TRANSLATION || typedNode.nodeType === NodeTypes.ENUMERATION || typedNode.nodeType === NodeTypes.PLURAL || typedNode.nodeType === NodeTypes.CONDITION || typedNode.nodeType === NodeTypes.INSERTION || typedNode.nodeType === NodeTypes.GENDER || typedNode.nodeType === NodeTypes.FILE || typedNode.nodeType === NodeTypes.MARKDOWN || typedNode.nodeType === NodeTypes.HTML) return content[Object.keys(content)[0]];
12
12
  if (typedNode.nodeType === NodeTypes.NESTED) return;
13
13
  return content;
14
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getNodeChildren.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getNodeChildren.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const getNodeChildren = (section: ContentNode): ContentNode => {\n if (typeof section === 'string') {\n return section;\n }\n if (typeof section === 'number') {\n return section;\n }\n if (typeof section === 'boolean') {\n return section;\n }\n if (typeof (section as TypedNode)?.nodeType === 'string') {\n const typedNode = section as TypedNode;\n const content =\n typedNode[typedNode.nodeType as unknown as keyof typeof typedNode];\n\n if (\n typedNode.nodeType === NodeTypes.TRANSLATION ||\n typedNode.nodeType === NodeTypes.ENUMERATION ||\n typedNode.nodeType === NodeTypes.CONDITION ||\n typedNode.nodeType === NodeTypes.INSERTION ||\n typedNode.nodeType === NodeTypes.GENDER ||\n typedNode.nodeType === NodeTypes.FILE ||\n typedNode.nodeType === NodeTypes.MARKDOWN ||\n typedNode.nodeType === NodeTypes.HTML\n ) {\n const firstKey = Object.keys(content)[0] as keyof typeof content;\n return content[firstKey] as ContentNode;\n }\n\n if (typedNode.nodeType === NodeTypes.NESTED) {\n return undefined;\n }\n\n return content;\n }\n\n if (!section || typeof section !== 'object') {\n return section;\n }\n\n if (Array.isArray(section)) {\n return (section as ContentNode[])[0];\n }\n\n return section;\n};\n"],"mappings":";;;AAIA,MAAa,mBAAmB,YAAsC;AACpE,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,UACrB,QAAO;AAET,KAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;AAEtB,MACE,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,UACjC,UAAU,aAAa,UAAU,QACjC,UAAU,aAAa,UAAU,YACjC,UAAU,aAAa,UAAU,KAGjC,QAAO,QADU,OAAO,KAAK,QAAQ,CAAC;AAIxC,MAAI,UAAU,aAAa,UAAU,OACnC;AAGF,SAAO;;AAGT,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;AAGT,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAQ,QAA0B;AAGpC,QAAO"}
1
+ {"version":3,"file":"getNodeChildren.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getNodeChildren.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const getNodeChildren = (section: ContentNode): ContentNode => {\n if (typeof section === 'string') {\n return section;\n }\n if (typeof section === 'number') {\n return section;\n }\n if (typeof section === 'boolean') {\n return section;\n }\n if (typeof (section as TypedNode)?.nodeType === 'string') {\n const typedNode = section as TypedNode;\n const content =\n typedNode[typedNode.nodeType as unknown as keyof typeof typedNode];\n\n if (\n typedNode.nodeType === NodeTypes.TRANSLATION ||\n typedNode.nodeType === NodeTypes.ENUMERATION ||\n typedNode.nodeType === NodeTypes.PLURAL ||\n typedNode.nodeType === NodeTypes.CONDITION ||\n typedNode.nodeType === NodeTypes.INSERTION ||\n typedNode.nodeType === NodeTypes.GENDER ||\n typedNode.nodeType === NodeTypes.FILE ||\n typedNode.nodeType === NodeTypes.MARKDOWN ||\n typedNode.nodeType === NodeTypes.HTML\n ) {\n const firstKey = Object.keys(content)[0] as keyof typeof content;\n return content[firstKey] as ContentNode;\n }\n\n if (typedNode.nodeType === NodeTypes.NESTED) {\n return undefined;\n }\n\n return content;\n }\n\n if (!section || typeof section !== 'object') {\n return section;\n }\n\n if (Array.isArray(section)) {\n return (section as ContentNode[])[0];\n }\n\n return section;\n};\n"],"mappings":";;;AAIA,MAAa,mBAAmB,YAAsC;AACpE,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,UACrB,QAAO;AAET,KAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;AAEtB,MACE,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,UACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,UACjC,UAAU,aAAa,UAAU,QACjC,UAAU,aAAa,UAAU,YACjC,UAAU,aAAa,UAAU,KAGjC,QAAO,QADU,OAAO,KAAK,QAAQ,CAAC;AAIxC,MAAI,UAAU,aAAa,UAAU,OACnC;AAGF,SAAO;;AAGT,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;AAGT,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAQ,QAA0B;AAGpC,QAAO"}
@@ -15,6 +15,7 @@ const isValidNodeType = (nodeType) => {
15
15
  return [
16
16
  NodeTypes.TRANSLATION,
17
17
  NodeTypes.ENUMERATION,
18
+ NodeTypes.PLURAL,
18
19
  NodeTypes.CONDITION,
19
20
  NodeTypes.INSERTION,
20
21
  NodeTypes.FILE,
@@ -1 +1 @@
1
- {"version":3,"file":"getNodeType.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getNodeType.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { isValidElement } from '../utils/isValidReactElement';\n\n/**\n * Type guard to check if content is a TypedNode\n */\nconst isTypedNode = (content: unknown): content is TypedNode => {\n return (\n typeof content === 'object' &&\n content !== null &&\n 'nodeType' in content &&\n typeof (content as TypedNode).nodeType === 'string'\n );\n};\n\n/**\n * Type guard to check if content is a valid NodeType\n */\nconst isValidNodeType = (nodeType: string): nodeType is NodeType => {\n return [\n NodeTypes.TRANSLATION,\n NodeTypes.ENUMERATION,\n NodeTypes.CONDITION,\n NodeTypes.INSERTION,\n NodeTypes.FILE,\n NodeTypes.OBJECT,\n NodeTypes.ARRAY,\n NodeTypes.NESTED,\n NodeTypes.REACT_NODE,\n NodeTypes.MARKDOWN,\n NodeTypes.HTML,\n NodeTypes.TEXT,\n NodeTypes.NUMBER,\n NodeTypes.BOOLEAN,\n NodeTypes.GENDER,\n NodeTypes.NULL,\n NodeTypes.UNKNOWN,\n ].includes(nodeType as NodeType);\n};\n\nexport const getNodeType = (content: ContentNode): NodeType => {\n if (typeof content === 'string') {\n return NodeTypes.TEXT;\n }\n\n if (isTypedNode(content)) {\n const nodeType = content.nodeType;\n if (isValidNodeType(nodeType)) {\n return nodeType;\n }\n // Fallback for unknown node types\n return NodeTypes.UNKNOWN;\n }\n\n if (Array.isArray(content)) {\n return NodeTypes.ARRAY;\n }\n\n if (isValidElement(content)) {\n return NodeTypes.REACT_NODE;\n }\n\n if (typeof content === 'number') {\n return NodeTypes.NUMBER;\n }\n\n if (typeof content === 'boolean') {\n return NodeTypes.BOOLEAN;\n }\n\n if (content && typeof content === 'object') {\n return NodeTypes.OBJECT;\n }\n\n if (content === null) {\n return NodeTypes.NULL;\n }\n\n return NodeTypes.UNKNOWN;\n};\n"],"mappings":";;;;;;;AASA,MAAM,eAAe,YAA2C;AAC9D,QACE,OAAO,YAAY,YACnB,YAAY,QACZ,cAAc,WACd,OAAQ,QAAsB,aAAa;;;;;AAO/C,MAAM,mBAAmB,aAA2C;AAClE,QAAO;EACL,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACX,CAAC,SAAS,SAAqB;;AAGlC,MAAa,eAAe,YAAmC;AAC7D,KAAI,OAAO,YAAY,SACrB,QAAO,UAAU;AAGnB,KAAI,YAAY,QAAQ,EAAE;EACxB,MAAM,WAAW,QAAQ;AACzB,MAAI,gBAAgB,SAAS,CAC3B,QAAO;AAGT,SAAO,UAAU;;AAGnB,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,UAAU;AAGnB,KAAI,eAAe,QAAQ,CACzB,QAAO,UAAU;AAGnB,KAAI,OAAO,YAAY,SACrB,QAAO,UAAU;AAGnB,KAAI,OAAO,YAAY,UACrB,QAAO,UAAU;AAGnB,KAAI,WAAW,OAAO,YAAY,SAChC,QAAO,UAAU;AAGnB,KAAI,YAAY,KACd,QAAO,UAAU;AAGnB,QAAO,UAAU"}
1
+ {"version":3,"file":"getNodeType.mjs","names":[],"sources":["../../../src/dictionaryManipulator/getNodeType.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { isValidElement } from '../utils/isValidReactElement';\n\n/**\n * Type guard to check if content is a TypedNode\n */\nconst isTypedNode = (content: unknown): content is TypedNode => {\n return (\n typeof content === 'object' &&\n content !== null &&\n 'nodeType' in content &&\n typeof (content as TypedNode).nodeType === 'string'\n );\n};\n\n/**\n * Type guard to check if content is a valid NodeType\n */\nconst isValidNodeType = (nodeType: string): nodeType is NodeType => {\n return [\n NodeTypes.TRANSLATION,\n NodeTypes.ENUMERATION,\n NodeTypes.PLURAL,\n NodeTypes.CONDITION,\n NodeTypes.INSERTION,\n NodeTypes.FILE,\n NodeTypes.OBJECT,\n NodeTypes.ARRAY,\n NodeTypes.NESTED,\n NodeTypes.REACT_NODE,\n NodeTypes.MARKDOWN,\n NodeTypes.HTML,\n NodeTypes.TEXT,\n NodeTypes.NUMBER,\n NodeTypes.BOOLEAN,\n NodeTypes.GENDER,\n NodeTypes.NULL,\n NodeTypes.UNKNOWN,\n ].includes(nodeType as NodeType);\n};\n\nexport const getNodeType = (content: ContentNode): NodeType => {\n if (typeof content === 'string') {\n return NodeTypes.TEXT;\n }\n\n if (isTypedNode(content)) {\n const nodeType = content.nodeType;\n if (isValidNodeType(nodeType)) {\n return nodeType;\n }\n // Fallback for unknown node types\n return NodeTypes.UNKNOWN;\n }\n\n if (Array.isArray(content)) {\n return NodeTypes.ARRAY;\n }\n\n if (isValidElement(content)) {\n return NodeTypes.REACT_NODE;\n }\n\n if (typeof content === 'number') {\n return NodeTypes.NUMBER;\n }\n\n if (typeof content === 'boolean') {\n return NodeTypes.BOOLEAN;\n }\n\n if (content && typeof content === 'object') {\n return NodeTypes.OBJECT;\n }\n\n if (content === null) {\n return NodeTypes.NULL;\n }\n\n return NodeTypes.UNKNOWN;\n};\n"],"mappings":";;;;;;;AASA,MAAM,eAAe,YAA2C;AAC9D,QACE,OAAO,YAAY,YACnB,YAAY,QACZ,cAAc,WACd,OAAQ,QAAsB,aAAa;;;;;AAO/C,MAAM,mBAAmB,aAA2C;AAClE,QAAO;EACL,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACX,CAAC,SAAS,SAAqB;;AAGlC,MAAa,eAAe,YAAmC;AAC7D,KAAI,OAAO,YAAY,SACrB,QAAO,UAAU;AAGnB,KAAI,YAAY,QAAQ,EAAE;EACxB,MAAM,WAAW,QAAQ;AACzB,MAAI,gBAAgB,SAAS,CAC3B,QAAO;AAGT,SAAO,UAAU;;AAGnB,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,UAAU;AAGnB,KAAI,eAAe,QAAQ,CACzB,QAAO,UAAU;AAGnB,KAAI,OAAO,YAAY,SACrB,QAAO,UAAU;AAGnB,KAAI,OAAO,YAAY,UACrB,QAAO,UAAU;AAGnB,KAAI,WAAW,OAAO,YAAY,SAChC,QAAO,UAAU;AAGnB,KAAI,YAAY,KACd,QAAO,UAAU;AAGnB,QAAO,UAAU"}
@@ -11,7 +11,7 @@ const removeContentNodeByKeyPath = (dictionaryContent, keyPath) => {
11
11
  lastKey = keyObj.key;
12
12
  currentValue = currentValue[keyObj.key];
13
13
  }
14
- if (keyObj.type === NodeTypes.TRANSLATION || keyObj.type === NodeTypes.ENUMERATION || keyObj.type === NodeTypes.CONDITION) {
14
+ if (keyObj.type === NodeTypes.TRANSLATION || keyObj.type === NodeTypes.ENUMERATION || keyObj.type === NodeTypes.PLURAL || keyObj.type === NodeTypes.CONDITION) {
15
15
  lastKey = keyObj.type;
16
16
  currentValue = currentValue[keyObj.type][keyObj.key];
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"removeContentNodeByKeyPath.mjs","names":[],"sources":["../../../src/dictionaryManipulator/removeContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const removeContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKey: string | number | null = null;\n\n for (const keyObj of keyPath) {\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKey = keyObj.key;\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.REACT_NODE ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type];\n }\n }\n\n if (parentValue && lastKey !== null) {\n if (Array.isArray(parentValue)) {\n parentValue.splice(lastKey as unknown as number, 1);\n } else {\n delete parentValue[lastKey];\n }\n }\n\n return dictionaryContent;\n};\n"],"mappings":";;;AAKA,MAAa,8BACX,mBACA,YACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,UAAkC;AAEtC,MAAK,MAAM,UAAU,SAAS;AAC5B,gBAAc;AAEd,MAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,OAAO;AACvE,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO;;AAGrC,MACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,WAC1B;AACA,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO,MAAM,OAAO;;AAGlD,MACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,cAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,aAC1B,OAAO,SAAS,UAAU,MAC1B;AACA,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO;;;AAIvC,KAAI,eAAe,YAAY,KAC7B,KAAI,MAAM,QAAQ,YAAY,CAC5B,aAAY,OAAO,SAA8B,EAAE;KAEnD,QAAO,YAAY;AAIvB,QAAO"}
1
+ {"version":3,"file":"removeContentNodeByKeyPath.mjs","names":[],"sources":["../../../src/dictionaryManipulator/removeContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const removeContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKey: string | number | null = null;\n\n for (const keyObj of keyPath) {\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKey = keyObj.key;\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.REACT_NODE ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type];\n }\n }\n\n if (parentValue && lastKey !== null) {\n if (Array.isArray(parentValue)) {\n parentValue.splice(lastKey as unknown as number, 1);\n } else {\n delete parentValue[lastKey];\n }\n }\n\n return dictionaryContent;\n};\n"],"mappings":";;;AAKA,MAAa,8BACX,mBACA,YACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,UAAkC;AAEtC,MAAK,MAAM,UAAU,SAAS;AAC5B,gBAAc;AAEd,MAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,OAAO;AACvE,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO;;AAGrC,MACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,UAC1B,OAAO,SAAS,UAAU,WAC1B;AACA,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO,MAAM,OAAO;;AAGlD,MACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,cAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,aAC1B,OAAO,SAAS,UAAU,MAC1B;AACA,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO;;;AAIvC,KAAI,eAAe,YAAY,KAC7B,KAAI,MAAM,QAAQ,YAAY,CAC5B,aAAY,OAAO,SAA8B,EAAE;KAEnD,QAAO,YAAY;AAIvB,QAAO"}
@@ -11,7 +11,7 @@ const renameContentNodeByKeyPath = (dictionaryContent, newKey, keyPath) => {
11
11
  lastKey = keyObj.key;
12
12
  currentValue = currentValue[keyObj.key];
13
13
  }
14
- if (keyObj.type === NodeTypes.TRANSLATION || keyObj.type === NodeTypes.ENUMERATION || keyObj.type === NodeTypes.CONDITION) {
14
+ if (keyObj.type === NodeTypes.TRANSLATION || keyObj.type === NodeTypes.ENUMERATION || keyObj.type === NodeTypes.PLURAL || keyObj.type === NodeTypes.CONDITION) {
15
15
  lastKey = keyObj.type;
16
16
  currentValue = currentValue[keyObj.type][keyObj.key];
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"renameContentNodeByKeyPath.mjs","names":[],"sources":["../../../src/dictionaryManipulator/renameContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const renameContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n newKey: KeyPath['key'],\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKey: string | number | null = null;\n\n for (const keyObj of keyPath) {\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKey = keyObj.key;\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.REACT_NODE ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type];\n }\n }\n\n // Assign the new value to the last key of the parent while preserving the order\n if (parentValue && lastKey !== null) {\n if (Array.isArray(parentValue)) {\n parentValue[lastKey as number] = currentValue;\n } else {\n const newParentValue: any = {};\n for (const key of Object.keys(parentValue)) {\n if (key === lastKey && typeof newKey !== 'undefined') {\n newParentValue[newKey] = currentValue;\n } else {\n newParentValue[key] = parentValue[key];\n }\n }\n // Replace the contents of parentValue with newParentValue\n Object.keys(parentValue).forEach((key) => {\n delete parentValue[key];\n });\n Object.assign(parentValue, newParentValue);\n }\n }\n\n return dictionaryContent;\n};\n"],"mappings":";;;AAKA,MAAa,8BACX,mBACA,QACA,YACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,UAAkC;AAEtC,MAAK,MAAM,UAAU,SAAS;AAC5B,gBAAc;AAEd,MAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,OAAO;AACvE,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO;;AAGrC,MACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,WAC1B;AACA,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO,MAAM,OAAO;;AAGlD,MACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,cAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,aAC1B,OAAO,SAAS,UAAU,MAC1B;AACA,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO;;;AAKvC,KAAI,eAAe,YAAY,KAC7B,KAAI,MAAM,QAAQ,YAAY,CAC5B,aAAY,WAAqB;MAC5B;EACL,MAAM,iBAAsB,EAAE;AAC9B,OAAK,MAAM,OAAO,OAAO,KAAK,YAAY,CACxC,KAAI,QAAQ,WAAW,OAAO,WAAW,YACvC,gBAAe,UAAU;MAEzB,gBAAe,OAAO,YAAY;AAItC,SAAO,KAAK,YAAY,CAAC,SAAS,QAAQ;AACxC,UAAO,YAAY;IACnB;AACF,SAAO,OAAO,aAAa,eAAe;;AAI9C,QAAO"}
1
+ {"version":3,"file":"renameContentNodeByKeyPath.mjs","names":[],"sources":["../../../src/dictionaryManipulator/renameContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const renameContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n newKey: KeyPath['key'],\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKey: string | number | null = null;\n\n for (const keyObj of keyPath) {\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKey = keyObj.key;\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.REACT_NODE ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type];\n }\n }\n\n // Assign the new value to the last key of the parent while preserving the order\n if (parentValue && lastKey !== null) {\n if (Array.isArray(parentValue)) {\n parentValue[lastKey as number] = currentValue;\n } else {\n const newParentValue: any = {};\n for (const key of Object.keys(parentValue)) {\n if (key === lastKey && typeof newKey !== 'undefined') {\n newParentValue[newKey] = currentValue;\n } else {\n newParentValue[key] = parentValue[key];\n }\n }\n // Replace the contents of parentValue with newParentValue\n Object.keys(parentValue).forEach((key) => {\n delete parentValue[key];\n });\n Object.assign(parentValue, newParentValue);\n }\n }\n\n return dictionaryContent;\n};\n"],"mappings":";;;AAKA,MAAa,8BACX,mBACA,QACA,YACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,UAAkC;AAEtC,MAAK,MAAM,UAAU,SAAS;AAC5B,gBAAc;AAEd,MAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,OAAO;AACvE,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO;;AAGrC,MACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,UAC1B,OAAO,SAAS,UAAU,WAC1B;AACA,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO,MAAM,OAAO;;AAGlD,MACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,cAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,aAC1B,OAAO,SAAS,UAAU,MAC1B;AACA,aAAU,OAAO;AACjB,kBAAe,aAAa,OAAO;;;AAKvC,KAAI,eAAe,YAAY,KAC7B,KAAI,MAAM,QAAQ,YAAY,CAC5B,aAAY,WAAqB;MAC5B;EACL,MAAM,iBAAsB,EAAE;AAC9B,OAAK,MAAM,OAAO,OAAO,KAAK,YAAY,CACxC,KAAI,QAAQ,WAAW,OAAO,WAAW,YACvC,gBAAe,UAAU;MAEzB,gBAAe,OAAO,YAAY;AAItC,SAAO,KAAK,YAAY,CAAC,SAAS,QAAQ;AACxC,UAAO,YAAY;IACnB;AACF,SAAO,OAAO,aAAa,eAAe;;AAI9C,QAAO"}
@@ -8,7 +8,7 @@ const updateNodeChildren = (section, newChildren) => {
8
8
  if (typeof section?.nodeType === "string") {
9
9
  const typedNode = section;
10
10
  const content = typedNode[typedNode.nodeType];
11
- if (typedNode.nodeType === NodeTypes.TRANSLATION || typedNode.nodeType === NodeTypes.ENUMERATION || typedNode.nodeType === NodeTypes.CONDITION) {
11
+ if (typedNode.nodeType === NodeTypes.TRANSLATION || typedNode.nodeType === NodeTypes.ENUMERATION || typedNode.nodeType === NodeTypes.PLURAL || typedNode.nodeType === NodeTypes.CONDITION) {
12
12
  const newContent = Object.entries(content).reduce((acc, [key]) => {
13
13
  acc[key] = newChildren;
14
14
  return acc;
@@ -1 +1 @@
1
- {"version":3,"file":"updateNodeChildren.mjs","names":[],"sources":["../../../src/dictionaryManipulator/updateNodeChildren.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const updateNodeChildren = <\n T extends ContentNode,\n U extends ContentNode,\n>(\n section: T,\n newChildren: U\n): ContentNode => {\n if (typeof section === 'string') {\n return newChildren;\n }\n if (typeof section === 'number') {\n return newChildren;\n }\n if (typeof section === 'boolean') {\n return newChildren;\n }\n if (typeof (section as TypedNode)?.nodeType === 'string') {\n const typedNode = section as TypedNode;\n const content =\n typedNode[typedNode.nodeType as unknown as keyof typeof typedNode];\n\n if (\n typedNode.nodeType === NodeTypes.TRANSLATION ||\n typedNode.nodeType === NodeTypes.ENUMERATION ||\n typedNode.nodeType === NodeTypes.CONDITION\n ) {\n const newContent = Object.entries(content).reduce(\n (acc, [key]) => {\n acc[key] = newChildren;\n return acc;\n },\n {} as Record<string, ContentNode>\n );\n\n return {\n ...typedNode,\n [typedNode.nodeType]: newContent,\n };\n }\n\n if (typedNode.nodeType === NodeTypes.NESTED) {\n return typedNode;\n }\n\n return {\n ...typedNode,\n [typedNode.nodeType]: newChildren,\n };\n }\n\n if (!section || typeof section !== 'object') {\n return newChildren;\n }\n\n if (Array.isArray(section)) {\n return section.map(() => newChildren) as unknown as ContentNode;\n }\n\n return Object.entries(\n section as unknown as Record<string, ContentNode>\n ).reduce(\n (acc, [key]) => ({\n ...acc,\n [key]: newChildren,\n }),\n {} as Record<string, ContentNode>\n ) as unknown as ContentNode;\n};\n"],"mappings":";;;AAIA,MAAa,sBAIX,SACA,gBACgB;AAChB,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,UACrB,QAAO;AAET,KAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;AAEtB,MACE,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,WACjC;GACA,MAAM,aAAa,OAAO,QAAQ,QAAQ,CAAC,QACxC,KAAK,CAAC,SAAS;AACd,QAAI,OAAO;AACX,WAAO;MAET,EAAE,CACH;AAED,UAAO;IACL,GAAG;KACF,UAAU,WAAW;IACvB;;AAGH,MAAI,UAAU,aAAa,UAAU,OACnC,QAAO;AAGT,SAAO;GACL,GAAG;IACF,UAAU,WAAW;GACvB;;AAGH,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;AAGT,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,QAAQ,UAAU,YAAY;AAGvC,QAAO,OAAO,QACZ,QACD,CAAC,QACC,KAAK,CAAC,UAAU;EACf,GAAG;GACF,MAAM;EACR,GACD,EAAE,CACH"}
1
+ {"version":3,"file":"updateNodeChildren.mjs","names":[],"sources":["../../../src/dictionaryManipulator/updateNodeChildren.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const updateNodeChildren = <\n T extends ContentNode,\n U extends ContentNode,\n>(\n section: T,\n newChildren: U\n): ContentNode => {\n if (typeof section === 'string') {\n return newChildren;\n }\n if (typeof section === 'number') {\n return newChildren;\n }\n if (typeof section === 'boolean') {\n return newChildren;\n }\n if (typeof (section as TypedNode)?.nodeType === 'string') {\n const typedNode = section as TypedNode;\n const content =\n typedNode[typedNode.nodeType as unknown as keyof typeof typedNode];\n\n if (\n typedNode.nodeType === NodeTypes.TRANSLATION ||\n typedNode.nodeType === NodeTypes.ENUMERATION ||\n typedNode.nodeType === NodeTypes.PLURAL ||\n typedNode.nodeType === NodeTypes.CONDITION\n ) {\n const newContent = Object.entries(content).reduce(\n (acc, [key]) => {\n acc[key] = newChildren;\n return acc;\n },\n {} as Record<string, ContentNode>\n );\n\n return {\n ...typedNode,\n [typedNode.nodeType]: newContent,\n };\n }\n\n if (typedNode.nodeType === NodeTypes.NESTED) {\n return typedNode;\n }\n\n return {\n ...typedNode,\n [typedNode.nodeType]: newChildren,\n };\n }\n\n if (!section || typeof section !== 'object') {\n return newChildren;\n }\n\n if (Array.isArray(section)) {\n return section.map(() => newChildren) as unknown as ContentNode;\n }\n\n return Object.entries(\n section as unknown as Record<string, ContentNode>\n ).reduce(\n (acc, [key]) => ({\n ...acc,\n [key]: newChildren,\n }),\n {} as Record<string, ContentNode>\n ) as unknown as ContentNode;\n};\n"],"mappings":";;;AAIA,MAAa,sBAIX,SACA,gBACgB;AAChB,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,SACrB,QAAO;AAET,KAAI,OAAO,YAAY,UACrB,QAAO;AAET,KAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;AAEtB,MACE,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,UACjC,UAAU,aAAa,UAAU,WACjC;GACA,MAAM,aAAa,OAAO,QAAQ,QAAQ,CAAC,QACxC,KAAK,CAAC,SAAS;AACd,QAAI,OAAO;AACX,WAAO;MAET,EAAE,CACH;AAED,UAAO;IACL,GAAG;KACF,UAAU,WAAW;IACvB;;AAGH,MAAI,UAAU,aAAa,UAAU,OACnC,QAAO;AAGT,SAAO;GACL,GAAG;IACF,UAAU,WAAW;GACvB;;AAGH,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;AAGT,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,QAAQ,UAAU,YAAY;AAGvC,QAAO,OAAO,QACZ,QACD,CAAC,QACC,KAAK,CAAC,UAAU;EACf,GAAG;GACF,MAAM;EACR,GACD,EAAE,CACH"}
@@ -4,8 +4,18 @@ import { findMatchingCondition, getEnumeration } from "./interpreter/getEnumerat
4
4
  import { getDictionary } from "./interpreter/getDictionary.mjs";
5
5
  import { getIntlayer } from "./interpreter/getIntlayer.mjs";
6
6
  import { getNesting } from "./interpreter/getNesting.mjs";
7
+ import { CachedIntl, bindIntl, getCachedIntl } from "./utils/intl.mjs";
8
+ import { compact } from "./formatters/compact.mjs";
9
+ import { currency } from "./formatters/currency.mjs";
10
+ import { date, presets } from "./formatters/date.mjs";
11
+ import { list } from "./formatters/list.mjs";
12
+ import { number } from "./formatters/number.mjs";
13
+ import { percentage } from "./formatters/percentage.mjs";
14
+ import { relativeTime } from "./formatters/relativeTime.mjs";
15
+ import { units } from "./formatters/units.mjs";
16
+ import { getPlural } from "./interpreter/getPlural.mjs";
7
17
  import { getTranslation } from "./interpreter/getTranslation.mjs";
8
- import { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, translationPlugin } from "./interpreter/getContent/plugins.mjs";
18
+ import { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, translationPlugin } from "./interpreter/getContent/plugins.mjs";
9
19
  import { getBasePlugins, getContent } from "./interpreter/getContent/getContent.mjs";
10
20
  import { getHTML } from "./interpreter/getHTML.mjs";
11
21
  import { splitInsertionTemplate } from "./interpreter/splitAndJoinInsertion.mjs";
@@ -23,6 +33,7 @@ import { getMarkdownMetadata } from "./transpiler/markdown/getMarkdownMetadata.m
23
33
  import { validateMarkdown } from "./transpiler/markdown/validateMarkdown.mjs";
24
34
  import { md as markdown } from "./transpiler/markdown/markdown.mjs";
25
35
  import { nest as nesting } from "./transpiler/nesting/nesting.mjs";
36
+ import { plural } from "./transpiler/plural/plural.mjs";
26
37
  import { t as translation } from "./transpiler/translation/translation.mjs";
27
38
  import { filterMissingTranslationsOnlyPlugin, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary } from "./deepTransformPlugins/getFilterMissingTranslationsContent.mjs";
28
39
  import { filterTranslationsOnlyPlugin, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary } from "./deepTransformPlugins/getFilterTranslationsOnlyContent.mjs";
@@ -46,15 +57,6 @@ import { normalizeDictionaries, normalizeDictionary } from "./dictionaryManipula
46
57
  import { removeContentNodeByKeyPath } from "./dictionaryManipulator/removeContentNodeByKeyPath.mjs";
47
58
  import { renameContentNodeByKeyPath } from "./dictionaryManipulator/renameContentNodeByKeyPath.mjs";
48
59
  import { updateNodeChildren } from "./dictionaryManipulator/updateNodeChildren.mjs";
49
- import { CachedIntl, bindIntl, getCachedIntl } from "./utils/intl.mjs";
50
- import { compact } from "./formatters/compact.mjs";
51
- import { currency } from "./formatters/currency.mjs";
52
- import { date, presets } from "./formatters/date.mjs";
53
- import { list } from "./formatters/list.mjs";
54
- import { number } from "./formatters/number.mjs";
55
- import { percentage } from "./formatters/percentage.mjs";
56
- import { relativeTime } from "./formatters/relativeTime.mjs";
57
- import { units } from "./formatters/units.mjs";
58
60
  import { checkIsURLAbsolute } from "./utils/checkIsURLAbsolute.mjs";
59
61
  import { getPathWithoutLocale } from "./localization/getPathWithoutLocale.mjs";
60
62
  import { getPrefix } from "./localization/getPrefix.mjs";
@@ -84,4 +86,4 @@ import { i18nextToIntlayerFormatter, intlayerToI18nextFormatter } from "./messag
84
86
  import { intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter } from "./messageFormat/vue-i18n.mjs";
85
87
  import { isSameKeyPath } from "./utils/isSameKeyPath.mjs";
86
88
 
87
- 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, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CUSTOM_COMPONENT_R, CachedIntl, CachedIntl as Intl, DO_NOT_PROCESS_HTML_ELEMENTS, DURATION_DELAY_TRIGGER, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, GFM_TASK_R, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTML_BLOCK_ELEMENT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_SELF_CLOSING_ELEMENT_R, HTML_TAGS, INLINE_SKIP_R, INTERPOLATION_R, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LIST_LOOKBEHIND_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, Priority, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, RuleType, 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_PLAIN_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_ELEMENTS, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getHTML, getHTMLTextDir, getInsertionValues, getInternalPath, getIntlayer, getLocale, getLocaleFromPath, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPrefix, getReplacedValuesContent, getRewritePath, getRewriteRules, getSplittedContent, getSplittedDictionaryContent, getTranslation, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToVueI18nFormatter, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseInline, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseYaml, parserFor, percentage, presets, qualifies, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderNothing, sanitizer, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, translation as t, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter };
89
+ 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, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CUSTOM_COMPONENT_R, CachedIntl, CachedIntl as Intl, DO_NOT_PROCESS_HTML_ELEMENTS, DURATION_DELAY_TRIGGER, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, GFM_TASK_R, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTML_BLOCK_ELEMENT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_SELF_CLOSING_ELEMENT_R, HTML_TAGS, INLINE_SKIP_R, INTERPOLATION_R, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LIST_LOOKBEHIND_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, Priority, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, RuleType, 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_PLAIN_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_ELEMENTS, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getHTML, getHTMLTextDir, getInsertionValues, getInternalPath, getIntlayer, getLocale, getLocaleFromPath, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPlural, getPrefix, getReplacedValuesContent, getRewritePath, getRewriteRules, getSplittedContent, getSplittedDictionaryContent, getTranslation, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToVueI18nFormatter, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseInline, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseYaml, parserFor, percentage, plural, pluralPlugin, presets, qualifies, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderNothing, sanitizer, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, translation as t, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter };
@@ -1,5 +1,5 @@
1
1
  import { deepTransformNode } from "./deepTransform.mjs";
2
- import { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, translationPlugin } from "./plugins.mjs";
2
+ import { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, 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, translationPlugin };
5
+ export { conditionPlugin, deepTransformNode, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, getBasePlugins, getContent, insertionPlugin, nestedPlugin, pluralPlugin, translationPlugin };
@@ -3,6 +3,7 @@ import { getEnumeration } from "../getEnumeration.mjs";
3
3
  import { getGender } from "../getGender.mjs";
4
4
  import { getInsertion } from "../getInsertion.mjs";
5
5
  import { getNesting } from "../getNesting.mjs";
6
+ import { getPlural } from "../getPlural.mjs";
6
7
  import { getTranslation } from "../getTranslation.mjs";
7
8
  import * as NodeTypes from "@intlayer/types/nodeType";
8
9
 
@@ -63,6 +64,59 @@ const enumerationPlugin = process.env["INTLAYER_NODE_TYPE_ENUMERATION"] === "fal
63
64
  };
64
65
  }
65
66
  };
67
+ /**
68
+ * Plural plugin. Replaces node with a function that takes a count (or
69
+ * `{ count, ...values }`) => string, picking the matching CLDR plural form
70
+ * for the active locale and interpolating `{{count}}` (and other values).
71
+ */
72
+ const pluralPlugin = (locale) => process.env["INTLAYER_NODE_TYPE_PLURAL"] === "false" ? fallbackPlugin : {
73
+ id: "plural-plugin",
74
+ canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.PLURAL,
75
+ transform: (node, props, deepTransformNode) => {
76
+ const original = node[NodeTypes.PLURAL];
77
+ const result = {};
78
+ /** String plugin for plural. Replaces string node with a component that renders the insertion. */
79
+ const pluralStringPlugin = {
80
+ id: "plural-string-plugin",
81
+ canHandle: (node) => typeof node === "string",
82
+ transform: (node, subProps, deepTransformNode) => {
83
+ const transformedResult = deepTransformNode(node, {
84
+ ...subProps,
85
+ children: node,
86
+ plugins: [...(props.plugins ?? []).filter((plugin) => plugin.id !== "intlayer-node-plugin")]
87
+ });
88
+ return (values) => {
89
+ const children = getInsertion(transformedResult, values);
90
+ return deepTransformNode(children, {
91
+ ...subProps,
92
+ plugins: props.plugins,
93
+ children
94
+ });
95
+ };
96
+ }
97
+ };
98
+ for (const key in original) {
99
+ const child = original[key];
100
+ result[key] = deepTransformNode(child, {
101
+ ...props,
102
+ children: child,
103
+ keyPath: [...props.keyPath, {
104
+ type: NodeTypes.PLURAL,
105
+ key
106
+ }],
107
+ plugins: [pluralStringPlugin, ...props.plugins ?? []]
108
+ });
109
+ }
110
+ const effectiveLocale = String(locale ?? props.locale ?? "en");
111
+ return (arg) => {
112
+ const count = typeof arg === "number" ? arg : arg.count;
113
+ const values = typeof arg === "object" ? arg : { count };
114
+ const subResult = getPlural(result, count, effectiveLocale);
115
+ if (typeof subResult === "function") return subResult(values);
116
+ return subResult;
117
+ };
118
+ }
119
+ };
66
120
  /** Condition plugin. Replaces node with a function that takes boolean => string. */
67
121
  const conditionPlugin = process.env["INTLAYER_NODE_TYPE_CONDITION"] === "false" ? fallbackPlugin : {
68
122
  id: "condition-plugin",
@@ -164,5 +218,5 @@ const filePlugin = process.env["INTLAYER_NODE_TYPE_FILE"] === "false" ? fallback
164
218
  };
165
219
 
166
220
  //#endregion
167
- export { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, translationPlugin };
221
+ export { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, translationPlugin };
168
222
  //# sourceMappingURL=plugins.mjs.map