@intlayer/core 8.9.8 → 8.10.0-canary.1

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 (103) hide show
  1. package/README.md +14 -0
  2. package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs +1 -1
  3. package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs.map +1 -1
  4. package/dist/cjs/dictionaryManipulator/getEmptyNode.cjs +1 -1
  5. package/dist/cjs/dictionaryManipulator/getEmptyNode.cjs.map +1 -1
  6. package/dist/cjs/dictionaryManipulator/getNodeChildren.cjs +2 -1
  7. package/dist/cjs/dictionaryManipulator/getNodeChildren.cjs.map +1 -1
  8. package/dist/cjs/index.cjs +3 -1
  9. package/dist/cjs/interpreter/getIntlayer.cjs +10 -19
  10. package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
  11. package/dist/cjs/transpiler/file/file.cjs +2 -3
  12. package/dist/cjs/transpiler/file/file.cjs.map +1 -1
  13. package/dist/cjs/transpiler/html/index.cjs +1 -1
  14. package/dist/cjs/transpiler/html/validateHTML.cjs +3 -3
  15. package/dist/cjs/transpiler/html/validateHTML.cjs.map +1 -1
  16. package/dist/cjs/transpiler/index.cjs +1 -1
  17. package/dist/cjs/utils/index.cjs +3 -1
  18. package/dist/cjs/utils/stringifyYaml.cjs +59 -0
  19. package/dist/cjs/utils/stringifyYaml.cjs.map +1 -0
  20. package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs +1 -1
  21. package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs.map +1 -1
  22. package/dist/esm/dictionaryManipulator/getEmptyNode.mjs +1 -1
  23. package/dist/esm/dictionaryManipulator/getEmptyNode.mjs.map +1 -1
  24. package/dist/esm/dictionaryManipulator/getNodeChildren.mjs +2 -1
  25. package/dist/esm/dictionaryManipulator/getNodeChildren.mjs.map +1 -1
  26. package/dist/esm/index.mjs +3 -2
  27. package/dist/esm/interpreter/getIntlayer.mjs +10 -18
  28. package/dist/esm/interpreter/getIntlayer.mjs.map +1 -1
  29. package/dist/esm/transpiler/file/file.mjs +2 -3
  30. package/dist/esm/transpiler/file/file.mjs.map +1 -1
  31. package/dist/esm/transpiler/html/index.mjs +2 -2
  32. package/dist/esm/transpiler/html/validateHTML.mjs +3 -3
  33. package/dist/esm/transpiler/html/validateHTML.mjs.map +1 -1
  34. package/dist/esm/transpiler/index.mjs +2 -2
  35. package/dist/esm/utils/index.mjs +2 -1
  36. package/dist/esm/utils/stringifyYaml.mjs +57 -0
  37. package/dist/esm/utils/stringifyYaml.mjs.map +1 -0
  38. package/dist/types/@intlayer/core/dist/types/formatters/compact.d.ts +1 -0
  39. package/dist/types/@intlayer/core/dist/types/formatters/currency.d.ts +1 -0
  40. package/dist/types/@intlayer/core/dist/types/formatters/date.d.ts +1 -0
  41. package/dist/types/@intlayer/core/dist/types/formatters/index.d.ts +1 -0
  42. package/dist/types/@intlayer/core/dist/types/formatters/list.d.ts +1 -0
  43. package/dist/types/@intlayer/core/dist/types/formatters/number.d.ts +1 -0
  44. package/dist/types/@intlayer/core/dist/types/formatters/percentage.d.ts +1 -0
  45. package/dist/types/@intlayer/core/dist/types/formatters/relativeTime.d.ts +1 -0
  46. package/dist/types/@intlayer/core/dist/types/formatters/units.d.ts +1 -0
  47. package/dist/types/@intlayer/core/dist/types/interpreter/getCondition.d.ts +1 -0
  48. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/deepTransform.d.ts +1 -0
  49. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/getContent.d.ts +2 -0
  50. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/plugins.d.ts +4 -0
  51. package/dist/types/@intlayer/core/dist/types/interpreter/getDictionary.d.ts +2 -0
  52. package/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
  53. package/dist/types/@intlayer/core/dist/types/interpreter/getIntlayer.d.ts +1 -0
  54. package/dist/types/@intlayer/core/dist/types/interpreter/getNesting.d.ts +2 -0
  55. package/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
  56. package/dist/types/@intlayer/core/dist/types/interpreter/getTranslation.d.ts +1 -0
  57. package/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +1 -0
  58. package/dist/types/@intlayer/core/dist/types/localization/generateSitemap.d.ts +2 -0
  59. package/dist/types/@intlayer/core/dist/types/localization/getBrowserLocale.d.ts +1 -0
  60. package/dist/types/@intlayer/core/dist/types/localization/getHTMLTextDir.d.ts +1 -0
  61. package/dist/types/@intlayer/core/dist/types/localization/getLocale.d.ts +1 -0
  62. package/dist/types/@intlayer/core/dist/types/localization/getLocaleFromPath.d.ts +1 -0
  63. package/dist/types/@intlayer/core/dist/types/localization/getLocaleLang.d.ts +1 -0
  64. package/dist/types/@intlayer/core/dist/types/localization/getLocaleName.d.ts +1 -0
  65. package/dist/types/@intlayer/core/dist/types/localization/getLocalizedUrl.d.ts +1 -0
  66. package/dist/types/@intlayer/core/dist/types/localization/getMultilingualUrls.d.ts +1 -0
  67. package/dist/types/@intlayer/core/dist/types/localization/getPathWithoutLocale.d.ts +1 -0
  68. package/dist/types/@intlayer/core/dist/types/localization/getPrefix.d.ts +3 -0
  69. package/dist/types/@intlayer/core/dist/types/localization/index.d.ts +1 -0
  70. package/dist/types/@intlayer/core/dist/types/localization/localeDetector.d.ts +1 -0
  71. package/dist/types/@intlayer/core/dist/types/localization/localeMapper.d.ts +2 -0
  72. package/dist/types/@intlayer/core/dist/types/localization/localeResolver.d.ts +2 -0
  73. package/dist/types/@intlayer/core/dist/types/localization/rewriteUtils.d.ts +3 -0
  74. package/dist/types/@intlayer/core/dist/types/localization/validatePrefix.d.ts +1 -0
  75. package/dist/types/@intlayer/core/dist/types/markdown/index.d.ts +1 -0
  76. package/dist/types/@intlayer/core/dist/types/transpiler/condition/condition.d.ts +1 -0
  77. package/dist/types/@intlayer/core/dist/types/transpiler/enumeration/enumeration.d.ts +1 -0
  78. package/dist/types/@intlayer/core/dist/types/transpiler/file/file.d.ts +1 -0
  79. package/dist/types/@intlayer/core/dist/types/transpiler/gender/gender.d.ts +1 -0
  80. package/dist/types/@intlayer/core/dist/types/transpiler/html/html.d.ts +1 -0
  81. package/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +1 -0
  82. package/dist/types/@intlayer/core/dist/types/transpiler/insertion/insertion.d.ts +1 -0
  83. package/dist/types/@intlayer/core/dist/types/transpiler/markdown/markdown.d.ts +1 -0
  84. package/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +2 -0
  85. package/dist/types/@intlayer/core/dist/types/transpiler/plural/plural.d.ts +1 -0
  86. package/dist/types/@intlayer/core/dist/types/transpiler/translation/translation.d.ts +2 -0
  87. package/dist/types/@intlayer/core/dist/types/utils/index.d.ts +1 -0
  88. package/dist/types/@intlayer/core/dist/types/utils/intl.d.ts +1 -0
  89. package/dist/types/@intlayer/core/dist/types/utils/isSameKeyPath.d.ts +1 -0
  90. package/dist/types/@intlayer/core/dist/types/utils/localeStorage.d.ts +2 -0
  91. package/dist/types/dictionaryManipulator/getNodeChildren.d.ts.map +1 -1
  92. package/dist/types/index.d.ts +3 -2
  93. package/dist/types/interpreter/getIntlayer.d.ts.map +1 -1
  94. package/dist/types/intlayer/dist/types/index.d.ts +3 -0
  95. package/dist/types/transpiler/file/file.d.ts.map +1 -1
  96. package/dist/types/transpiler/html/index.d.ts +2 -2
  97. package/dist/types/transpiler/html/validateHTML.d.ts +2 -2
  98. package/dist/types/transpiler/html/validateHTML.d.ts.map +1 -1
  99. package/dist/types/transpiler/index.d.ts +2 -2
  100. package/dist/types/utils/index.d.ts +2 -1
  101. package/dist/types/utils/stringifyYaml.d.ts +5 -0
  102. package/dist/types/utils/stringifyYaml.d.ts.map +1 -0
  103. package/package.json +7 -7
package/README.md CHANGED
@@ -67,6 +67,7 @@ With **per-locale content files**, **TypeScript autocompletion**, **tree-shakabl
67
67
  | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md) |
68
68
  | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension) |
69
69
  | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) |
70
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark) |
70
71
 
71
72
  ---
72
73
 
@@ -249,6 +250,19 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
249
250
  </ul>
250
251
  </details>
251
252
 
253
+ ## Multilingual content management system
254
+
255
+ More than an i18n library, Intlayer is a complete **multilingual content management system**. A full CMS is available for free at [app.intlayer.org](https://app.intlayer.org).
256
+
257
+ Intlayer connects **developers**, **copywriters**, and **AI agents** in one workflow for creating and maintaining multilingual websites effortlessly.Intlayer replaces the following stack in a single solution:
258
+
259
+ - i18n solutions (e.g. `i18next`, `next-intl`, `vue-i18n`)
260
+ - TMSs (Translation Management Systems) (e.g. Crowdin, Phrase, Lokalise)
261
+ - Feature flags
262
+ - Headless CMSs (e.g. Contentful, Strapi, Sanity)
263
+
264
+ ![CMS Preview](https://github.com/aymericzip/intlayer/blob/main/docs/assets/CMS.png?raw=true)
265
+
252
266
  ## 🌐 Readme in other languages
253
267
 
254
268
  <p align="center">
@@ -32,7 +32,7 @@ const editDictionaryByKeyPath = (dictionaryContent, keyPath, newValue) => {
32
32
  }
33
33
  if (keyObj.type === _intlayer_types_nodeType.MARKDOWN || keyObj.type === _intlayer_types_nodeType.HTML || keyObj.type === _intlayer_types_nodeType.INSERTION) {
34
34
  lastKeys = [keyObj.type];
35
- if (!currentValue[keyObj.type] || typeof currentValue[keyObj.type] !== "object") currentValue[keyObj.type] = "";
35
+ if (currentValue[keyObj.type] == null) currentValue[keyObj.type] = "";
36
36
  currentValue = currentValue[keyObj.type];
37
37
  }
38
38
  if (keyObj.type === _intlayer_types_nodeType.FILE) {
@@ -1 +1 @@
1
- {"version":3,"file":"editDictionaryByKeyPath.cjs","names":["NodeTypes"],"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,CAAC;CAE/B,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,IAAI;EACF,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;GACvB,cAAc;GAEd,IAAI,OAAO,SAASA,yBAAU,UAAU,OAAO,SAASA,yBAAU,OAAO;IACvE,WAAW,CAAC,OAAO,GAAG;IAEtB,IACE,CAAC,aAAa,OAAO,QACrB,OAAO,aAAa,OAAO,SAAS,UAEpC,aAAa,OAAO,OAAO,CAAC;IAE9B,eAAe,aAAa,OAAO;GACrC;GAEA,IACE,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,QAC1B;IACA,WAAW,CAAC,OAAO,MAAM,OAAO,GAAG;IAEnC,IACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,UAErC,aAAa,OAAO,QAAQ,CAAC;IAG/B,IACE,CAAC,aAAa,OAAO,MAAM,OAAO,QAClC,OAAO,aAAa,OAAO,MAAM,OAAO,SAAS,UAEjD,aAAa,OAAO,MAAM,OAAO,OAAO,CAAC;IAE3C,eAAe,aAAa,OAAO,MAAM,OAAO;GAClD;GAEA,IACE,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,UAC1B,OAAO,SAASA,yBAAU,WAQ1B;QACE,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,QAC1B;KACA,WAAW,CAAC,OAAO,MAAM,OAAO,GAAG;KACnC,eAAe,aAAa,OAAO,MAAM,OAAO;IAClD;;GAGF,IACE,OAAO,SAASA,yBAAU,YAC1B,OAAO,SAASA,yBAAU,QAC1B,OAAO,SAASA,yBAAU,WAC1B;IACA,WAAW,CAAC,OAAO,IAAI;IAEvB,IACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,UAErC,aAAa,OAAO,QAAQ;IAE9B,eAAe,aAAa,OAAO;GACrC;GAEA,IAAI,OAAO,SAASA,yBAAU,MAAM;IAClC,WAAW,CAAC,SAAS;IACrB,eAAe,aAAa;GAC9B;GAIA,IAAI,MAAM,QAAQ,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;IAClE,IAAI,SAAS;IAGb,KAAK,MAAM,OAAO,SAAS,MAAM,GAAG,EAAE,GACpC,SAAS,OAAO;IAGlB,MAAM,WAAW,SAAS,SAAS,SAAS;IAE5C,IAAI,OAAO,aAAa,aAGtB,IAAI,MAAM,QAAQ,MAAM,GAAG;KACzB,MAAM,QAAQ,OAAO,QAAQ;KAE7B,IAAI,CAAC,OAAO,MAAM,KAAK,KAAK,SAAS,KAAK,QAAQ,OAAO,QACvD,OAAO,OAAO,OAAO,CAAC;IAE1B,OACE,OAAO,OAAO;SAGhB,OAAO,YAAY;GAEvB;EACF;EAEA,OAAO;CACT,SAAS,OAAO;EACd,QAAQ,MACN,sCACA;GAAE;GAAmB;GAAS;EAAS,GACvC,KACF;EACA,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"editDictionaryByKeyPath.cjs","names":["NodeTypes"],"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 (currentValue[keyObj.type] == null) {\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,CAAC;CAE/B,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,IAAI;EACF,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;GACvB,cAAc;GAEd,IAAI,OAAO,SAASA,yBAAU,UAAU,OAAO,SAASA,yBAAU,OAAO;IACvE,WAAW,CAAC,OAAO,GAAG;IAEtB,IACE,CAAC,aAAa,OAAO,QACrB,OAAO,aAAa,OAAO,SAAS,UAEpC,aAAa,OAAO,OAAO,CAAC;IAE9B,eAAe,aAAa,OAAO;GACrC;GAEA,IACE,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,QAC1B;IACA,WAAW,CAAC,OAAO,MAAM,OAAO,GAAG;IAEnC,IACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,UAErC,aAAa,OAAO,QAAQ,CAAC;IAG/B,IACE,CAAC,aAAa,OAAO,MAAM,OAAO,QAClC,OAAO,aAAa,OAAO,MAAM,OAAO,SAAS,UAEjD,aAAa,OAAO,MAAM,OAAO,OAAO,CAAC;IAE3C,eAAe,aAAa,OAAO,MAAM,OAAO;GAClD;GAEA,IACE,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,UAC1B,OAAO,SAASA,yBAAU,WAQ1B;QACE,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,QAC1B;KACA,WAAW,CAAC,OAAO,MAAM,OAAO,GAAG;KACnC,eAAe,aAAa,OAAO,MAAM,OAAO;IAClD;;GAGF,IACE,OAAO,SAASA,yBAAU,YAC1B,OAAO,SAASA,yBAAU,QAC1B,OAAO,SAASA,yBAAU,WAC1B;IACA,WAAW,CAAC,OAAO,IAAI;IAEvB,IAAI,aAAa,OAAO,SAAS,MAC/B,aAAa,OAAO,QAAQ;IAE9B,eAAe,aAAa,OAAO;GACrC;GAEA,IAAI,OAAO,SAASA,yBAAU,MAAM;IAClC,WAAW,CAAC,SAAS;IACrB,eAAe,aAAa;GAC9B;GAIA,IAAI,MAAM,QAAQ,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;IAClE,IAAI,SAAS;IAGb,KAAK,MAAM,OAAO,SAAS,MAAM,GAAG,EAAE,GACpC,SAAS,OAAO;IAGlB,MAAM,WAAW,SAAS,SAAS,SAAS;IAE5C,IAAI,OAAO,aAAa,aAGtB,IAAI,MAAM,QAAQ,MAAM,GAAG;KACzB,MAAM,QAAQ,OAAO,QAAQ;KAE7B,IAAI,CAAC,OAAO,MAAM,KAAK,KAAK,SAAS,KAAK,QAAQ,OAAO,QACvD,OAAO,OAAO,OAAO,CAAC;IAE1B,OACE,OAAO,OAAO;SAGhB,OAAO,YAAY;GAEvB;EACF;EAEA,OAAO;CACT,SAAS,OAAO;EACd,QAAQ,MACN,sCACA;GAAE;GAAmB;GAAS;EAAS,GACvC,KACF;EACA,OAAO;CACT;AACF"}
@@ -14,7 +14,7 @@ const getEmptyNode = (section) => {
14
14
  if (typedNode.nodeType === _intlayer_types_nodeType.TRANSLATION || typedNode.nodeType === _intlayer_types_nodeType.ENUMERATION || typedNode.nodeType === _intlayer_types_nodeType.PLURAL || typedNode.nodeType === _intlayer_types_nodeType.CONDITION || typedNode.nodeType === _intlayer_types_nodeType.INSERTION || typedNode.nodeType === _intlayer_types_nodeType.HTML) return getEmptyNode(content);
15
15
  if (typedNode.nodeType === _intlayer_types_nodeType.NESTED) return "dictionary-key";
16
16
  if (typedNode.nodeType === _intlayer_types_nodeType.FILE) return "file/path";
17
- if (typedNode.nodeType === _intlayer_types_nodeType.MARKDOWN) return getEmptyNode(typedNode);
17
+ if (typedNode.nodeType === _intlayer_types_nodeType.MARKDOWN) return getEmptyNode(content);
18
18
  return content;
19
19
  }
20
20
  if (!section || typeof section !== "object") return section;
@@ -1 +1 @@
1
- {"version":3,"file":"getEmptyNode.cjs","names":["NodeTypes"],"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;CACjE,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,UACjC,UAAU,aAAaA,yBAAU,aACjC,UAAU,aAAaA,yBAAU,aACjC,UAAU,aAAaA,yBAAU,MAEjC,OAAO,aAAa,OAAsB;EAG5C,IAAI,UAAU,aAAaA,yBAAU,QACnC,OAAO;EAGT,IAAI,UAAU,aAAaA,yBAAU,MACnC,OAAO;EAGT,IAAI,UAAU,aAAaA,yBAAU,UACnC,OAAO,aAAa,SAAS;EAG/B,OAAO;CACT;CAEA,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAQ,QAA0B,IAChC,YACF;CAGF,MAAM,sBAAsB,OAAO,QAAQ,OAAO,EAAE,KAAK,CAAC,KAAK,WAAW,CACxE,KACA,aAAa,KAAoB,CACnC,CAAC;CAID,OAF2B,OAAO,YAAY,mBAEtB;AAC1B"}
1
+ {"version":3,"file":"getEmptyNode.cjs","names":["NodeTypes"],"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(content as ContentNode);\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;CACjE,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,UACjC,UAAU,aAAaA,yBAAU,aACjC,UAAU,aAAaA,yBAAU,aACjC,UAAU,aAAaA,yBAAU,MAEjC,OAAO,aAAa,OAAsB;EAG5C,IAAI,UAAU,aAAaA,yBAAU,QACnC,OAAO;EAGT,IAAI,UAAU,aAAaA,yBAAU,MACnC,OAAO;EAGT,IAAI,UAAU,aAAaA,yBAAU,UACnC,OAAO,aAAa,OAAsB;EAG5C,OAAO;CACT;CAEA,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAQ,QAA0B,IAChC,YACF;CAGF,MAAM,sBAAsB,OAAO,QAAQ,OAAO,EAAE,KAAK,CAAC,KAAK,WAAW,CACxE,KACA,aAAa,KAAoB,CACnC,CAAC;CAID,OAF2B,OAAO,YAAY,mBAEtB;AAC1B"}
@@ -11,7 +11,8 @@ const getNodeChildren = (section) => {
11
11
  if (typeof section?.nodeType === "string") {
12
12
  const typedNode = section;
13
13
  const content = typedNode[typedNode.nodeType];
14
- if (typedNode.nodeType === _intlayer_types_nodeType.TRANSLATION || typedNode.nodeType === _intlayer_types_nodeType.ENUMERATION || typedNode.nodeType === _intlayer_types_nodeType.PLURAL || typedNode.nodeType === _intlayer_types_nodeType.CONDITION || typedNode.nodeType === _intlayer_types_nodeType.INSERTION || typedNode.nodeType === _intlayer_types_nodeType.GENDER || typedNode.nodeType === _intlayer_types_nodeType.FILE || typedNode.nodeType === _intlayer_types_nodeType.MARKDOWN || typedNode.nodeType === _intlayer_types_nodeType.HTML) return content[Object.keys(content)[0]];
14
+ if (typedNode.nodeType === _intlayer_types_nodeType.MARKDOWN || typedNode.nodeType === _intlayer_types_nodeType.HTML) return content;
15
+ if (typedNode.nodeType === _intlayer_types_nodeType.TRANSLATION || typedNode.nodeType === _intlayer_types_nodeType.ENUMERATION || typedNode.nodeType === _intlayer_types_nodeType.PLURAL || typedNode.nodeType === _intlayer_types_nodeType.CONDITION || typedNode.nodeType === _intlayer_types_nodeType.INSERTION || typedNode.nodeType === _intlayer_types_nodeType.GENDER || typedNode.nodeType === _intlayer_types_nodeType.FILE) return content[Object.keys(content)[0]];
15
16
  if (typedNode.nodeType === _intlayer_types_nodeType.NESTED) return;
16
17
  return content;
17
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getNodeChildren.cjs","names":["NodeTypes"],"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;CACpE,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,UACjC,UAAU,aAAaA,yBAAU,aACjC,UAAU,aAAaA,yBAAU,aACjC,UAAU,aAAaA,yBAAU,UACjC,UAAU,aAAaA,yBAAU,QACjC,UAAU,aAAaA,yBAAU,YACjC,UAAU,aAAaA,yBAAU,MAGjC,OAAO,QADU,OAAO,KAAK,OAAO,EAAE;EAIxC,IAAI,UAAU,aAAaA,yBAAU,QACnC;EAGF,OAAO;CACT;CAEA,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAQ,QAA0B;CAGpC,OAAO;AACT"}
1
+ {"version":3,"file":"getNodeChildren.cjs","names":["NodeTypes"],"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.MARKDOWN ||\n typedNode.nodeType === NodeTypes.HTML\n ) {\n return content as ContentNode;\n }\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 ) {\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;CACpE,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,UAAU,aAAaA,yBAAU,YACjC,UAAU,aAAaA,yBAAU,MAEjC,OAAO;EAGT,IACE,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,UACjC,UAAU,aAAaA,yBAAU,aACjC,UAAU,aAAaA,yBAAU,aACjC,UAAU,aAAaA,yBAAU,UACjC,UAAU,aAAaA,yBAAU,MAGjC,OAAO,QADU,OAAO,KAAK,OAAO,EAAE;EAIxC,IAAI,UAAU,aAAaA,yBAAU,QACnC;EAGF,OAAO;CACT;CAEA,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAQ,QAA0B;CAGpC,OAAO;AACT"}
@@ -87,6 +87,7 @@ const require_messageFormat_i18next = require('./messageFormat/i18next.cjs');
87
87
  const require_messageFormat_po = require('./messageFormat/po.cjs');
88
88
  const require_messageFormat_vue_i18n = require('./messageFormat/vue-i18n.cjs');
89
89
  const require_utils_isSameKeyPath = require('./utils/isSameKeyPath.cjs');
90
+ const require_utils_stringifyYaml = require('./utils/stringifyYaml.cjs');
90
91
 
91
92
  exports.ATTRIBUTES_TO_SANITIZE = require_markdown_constants.ATTRIBUTES_TO_SANITIZE;
92
93
  exports.ATTRIBUTE_TO_NODE_PROP_MAP = require_markdown_constants.ATTRIBUTE_TO_NODE_PROP_MAP;
@@ -167,7 +168,7 @@ exports.UNORDERED_LIST_ITEM_PREFIX = require_markdown_constants.UNORDERED_LIST_I
167
168
  exports.UNORDERED_LIST_ITEM_PREFIX_R = require_markdown_constants.UNORDERED_LIST_ITEM_PREFIX_R;
168
169
  exports.UNORDERED_LIST_ITEM_R = require_markdown_constants.UNORDERED_LIST_ITEM_R;
169
170
  exports.UNORDERED_LIST_R = require_markdown_constants.UNORDERED_LIST_R;
170
- exports.VOID_ELEMENTS = require_transpiler_html_validateHTML.VOID_ELEMENTS;
171
+ exports.VOID_HTML_ELEMENTS = require_transpiler_html_validateHTML.VOID_HTML_ELEMENTS;
171
172
  exports.allowInline = require_markdown_utils.allowInline;
172
173
  exports.anyScopeRegex = require_markdown_utils.anyScopeRegex;
173
174
  exports.attributeValueToNodePropValue = require_markdown_utils.attributeValueToNodePropValue;
@@ -318,6 +319,7 @@ exports.slugify = require_markdown_utils.slugify;
318
319
  exports.some = require_markdown_utils.some;
319
320
  exports.splitInsertionTemplate = require_interpreter_splitAndJoinInsertion.splitInsertionTemplate;
320
321
  exports.startsWith = require_markdown_utils.startsWith;
322
+ exports.stringifyYaml = require_utils_stringifyYaml.stringifyYaml;
321
323
  exports.t = require_transpiler_translation_translation.t;
322
324
  exports.translationPlugin = require_interpreter_getContent_plugins.translationPlugin;
323
325
  exports.trimEnd = require_markdown_utils.trimEnd;
@@ -11,33 +11,24 @@ let _intlayer_dictionaries_entry = require("@intlayer/dictionaries-entry");
11
11
  * stringified. This prevents the app from crashing on undefined access.
12
12
  */
13
13
  const createSafeFallback = (path = "") => {
14
- return new Proxy(() => path, {
15
- get: (_target, prop) => {
16
- if (prop === "toJSON" || prop === Symbol.toPrimitive || prop === "toString") return () => path;
17
- if (prop === "then") return;
18
- if (prop === Symbol.iterator) return function* () {
19
- yield path;
20
- };
21
- return createSafeFallback(path ? `${path}.${String(prop)}` : String(prop));
22
- },
23
- apply: () => {
24
- return path;
25
- }
26
- });
14
+ return new Proxy({}, { get: (_target, prop) => {
15
+ if (prop === "toJSON" || prop === Symbol.toPrimitive || prop === "toString" || prop === "valueOf") return () => path;
16
+ if (prop === "then") return;
17
+ if (prop === Symbol.iterator) return function* () {
18
+ yield path;
19
+ };
20
+ return createSafeFallback(path ? `${path}.${String(prop)}` : String(prop));
21
+ } });
27
22
  };
28
23
  const dictionaryCache = /* @__PURE__ */ new Map();
29
24
  const warnedMissingDictionaries = /* @__PURE__ */ new Set();
30
25
  const getIntlayer = (key, locale, plugins) => {
31
26
  const dictionary = (0, _intlayer_dictionaries_entry.getDictionaries)()[key];
32
- if (!dictionary) {
27
+ if (!dictionary && process.env.NODE_ENV === "development") {
33
28
  if (!warnedMissingDictionaries.has(key)) {
34
- (0, _intlayer_config_logger.getAppLogger)({ log: _intlayer_config_built.log })(`Dictionary ${(0, _intlayer_config_logger.colorizeKey)(key)} was not found. Using fallback proxy.`, {
35
- level: "warn",
36
- isVerbose: true
37
- });
29
+ (0, _intlayer_config_logger.getAppLogger)({ log: _intlayer_config_built.log })(typeof window === "undefined" ? `Dictionary ${(0, _intlayer_config_logger.colorizeKey)(key)} was not found. Using fallback proxy.` : `Dictionary ${key} was not found. Using fallback proxy.`, { level: "warn" });
38
30
  warnedMissingDictionaries.add(key);
39
31
  }
40
- if (process.env.NODE_ENV === "development") return createSafeFallback(key);
41
32
  return createSafeFallback(key);
42
33
  }
43
34
  const cacheKey = `${key}_${locale ?? "default"}_${plugins ? "custom_plugins" : "default_plugins"}`;
@@ -1 +1 @@
1
- {"version":3,"file":"getIntlayer.cjs","names":["getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryContent,\n DictionaryRegistryElement,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy(\n // Target is a function so it can be called if the dictionary expects a function\n () => path,\n {\n get: (_target, prop) => {\n // Handle common object methods to prevent infinite recursion or weird behavior\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n if (prop === Symbol.iterator) {\n return function* () {\n yield path;\n };\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n // If the code tries to execute the missing key as a function: t.title()\n apply: () => {\n return path;\n },\n }\n );\n};\n\nconst dictionaryCache = new Map<string, any>();\nconst warnedMissingDictionaries = new Set<string>();\n\nexport const getIntlayer = <\n T extends DictionaryKeys,\n L extends LocalesValues = DeclaredLocales,\n>(\n key: T,\n locale?: L,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryContent<T>,\n IInterpreterPluginState,\n L\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T] as DictionaryRegistryElement<T>;\n\n if (!dictionary) {\n if (!warnedMissingDictionaries.has(key as string)) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n `Dictionary ${colorizeKey(key as string)} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n isVerbose: true,\n }\n );\n warnedMissingDictionaries.add(key as string);\n }\n\n if (process.env.NODE_ENV === 'development') {\n // Return the Safe Proxy\n // We initialize it with the dictionary key name so the UI shows \"my-dictionary.someKey\"\n return createSafeFallback(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n const cacheKey = `${key}_${locale ?? 'default'}_${plugins ? 'custom_plugins' : 'default_plugins'}`;\n\n if (dictionaryCache.has(cacheKey)) {\n return dictionaryCache.get(cacheKey);\n }\n\n const result = getDictionary<DictionaryRegistryElement<T>, L>(\n dictionary,\n locale,\n plugins\n );\n\n dictionaryCache.set(cacheKey, result);\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAM,sBAAsB,OAAO,OAAY;CAC7C,OAAO,IAAI,YAEH,MACN;EACE,MAAM,SAAS,SAAS;GAEtB,IACE,SAAS,YACT,SAAS,OAAO,eAChB,SAAS,YAET,aAAa;GAEf,IAAI,SAAS,QACX;GAEF,IAAI,SAAS,OAAO,UAClB,OAAO,aAAa;IAClB,MAAM;GACR;GAKF,OAAO,mBADU,OAAO,GAAG,KAAK,GAAG,OAAO,IAAI,MAAM,OAAO,IAAI,CAC7B;EACpC;EAEA,aAAa;GACX,OAAO;EACT;CACF,CACF;AACF;AAEA,MAAM,kCAAkB,IAAI,IAAiB;AAC7C,MAAM,4CAA4B,IAAI,IAAY;AAElD,MAAa,eAIX,KACA,QACA,YAKG;CAEH,MAAM,+DAAwB,EAAE;CAEhC,IAAI,CAAC,YAAY;EACf,IAAI,CAAC,0BAA0B,IAAI,GAAa,GAAG;GAGjD,0CAD4B,EAAE,gCAAI,CAC7B,EACH,uDAA0B,GAAa,EAAE,wCACzC;IACE,OAAO;IACP,WAAW;GACb,CACF;GACA,0BAA0B,IAAI,GAAa;EAC7C;EAEA,IAAI,QAAQ,IAAI,aAAa,eAG3B,OAAO,mBAAmB,GAAa;EAGzC,OAAO,mBAAmB,GAAa;CACzC;CAEA,MAAM,WAAW,GAAG,IAAI,GAAG,UAAU,UAAU,GAAG,UAAU,mBAAmB;CAE/E,IAAI,gBAAgB,IAAI,QAAQ,GAC9B,OAAO,gBAAgB,IAAI,QAAQ;CAGrC,MAAM,SAASA,gDACb,YACA,QACA,OACF;CAEA,gBAAgB,IAAI,UAAU,MAAM;CAEpC,OAAO;AACT"}
1
+ {"version":3,"file":"getIntlayer.cjs","names":["getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryContent,\n DictionaryRegistryElement,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy({} as Record<string | symbol, unknown>, {\n get: (_target, prop) => {\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString' ||\n prop === 'valueOf'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n if (prop === Symbol.iterator) {\n return function* () {\n yield path;\n };\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n });\n};\n\nconst dictionaryCache = new Map<string, any>();\nconst warnedMissingDictionaries = new Set<string>();\n\nexport const getIntlayer = <\n T extends DictionaryKeys,\n L extends LocalesValues = DeclaredLocales,\n>(\n key: T,\n locale?: L,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryContent<T>,\n IInterpreterPluginState,\n L\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T] as DictionaryRegistryElement<T>;\n\n if (!dictionary && process.env.NODE_ENV === 'development') {\n if (!warnedMissingDictionaries.has(key as string)) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n typeof window === 'undefined'\n ? `Dictionary ${colorizeKey(key)} was not found. Using fallback proxy.`\n : `Dictionary ${key} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n }\n );\n warnedMissingDictionaries.add(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n const cacheKey = `${key}_${locale ?? 'default'}_${plugins ? 'custom_plugins' : 'default_plugins'}`;\n\n if (dictionaryCache.has(cacheKey)) {\n return dictionaryCache.get(cacheKey);\n }\n\n const result = getDictionary<DictionaryRegistryElement<T>, L>(\n dictionary,\n locale,\n plugins\n );\n\n dictionaryCache.set(cacheKey, result);\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAM,sBAAsB,OAAO,OAAY;CAC7C,OAAO,IAAI,MAAM,CAAC,GAAuC,EACvD,MAAM,SAAS,SAAS;EACtB,IACE,SAAS,YACT,SAAS,OAAO,eAChB,SAAS,cACT,SAAS,WAET,aAAa;EAEf,IAAI,SAAS,QACX;EAEF,IAAI,SAAS,OAAO,UAClB,OAAO,aAAa;GAClB,MAAM;EACR;EAKF,OAAO,mBADU,OAAO,GAAG,KAAK,GAAG,OAAO,IAAI,MAAM,OAAO,IAAI,CAC7B;CACpC,EACF,CAAC;AACH;AAEA,MAAM,kCAAkB,IAAI,IAAiB;AAC7C,MAAM,4CAA4B,IAAI,IAAY;AAElD,MAAa,eAIX,KACA,QACA,YAKG;CAEH,MAAM,+DAAwB,EAAE;CAEhC,IAAI,CAAC,cAAc,QAAQ,IAAI,aAAa,eAAe;EACzD,IAAI,CAAC,0BAA0B,IAAI,GAAa,GAAG;GAGjD,0CAD4B,EAAE,gCAAI,CAC7B,EACH,OAAO,WAAW,cACd,uDAA0B,GAAG,EAAE,yCAC/B,cAAc,IAAI,wCACtB,EACE,OAAO,OACT,CACF;GACA,0BAA0B,IAAI,GAAa;EAC7C;EAEA,OAAO,mBAAmB,GAAa;CACzC;CAEA,MAAM,WAAW,GAAG,IAAI,GAAG,UAAU,UAAU,GAAG,UAAU,mBAAmB;CAE/E,IAAI,gBAAgB,IAAI,QAAQ,GAC9B,OAAO,gBAAgB,IAAI,QAAQ;CAGrC,MAAM,SAASA,gDACb,YACA,QACA,OACF;CAEA,gBAAgB,IAAI,UAAU,MAAM;CAEpC,OAAO;AACT"}
@@ -21,10 +21,9 @@ const fileContent = (path, callerDir, baseDir) => {
21
21
  fixedPath: (0, node_path.relative)(baseDir, filePath)
22
22
  });
23
23
  } catch {
24
- appLogger(`Unable to read path: ${(0, _intlayer_config_logger.colorizePath)((0, node_path.relative)(baseDir, filePath))}`, { level: "warn" });
24
+ throw new Error(`Unable to read path: ${(0, _intlayer_config_logger.colorizePath)((0, node_path.relative)(baseDir, filePath))}`);
25
25
  }
26
- else appLogger(`File not found: ${(0, _intlayer_config_logger.colorizePath)((0, node_path.relative)(baseDir, filePath))}`, { level: "warn" });
27
- return (0, _intlayer_types_nodeType.formatNodeType)(_intlayer_types_nodeType.FILE, path, { content: `-` });
26
+ else throw new Error(`File not found: ${(0, _intlayer_config_logger.colorizePath)((0, node_path.relative)(baseDir, filePath))}`);
28
27
  };
29
28
  /**
30
29
  * Function intended to be used to build intlayer dictionaries.
@@ -1 +1 @@
1
- {"version":3,"file":"file.cjs","names":["FILE","baseDir"],"sources":["../../../../src/transpiler/file/file.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport { colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { FILE, formatNodeType } from '@intlayer/types/nodeType';\n\nexport type FileContentConstructor<T extends Record<string, any> = {}> =\n TypedNodeModel<typeof FILE, string, T>;\n\nexport type FileContent = FileContentConstructor<{\n content: string;\n fixedPath?: string;\n}>;\n\nexport const fileContent = (\n path: string,\n callerDir: string,\n baseDir: string\n): FileContent => {\n const isRelativePath = path.startsWith('./') || path.startsWith('../');\n const appLogger = getAppLogger();\n\n let filePath: string;\n if (isAbsolute(path)) {\n appLogger(\n `Using absolute path for file is not recommended. Use relative paths instead. Path: ${path}, imported from: ${callerDir}`,\n { level: 'warn' }\n );\n filePath = path;\n } else if (isRelativePath) {\n filePath = resolve(callerDir, path);\n } else {\n filePath = resolve(baseDir, path);\n }\n\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n try {\n const content = readFileSync(filePath, 'utf8');\n\n return formatNodeType(FILE, path, {\n content,\n fixedPath: relative(baseDir, filePath),\n });\n } catch {\n appLogger(\n `Unable to read path: ${colorizePath(relative(baseDir, filePath))}`,\n { level: 'warn' }\n );\n }\n } else {\n appLogger(`File not found: ${colorizePath(relative(baseDir, filePath))}`, {\n level: 'warn',\n });\n }\n\n return formatNodeType(FILE, path, {\n content: `-`,\n });\n};\n\ntype GlobalIntlayerFilePath = {\n INTLAYER_FILE_PATH: string;\n INTLAYER_BASE_DIR: string;\n};\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow identify the usage of an external resource.\n *\n * Usage:\n *\n * ```ts\n * file('/path/to/file.md') // absolute path\n *\n * // or\n *\n * file('path/to/file.md') // relative path\n * ```\n */\nexport const file = (path: string): FileContent => {\n const { INTLAYER_FILE_PATH, INTLAYER_BASE_DIR } =\n globalThis as unknown as GlobalIntlayerFilePath;\n\n const callerDir = dirname(INTLAYER_FILE_PATH);\n const baseDir = INTLAYER_BASE_DIR;\n\n return fileContent(path, callerDir, baseDir);\n};\n"],"mappings":";;;;;;;;AAcA,MAAa,eACX,MACA,WACA,YACgB;CAChB,MAAM,iBAAiB,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,KAAK;CACrE,MAAM,sDAAyB;CAE/B,IAAI;CACJ,8BAAe,IAAI,GAAG;EACpB,UACE,sFAAsF,KAAK,mBAAmB,aAC9G,EAAE,OAAO,OAAO,CAClB;EACA,WAAW;CACb,OAAO,IAAI,gBACT,kCAAmB,WAAW,IAAI;MAElC,kCAAmB,SAAS,IAAI;CAGlC,4BAAe,QAAQ,2BAAc,QAAQ,EAAE,OAAO,GACpD,IAAI;EAGF,oDAAsBA,+BAAM,MAAM;GAChC,mCAH2B,UAAU,MAG/B;GACN,mCAAoB,SAAS,QAAQ;EACvC,CAAC;CACH,QAAQ;EACN,UACE,0FAA8C,SAAS,QAAQ,CAAC,KAChE,EAAE,OAAO,OAAO,CAClB;CACF;MAEA,UAAU,qFAAyC,SAAS,QAAQ,CAAC,KAAK,EACxE,OAAO,OACT,CAAC;CAGH,oDAAsBA,+BAAM,MAAM,EAChC,SAAS,IACX,CAAC;AACH;;;;;;;;;;;;;;;;AAsBA,MAAa,QAAQ,SAA8B;CACjD,MAAM,EAAE,oBAAoB,sBAC1B;CAKF,OAAO,YAAY,6BAHO,kBAGO,GAAGC,iBAAO;AAC7C"}
1
+ {"version":3,"file":"file.cjs","names":["FILE","baseDir"],"sources":["../../../../src/transpiler/file/file.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport { colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { FILE, formatNodeType } from '@intlayer/types/nodeType';\n\nexport type FileContentConstructor<T extends Record<string, any> = {}> =\n TypedNodeModel<typeof FILE, string, T>;\n\nexport type FileContent = FileContentConstructor<{\n content: string;\n fixedPath?: string;\n}>;\n\nexport const fileContent = (\n path: string,\n callerDir: string,\n baseDir: string\n): FileContent => {\n const isRelativePath = path.startsWith('./') || path.startsWith('../');\n const appLogger = getAppLogger();\n\n let filePath: string;\n if (isAbsolute(path)) {\n appLogger(\n `Using absolute path for file is not recommended. Use relative paths instead. Path: ${path}, imported from: ${callerDir}`,\n { level: 'warn' }\n );\n filePath = path;\n } else if (isRelativePath) {\n filePath = resolve(callerDir, path);\n } else {\n filePath = resolve(baseDir, path);\n }\n\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n try {\n const content = readFileSync(filePath, 'utf8');\n\n return formatNodeType(FILE, path, {\n content,\n fixedPath: relative(baseDir, filePath),\n });\n } catch {\n throw new Error(\n `Unable to read path: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n } else {\n throw new Error(\n `File not found: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n};\n\ntype GlobalIntlayerFilePath = {\n INTLAYER_FILE_PATH: string;\n INTLAYER_BASE_DIR: string;\n};\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow identify the usage of an external resource.\n *\n * Usage:\n *\n * ```ts\n * file('/path/to/file.md') // absolute path\n *\n * // or\n *\n * file('path/to/file.md') // relative path\n * ```\n */\nexport const file = (path: string): FileContent => {\n const { INTLAYER_FILE_PATH, INTLAYER_BASE_DIR } =\n globalThis as unknown as GlobalIntlayerFilePath;\n\n const callerDir = dirname(INTLAYER_FILE_PATH);\n const baseDir = INTLAYER_BASE_DIR;\n\n return fileContent(path, callerDir, baseDir);\n};\n"],"mappings":";;;;;;;;AAcA,MAAa,eACX,MACA,WACA,YACgB;CAChB,MAAM,iBAAiB,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,KAAK;CACrE,MAAM,sDAAyB;CAE/B,IAAI;CACJ,8BAAe,IAAI,GAAG;EACpB,UACE,sFAAsF,KAAK,mBAAmB,aAC9G,EAAE,OAAO,OAAO,CAClB;EACA,WAAW;CACb,OAAO,IAAI,gBACT,kCAAmB,WAAW,IAAI;MAElC,kCAAmB,SAAS,IAAI;CAGlC,4BAAe,QAAQ,2BAAc,QAAQ,EAAE,OAAO,GACpD,IAAI;EAGF,oDAAsBA,+BAAM,MAAM;GAChC,mCAH2B,UAAU,MAG/B;GACN,mCAAoB,SAAS,QAAQ;EACvC,CAAC;CACH,QAAQ;EACN,MAAM,IAAI,MACR,0FAA8C,SAAS,QAAQ,CAAC,GAClE;CACF;MAEA,MAAM,IAAI,MACR,qFAAyC,SAAS,QAAQ,CAAC,GAC7D;AAEJ;;;;;;;;;;;;;;;;AAsBA,MAAa,QAAQ,SAA8B;CACjD,MAAM,EAAE,oBAAoB,sBAC1B;CAKF,OAAO,YAAY,6BAHO,kBAGO,GAAGC,iBAAO;AAC7C"}
@@ -4,6 +4,6 @@ const require_transpiler_html_html = require('./html.cjs');
4
4
  const require_transpiler_html_htmlTags = require('./htmlTags.cjs');
5
5
 
6
6
  exports.HTML_TAGS = require_transpiler_html_htmlTags.HTML_TAGS;
7
- exports.VOID_ELEMENTS = require_transpiler_html_validateHTML.VOID_ELEMENTS;
7
+ exports.VOID_HTML_ELEMENTS = require_transpiler_html_validateHTML.VOID_HTML_ELEMENTS;
8
8
  exports.html = require_transpiler_html_html.html;
9
9
  exports.validateHTML = require_transpiler_html_validateHTML.validateHTML;
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  //#region src/transpiler/html/validateHTML.ts
4
- const VOID_ELEMENTS = new Set([
4
+ const VOID_HTML_ELEMENTS = new Set([
5
5
  "area",
6
6
  "base",
7
7
  "br",
@@ -46,7 +46,7 @@ const validateHTML = (content) => {
46
46
  stack.pop();
47
47
  }
48
48
  else {
49
- const isVoidElement = VOID_ELEMENTS.has(tagName.toLowerCase());
49
+ const isVoidElement = VOID_HTML_ELEMENTS.has(tagName.toLowerCase());
50
50
  if (!isSelfClosing && !isVoidElement) stack.push({ tag: tagName });
51
51
  }
52
52
  }
@@ -61,6 +61,6 @@ const validateHTML = (content) => {
61
61
  };
62
62
 
63
63
  //#endregion
64
- exports.VOID_ELEMENTS = VOID_ELEMENTS;
64
+ exports.VOID_HTML_ELEMENTS = VOID_HTML_ELEMENTS;
65
65
  exports.validateHTML = validateHTML;
66
66
  //# sourceMappingURL=validateHTML.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"validateHTML.cjs","names":[],"sources":["../../../../src/transpiler/html/validateHTML.ts"],"sourcesContent":["export const VOID_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'source',\n 'track',\n 'wbr',\n]);\n\nexport type HTMLValidationIssue = {\n type: 'error' | 'warning';\n message: string;\n};\n\nexport type HTMLValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n// Matches HTML tags: <Tag ...>, </Tag>, or <Tag ... />\n// Attributes may span multiple lines but NOT blank lines (two consecutive newlines),\n// which prevents matching blockquote `>` markers as tag closers.\n// Groups: 1: closing slash, 2: tag name, 3: attributes, 4: self-closing slash\nconst TAG_REGEX =\n /<(\\/)?([a-zA-Z][a-zA-Z0-9.-]*)\\s*((?:[^\\n]|\\n(?!\\n))*?)(\\/?)>/g;\n\n/**\n * Validates that HTML tags in `content` are properly opened, nested, and closed.\n * Returns structured issues instead of logging to the console.\n *\n * False-positive exclusions:\n * - Tags whose attribute string starts with `://` are URL autolinks (e.g. `<https://…>`).\n */\nexport const validateHTML = (content: string): HTMLValidationResult => {\n const issues: HTMLValidationIssue[] = [];\n const stack: Array<{ tag: string }> = [];\n\n for (const match of content.matchAll(TAG_REGEX)) {\n const isClosing = !!match[1];\n const tagName = match[2];\n const attrs = match[3];\n const isSelfClosing = !!match[4];\n\n // Skip URL autolinks like <https://example.com> or <mailto:user@example.com>\n if (\n attrs.trimStart().startsWith('://') ||\n attrs.trimStart().startsWith(':')\n ) {\n continue;\n }\n\n if (isClosing) {\n if (stack.length === 0) {\n issues.push({\n type: 'error',\n message: `Closing tag </${tagName}> has no matching opening tag`,\n });\n } else {\n const last = stack[stack.length - 1];\n if (last.tag.toLowerCase() !== tagName.toLowerCase()) {\n issues.push({\n type: 'error',\n message: `Mismatched closing tag: expected </${last.tag}> but found </${tagName}>`,\n });\n }\n stack.pop();\n }\n } else {\n const isVoidElement = VOID_ELEMENTS.has(tagName.toLowerCase());\n if (!isSelfClosing && !isVoidElement) {\n stack.push({ tag: tagName });\n }\n }\n }\n\n for (const unclosed of stack) {\n issues.push({\n type: 'error',\n message: `Unclosed HTML tag: <${unclosed.tag}>`,\n });\n }\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";;;AAAA,MAAa,gBAAgB,IAAI,IAAI;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAgBD,MAAM,YACJ;;;;;;;;AASF,MAAa,gBAAgB,YAA0C;CACrE,MAAM,SAAgC,CAAC;CACvC,MAAM,QAAgC,CAAC;CAEvC,KAAK,MAAM,SAAS,QAAQ,SAAS,SAAS,GAAG;EAC/C,MAAM,YAAY,CAAC,CAAC,MAAM;EAC1B,MAAM,UAAU,MAAM;EACtB,MAAM,QAAQ,MAAM;EACpB,MAAM,gBAAgB,CAAC,CAAC,MAAM;EAG9B,IACE,MAAM,UAAU,EAAE,WAAW,KAAK,KAClC,MAAM,UAAU,EAAE,WAAW,GAAG,GAEhC;EAGF,IAAI,WACF,IAAI,MAAM,WAAW,GACnB,OAAO,KAAK;GACV,MAAM;GACN,SAAS,iBAAiB,QAAQ;EACpC,CAAC;OACI;GACL,MAAM,OAAO,MAAM,MAAM,SAAS;GAClC,IAAI,KAAK,IAAI,YAAY,MAAM,QAAQ,YAAY,GACjD,OAAO,KAAK;IACV,MAAM;IACN,SAAS,sCAAsC,KAAK,IAAI,gBAAgB,QAAQ;GAClF,CAAC;GAEH,MAAM,IAAI;EACZ;OACK;GACL,MAAM,gBAAgB,cAAc,IAAI,QAAQ,YAAY,CAAC;GAC7D,IAAI,CAAC,iBAAiB,CAAC,eACrB,MAAM,KAAK,EAAE,KAAK,QAAQ,CAAC;EAE/B;CACF;CAEA,KAAK,MAAM,YAAY,OACrB,OAAO,KAAK;EACV,MAAM;EACN,SAAS,uBAAuB,SAAS,IAAI;CAC/C,CAAC;CAGH,OAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,OAAO,EAAE,WAAW;EAC3D;CACF;AACF"}
1
+ {"version":3,"file":"validateHTML.cjs","names":[],"sources":["../../../../src/transpiler/html/validateHTML.ts"],"sourcesContent":["export const VOID_HTML_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'source',\n 'track',\n 'wbr',\n]);\n\nexport type HTMLValidationIssue = {\n type: 'error' | 'warning';\n message: string;\n};\n\nexport type HTMLValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n// Matches HTML tags: <Tag ...>, </Tag>, or <Tag ... />\n// Attributes may span multiple lines but NOT blank lines (two consecutive newlines),\n// which prevents matching blockquote `>` markers as tag closers.\n// Groups: 1: closing slash, 2: tag name, 3: attributes, 4: self-closing slash\nconst TAG_REGEX =\n /<(\\/)?([a-zA-Z][a-zA-Z0-9.-]*)\\s*((?:[^\\n]|\\n(?!\\n))*?)(\\/?)>/g;\n\n/**\n * Validates that HTML tags in `content` are properly opened, nested, and closed.\n * Returns structured issues instead of logging to the console.\n *\n * False-positive exclusions:\n * - Tags whose attribute string starts with `://` are URL autolinks (e.g. `<https://…>`).\n */\nexport const validateHTML = (content: string): HTMLValidationResult => {\n const issues: HTMLValidationIssue[] = [];\n const stack: Array<{ tag: string }> = [];\n\n for (const match of content.matchAll(TAG_REGEX)) {\n const isClosing = !!match[1];\n const tagName = match[2];\n const attrs = match[3];\n const isSelfClosing = !!match[4];\n\n // Skip URL autolinks like <https://example.com> or <mailto:user@example.com>\n if (\n attrs.trimStart().startsWith('://') ||\n attrs.trimStart().startsWith(':')\n ) {\n continue;\n }\n\n if (isClosing) {\n if (stack.length === 0) {\n issues.push({\n type: 'error',\n message: `Closing tag </${tagName}> has no matching opening tag`,\n });\n } else {\n const last = stack[stack.length - 1];\n if (last.tag.toLowerCase() !== tagName.toLowerCase()) {\n issues.push({\n type: 'error',\n message: `Mismatched closing tag: expected </${last.tag}> but found </${tagName}>`,\n });\n }\n stack.pop();\n }\n } else {\n const isVoidElement = VOID_HTML_ELEMENTS.has(tagName.toLowerCase());\n if (!isSelfClosing && !isVoidElement) {\n stack.push({ tag: tagName });\n }\n }\n }\n\n for (const unclosed of stack) {\n issues.push({\n type: 'error',\n message: `Unclosed HTML tag: <${unclosed.tag}>`,\n });\n }\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";;;AAAA,MAAa,qBAAqB,IAAI,IAAI;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAgBD,MAAM,YACJ;;;;;;;;AASF,MAAa,gBAAgB,YAA0C;CACrE,MAAM,SAAgC,CAAC;CACvC,MAAM,QAAgC,CAAC;CAEvC,KAAK,MAAM,SAAS,QAAQ,SAAS,SAAS,GAAG;EAC/C,MAAM,YAAY,CAAC,CAAC,MAAM;EAC1B,MAAM,UAAU,MAAM;EACtB,MAAM,QAAQ,MAAM;EACpB,MAAM,gBAAgB,CAAC,CAAC,MAAM;EAG9B,IACE,MAAM,UAAU,EAAE,WAAW,KAAK,KAClC,MAAM,UAAU,EAAE,WAAW,GAAG,GAEhC;EAGF,IAAI,WACF,IAAI,MAAM,WAAW,GACnB,OAAO,KAAK;GACV,MAAM;GACN,SAAS,iBAAiB,QAAQ;EACpC,CAAC;OACI;GACL,MAAM,OAAO,MAAM,MAAM,SAAS;GAClC,IAAI,KAAK,IAAI,YAAY,MAAM,QAAQ,YAAY,GACjD,OAAO,KAAK;IACV,MAAM;IACN,SAAS,sCAAsC,KAAK,IAAI,gBAAgB,QAAQ;GAClF,CAAC;GAEH,MAAM,IAAI;EACZ;OACK;GACL,MAAM,gBAAgB,mBAAmB,IAAI,QAAQ,YAAY,CAAC;GAClE,IAAI,CAAC,iBAAiB,CAAC,eACrB,MAAM,KAAK,EAAE,KAAK,QAAQ,CAAC;EAE/B;CACF;CAEA,KAAK,MAAM,YAAY,OACrB,OAAO,KAAK;EACV,MAAM;EACN,SAAS,uBAAuB,SAAS,IAAI;CAC/C,CAAC;CAGH,OAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,OAAO,EAAE,WAAW;EAC3D;CACF;AACF"}
@@ -15,7 +15,7 @@ const require_transpiler_plural_plural = require('./plural/plural.cjs');
15
15
  const require_transpiler_translation_translation = require('./translation/translation.cjs');
16
16
 
17
17
  exports.HTML_TAGS = require_transpiler_html_htmlTags.HTML_TAGS;
18
- exports.VOID_ELEMENTS = require_transpiler_html_validateHTML.VOID_ELEMENTS;
18
+ exports.VOID_HTML_ELEMENTS = require_transpiler_html_validateHTML.VOID_HTML_ELEMENTS;
19
19
  exports.cond = require_transpiler_condition_condition.cond;
20
20
  exports.enu = require_transpiler_enumeration_enumeration.enu;
21
21
  exports.gender = require_transpiler_gender_gender.gender;
@@ -6,6 +6,7 @@ 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');
8
8
  const require_utils_isSameKeyPath = require('./isSameKeyPath.cjs');
9
+ const require_utils_stringifyYaml = require('./stringifyYaml.cjs');
9
10
 
10
11
  exports.CachedIntl = require_utils_intl.CachedIntl;
11
12
  exports.Intl = require_utils_intl.CachedIntl;
@@ -24,4 +25,5 @@ exports.isValidElement = require_utils_isValidReactElement.isValidElement;
24
25
  exports.parseYaml = require_utils_parseYaml.parseYaml;
25
26
  exports.setLocaleInStorage = require_utils_localeStorage.setLocaleInStorage;
26
27
  exports.setLocaleInStorageClient = require_utils_localeStorage.setLocaleInStorageClient;
27
- exports.setLocaleInStorageServer = require_utils_localeStorage.setLocaleInStorageServer;
28
+ exports.setLocaleInStorageServer = require_utils_localeStorage.setLocaleInStorageServer;
29
+ exports.stringifyYaml = require_utils_stringifyYaml.stringifyYaml;
@@ -0,0 +1,59 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ //#region src/utils/stringifyYaml.ts
4
+ const NEEDS_QUOTING = /[\n\r\t#:{}[\],&*?|<>=!%@`'"\\]|^[-?!]|\s$|^\s|^[>|]|^[.]{2,}/;
5
+ const PRESERVED_LITERALS = new Set([
6
+ "true",
7
+ "false",
8
+ "null",
9
+ "undefined",
10
+ "yes",
11
+ "no",
12
+ "on",
13
+ "off",
14
+ "NaN",
15
+ "Infinity",
16
+ "-Infinity"
17
+ ]);
18
+ const serializeString = (value, indent) => {
19
+ if (value.includes("\n")) return `|\n${value.split("\n").map((l) => `${indent} ${l}`).join("\n")}`;
20
+ if (NEEDS_QUOTING.test(value) || PRESERVED_LITERALS.has(value) || /^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i.test(value)) return JSON.stringify(value);
21
+ return value;
22
+ };
23
+ const serializeValue = (value, indent) => {
24
+ if (value === null || value === void 0) return "null";
25
+ if (typeof value === "boolean" || typeof value === "number") return String(value);
26
+ if (typeof value === "string") return serializeString(value, indent);
27
+ if (Array.isArray(value)) {
28
+ if (value.length === 0) return "[]";
29
+ return value.map((item) => {
30
+ const serialized = serializeValue(item, `${indent} `);
31
+ if (typeof item === "object" && item !== null && !Array.isArray(item) && !serialized.startsWith("'") && !serialized.startsWith("\"")) {
32
+ const lines = serialized.split("\n");
33
+ return `${indent}- ${lines[0]}\n${lines.slice(1).map((l) => `${indent} ${l}`).join("\n")}`.trimEnd();
34
+ }
35
+ return `${indent}- ${serialized}`;
36
+ }).join("\n");
37
+ }
38
+ if (typeof value === "object") {
39
+ const entries = Object.entries(value).filter(([, v]) => v !== void 0);
40
+ if (entries.length === 0) return "{}";
41
+ return entries.map(([k, value]) => {
42
+ const key = /[\s:{}[\]]/.test(k) ? JSON.stringify(k) : k;
43
+ const childIndent = `${indent} `;
44
+ if (value === null || value === void 0) return `${indent}${key}: null`;
45
+ if (typeof value === "object" && !Array.isArray(value)) return `${indent}${key}:\n${serializeValue(value, childIndent)}`;
46
+ if (Array.isArray(value)) {
47
+ if (value.length === 0) return `${indent}${key}: []`;
48
+ return `${indent}${key}:\n${serializeValue(value, childIndent)}`;
49
+ }
50
+ return `${indent}${key}: ${serializeValue(value, indent)}`;
51
+ }).join("\n");
52
+ }
53
+ return String(value);
54
+ };
55
+ const stringifyYaml = (value) => `${serializeValue(value, "")}\n`;
56
+
57
+ //#endregion
58
+ exports.stringifyYaml = stringifyYaml;
59
+ //# sourceMappingURL=stringifyYaml.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringifyYaml.cjs","names":[],"sources":["../../../src/utils/stringifyYaml.ts"],"sourcesContent":["// Characters/patterns in a string that require quoting in YAML\nconst NEEDS_QUOTING =\n /[\\n\\r\\t#:{}[\\],&*?|<>=!%@`'\"\\\\]|^[-?!]|\\s$|^\\s|^[>|]|^[.]{2,}/;\n\n// Values that parseYaml treats as preserved literals (not typed conversions)\nconst PRESERVED_LITERALS = new Set([\n 'true',\n 'false',\n 'null',\n 'undefined',\n 'yes',\n 'no',\n 'on',\n 'off',\n 'NaN',\n 'Infinity',\n '-Infinity',\n]);\n\nconst serializeString = (value: string, indent: string): string => {\n if (value.includes('\\n')) {\n const lines = value.split('\\n');\n const body = lines.map((l) => `${indent} ${l}`).join('\\n');\n return `|\\n${body}`;\n }\n\n if (\n NEEDS_QUOTING.test(value) ||\n PRESERVED_LITERALS.has(value) ||\n /^-?\\d+(?:\\.\\d+)?(?:e[+-]?\\d+)?$/i.test(value)\n ) {\n return JSON.stringify(value);\n }\n\n return value;\n};\n\nconst serializeValue = (value: any, indent: string): string => {\n if (value === null || value === undefined) return 'null';\n\n if (typeof value === 'boolean' || typeof value === 'number') {\n return String(value);\n }\n\n if (typeof value === 'string') {\n return serializeString(value, indent);\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) return '[]';\n return value\n .map((item) => {\n const serialized = serializeValue(item, `${indent} `);\n if (\n typeof item === 'object' &&\n item !== null &&\n !Array.isArray(item) &&\n !serialized.startsWith(\"'\") &&\n !serialized.startsWith('\"')\n ) {\n // Object items: put first key inline with the dash\n const lines = serialized.split('\\n');\n return `${indent}- ${lines[0]}\\n${lines\n .slice(1)\n .map((l) => `${indent} ${l}`)\n .join('\\n')}`.trimEnd();\n }\n return `${indent}- ${serialized}`;\n })\n .join('\\n');\n }\n\n if (typeof value === 'object') {\n const entries = Object.entries(value).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return '{}';\n\n return entries\n .map(([k, value]) => {\n const key = /[\\s:{}[\\]]/.test(k) ? JSON.stringify(k) : k;\n const childIndent = `${indent} `;\n\n if (value === null || value === undefined) {\n return `${indent}${key}: null`;\n }\n\n if (typeof value === 'object' && !Array.isArray(value)) {\n const nested = serializeValue(value, childIndent);\n return `${indent}${key}:\\n${nested}`;\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) return `${indent}${key}: []`;\n const nested = serializeValue(value, childIndent);\n return `${indent}${key}:\\n${nested}`;\n }\n\n return `${indent}${key}: ${serializeValue(value, indent)}`;\n })\n .join('\\n');\n }\n\n return String(value);\n};\n\nexport const stringifyYaml = (value: any): string =>\n `${serializeValue(value, '')}\\n`;\n"],"mappings":";;;AACA,MAAM,gBACJ;AAGF,MAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,mBAAmB,OAAe,WAA2B;CACjE,IAAI,MAAM,SAAS,IAAI,GAGrB,OAAO,MAFO,MAAM,MAAM,IACT,EAAE,KAAK,MAAM,GAAG,OAAO,IAAI,GAAG,EAAE,KAAK,IACtC;CAGlB,IACE,cAAc,KAAK,KAAK,KACxB,mBAAmB,IAAI,KAAK,KAC5B,mCAAmC,KAAK,KAAK,GAE7C,OAAO,KAAK,UAAU,KAAK;CAG7B,OAAO;AACT;AAEA,MAAM,kBAAkB,OAAY,WAA2B;CAC7D,IAAI,UAAU,QAAQ,UAAU,QAAW,OAAO;CAElD,IAAI,OAAO,UAAU,aAAa,OAAO,UAAU,UACjD,OAAO,OAAO,KAAK;CAGrB,IAAI,OAAO,UAAU,UACnB,OAAO,gBAAgB,OAAO,MAAM;CAGtC,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,IAAI,MAAM,WAAW,GAAG,OAAO;EAC/B,OAAO,MACJ,KAAK,SAAS;GACb,MAAM,aAAa,eAAe,MAAM,GAAG,OAAO,GAAG;GACrD,IACE,OAAO,SAAS,YAChB,SAAS,QACT,CAAC,MAAM,QAAQ,IAAI,KACnB,CAAC,WAAW,WAAW,GAAG,KAC1B,CAAC,WAAW,WAAW,IAAG,GAC1B;IAEA,MAAM,QAAQ,WAAW,MAAM,IAAI;IACnC,OAAO,GAAG,OAAO,IAAI,MAAM,GAAG,IAAI,MAC/B,MAAM,CAAC,EACP,KAAK,MAAM,GAAG,OAAO,IAAI,GAAG,EAC5B,KAAK,IAAI,IAAI,QAAQ;GAC1B;GACA,OAAO,GAAG,OAAO,IAAI;EACvB,CAAC,EACA,KAAK,IAAI;CACd;CAEA,IAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,UAAU,OAAO,QAAQ,KAAK,EAAE,QAAQ,GAAG,OAAO,MAAM,MAAS;EACvE,IAAI,QAAQ,WAAW,GAAG,OAAO;EAEjC,OAAO,QACJ,KAAK,CAAC,GAAG,WAAW;GACnB,MAAM,MAAM,aAAa,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI;GACvD,MAAM,cAAc,GAAG,OAAO;GAE9B,IAAI,UAAU,QAAQ,UAAU,QAC9B,OAAO,GAAG,SAAS,IAAI;GAGzB,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAEnD,OAAO,GAAG,SAAS,IAAI,KADR,eAAe,OAAO,WACJ;GAGnC,IAAI,MAAM,QAAQ,KAAK,GAAG;IACxB,IAAI,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,IAAI;IAE/C,OAAO,GAAG,SAAS,IAAI,KADR,eAAe,OAAO,WACJ;GACnC;GAEA,OAAO,GAAG,SAAS,IAAI,IAAI,eAAe,OAAO,MAAM;EACzD,CAAC,EACA,KAAK,IAAI;CACd;CAEA,OAAO,OAAO,KAAK;AACrB;AAEA,MAAa,iBAAiB,UAC5B,GAAG,eAAe,OAAO,EAAE,EAAE"}
@@ -29,7 +29,7 @@ const editDictionaryByKeyPath = (dictionaryContent, keyPath, newValue) => {
29
29
  }
30
30
  if (keyObj.type === NodeTypes.MARKDOWN || keyObj.type === NodeTypes.HTML || keyObj.type === NodeTypes.INSERTION) {
31
31
  lastKeys = [keyObj.type];
32
- if (!currentValue[keyObj.type] || typeof currentValue[keyObj.type] !== "object") currentValue[keyObj.type] = "";
32
+ if (currentValue[keyObj.type] == null) currentValue[keyObj.type] = "";
33
33
  currentValue = currentValue[keyObj.type];
34
34
  }
35
35
  if (keyObj.type === NodeTypes.FILE) {
@@ -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 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,CAAC;CAE/B,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,IAAI;EACF,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;GACvB,cAAc;GAEd,IAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,OAAO;IACvE,WAAW,CAAC,OAAO,GAAG;IAEtB,IACE,CAAC,aAAa,OAAO,QACrB,OAAO,aAAa,OAAO,SAAS,UAEpC,aAAa,OAAO,OAAO,CAAC;IAE9B,eAAe,aAAa,OAAO;GACrC;GAEA,IACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,QAC1B;IACA,WAAW,CAAC,OAAO,MAAM,OAAO,GAAG;IAEnC,IACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,UAErC,aAAa,OAAO,QAAQ,CAAC;IAG/B,IACE,CAAC,aAAa,OAAO,MAAM,OAAO,QAClC,OAAO,aAAa,OAAO,MAAM,OAAO,SAAS,UAEjD,aAAa,OAAO,MAAM,OAAO,OAAO,CAAC;IAE3C,eAAe,aAAa,OAAO,MAAM,OAAO;GAClD;GAEA,IACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,UAC1B,OAAO,SAAS,UAAU,WAQ1B;QACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,QAC1B;KACA,WAAW,CAAC,OAAO,MAAM,OAAO,GAAG;KACnC,eAAe,aAAa,OAAO,MAAM,OAAO;IAClD;;GAGF,IACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,WAC1B;IACA,WAAW,CAAC,OAAO,IAAI;IAEvB,IACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,UAErC,aAAa,OAAO,QAAQ;IAE9B,eAAe,aAAa,OAAO;GACrC;GAEA,IAAI,OAAO,SAAS,UAAU,MAAM;IAClC,WAAW,CAAC,SAAS;IACrB,eAAe,aAAa;GAC9B;GAIA,IAAI,MAAM,QAAQ,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;IAClE,IAAI,SAAS;IAGb,KAAK,MAAM,OAAO,SAAS,MAAM,GAAG,EAAE,GACpC,SAAS,OAAO;IAGlB,MAAM,WAAW,SAAS,SAAS,SAAS;IAE5C,IAAI,OAAO,aAAa,aAGtB,IAAI,MAAM,QAAQ,MAAM,GAAG;KACzB,MAAM,QAAQ,OAAO,QAAQ;KAE7B,IAAI,CAAC,OAAO,MAAM,KAAK,KAAK,SAAS,KAAK,QAAQ,OAAO,QACvD,OAAO,OAAO,OAAO,CAAC;IAE1B,OACE,OAAO,OAAO;SAGhB,OAAO,YAAY;GAEvB;EACF;EAEA,OAAO;CACT,SAAS,OAAO;EACd,QAAQ,MACN,sCACA;GAAE;GAAmB;GAAS;EAAS,GACvC,KACF;EACA,OAAO;CACT;AACF"}
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 (currentValue[keyObj.type] == null) {\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,CAAC;CAE/B,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,IAAI;EACF,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;GACvB,cAAc;GAEd,IAAI,OAAO,SAAS,UAAU,UAAU,OAAO,SAAS,UAAU,OAAO;IACvE,WAAW,CAAC,OAAO,GAAG;IAEtB,IACE,CAAC,aAAa,OAAO,QACrB,OAAO,aAAa,OAAO,SAAS,UAEpC,aAAa,OAAO,OAAO,CAAC;IAE9B,eAAe,aAAa,OAAO;GACrC;GAEA,IACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,QAC1B;IACA,WAAW,CAAC,OAAO,MAAM,OAAO,GAAG;IAEnC,IACE,CAAC,aAAa,OAAO,SACrB,OAAO,aAAa,OAAO,UAAU,UAErC,aAAa,OAAO,QAAQ,CAAC;IAG/B,IACE,CAAC,aAAa,OAAO,MAAM,OAAO,QAClC,OAAO,aAAa,OAAO,MAAM,OAAO,SAAS,UAEjD,aAAa,OAAO,MAAM,OAAO,OAAO,CAAC;IAE3C,eAAe,aAAa,OAAO,MAAM,OAAO;GAClD;GAEA,IACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,UAC1B,OAAO,SAAS,UAAU,WAQ1B;QACE,OAAO,SAAS,UAAU,eAC1B,OAAO,SAAS,UAAU,QAC1B;KACA,WAAW,CAAC,OAAO,MAAM,OAAO,GAAG;KACnC,eAAe,aAAa,OAAO,MAAM,OAAO;IAClD;;GAGF,IACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,QAC1B,OAAO,SAAS,UAAU,WAC1B;IACA,WAAW,CAAC,OAAO,IAAI;IAEvB,IAAI,aAAa,OAAO,SAAS,MAC/B,aAAa,OAAO,QAAQ;IAE9B,eAAe,aAAa,OAAO;GACrC;GAEA,IAAI,OAAO,SAAS,UAAU,MAAM;IAClC,WAAW,CAAC,SAAS;IACrB,eAAe,aAAa;GAC9B;GAIA,IAAI,MAAM,QAAQ,SAAS,KAAK,eAAe,SAAS,SAAS,GAAG;IAClE,IAAI,SAAS;IAGb,KAAK,MAAM,OAAO,SAAS,MAAM,GAAG,EAAE,GACpC,SAAS,OAAO;IAGlB,MAAM,WAAW,SAAS,SAAS,SAAS;IAE5C,IAAI,OAAO,aAAa,aAGtB,IAAI,MAAM,QAAQ,MAAM,GAAG;KACzB,MAAM,QAAQ,OAAO,QAAQ;KAE7B,IAAI,CAAC,OAAO,MAAM,KAAK,KAAK,SAAS,KAAK,QAAQ,OAAO,QACvD,OAAO,OAAO,OAAO,CAAC;IAE1B,OACE,OAAO,OAAO;SAGhB,OAAO,YAAY;GAEvB;EACF;EAEA,OAAO;CACT,SAAS,OAAO;EACd,QAAQ,MACN,sCACA;GAAE;GAAmB;GAAS;EAAS,GACvC,KACF;EACA,OAAO;CACT;AACF"}
@@ -11,7 +11,7 @@ const getEmptyNode = (section) => {
11
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
- if (typedNode.nodeType === NodeTypes.MARKDOWN) return getEmptyNode(typedNode);
14
+ if (typedNode.nodeType === NodeTypes.MARKDOWN) return getEmptyNode(content);
15
15
  return content;
16
16
  }
17
17
  if (!section || typeof section !== "object") return section;
@@ -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.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;CACjE,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,UACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,MAEjC,OAAO,aAAa,OAAsB;EAG5C,IAAI,UAAU,aAAa,UAAU,QACnC,OAAO;EAGT,IAAI,UAAU,aAAa,UAAU,MACnC,OAAO;EAGT,IAAI,UAAU,aAAa,UAAU,UACnC,OAAO,aAAa,SAAS;EAG/B,OAAO;CACT;CAEA,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAQ,QAA0B,IAChC,YACF;CAGF,MAAM,sBAAsB,OAAO,QAAQ,OAAO,EAAE,KAAK,CAAC,KAAK,WAAW,CACxE,KACA,aAAa,KAAoB,CACnC,CAAC;CAID,OAF2B,OAAO,YAAY,mBAEtB;AAC1B"}
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(content as ContentNode);\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;CACjE,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,eACjC,UAAU,aAAa,UAAU,UACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,aACjC,UAAU,aAAa,UAAU,MAEjC,OAAO,aAAa,OAAsB;EAG5C,IAAI,UAAU,aAAa,UAAU,QACnC,OAAO;EAGT,IAAI,UAAU,aAAa,UAAU,MACnC,OAAO;EAGT,IAAI,UAAU,aAAa,UAAU,UACnC,OAAO,aAAa,OAAsB;EAG5C,OAAO;CACT;CAEA,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAQ,QAA0B,IAChC,YACF;CAGF,MAAM,sBAAsB,OAAO,QAAQ,OAAO,EAAE,KAAK,CAAC,KAAK,WAAW,CACxE,KACA,aAAa,KAAoB,CACnC,CAAC;CAID,OAF2B,OAAO,YAAY,mBAEtB;AAC1B"}
@@ -8,7 +8,8 @@ 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.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]];
11
+ if (typedNode.nodeType === NodeTypes.MARKDOWN || typedNode.nodeType === NodeTypes.HTML) return content;
12
+ 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) return content[Object.keys(content)[0]];
12
13
  if (typedNode.nodeType === NodeTypes.NESTED) return;
13
14
  return content;
14
15
  }
@@ -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.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;CACpE,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,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,MAGjC,OAAO,QADU,OAAO,KAAK,OAAO,EAAE;EAIxC,IAAI,UAAU,aAAa,UAAU,QACnC;EAGF,OAAO;CACT;CAEA,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAQ,QAA0B;CAGpC,OAAO;AACT"}
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.MARKDOWN ||\n typedNode.nodeType === NodeTypes.HTML\n ) {\n return content as ContentNode;\n }\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 ) {\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;CACpE,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,UAAU,aAAa,UAAU,YACjC,UAAU,aAAa,UAAU,MAEjC,OAAO;EAGT,IACE,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,MAGjC,OAAO,QADU,OAAO,KAAK,OAAO,EAAE;EAIxC,IAAI,UAAU,aAAa,UAAU,QACnC;EAGF,OAAO;CACT;CAEA,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,OAAO,GACvB,OAAQ,QAA0B;CAGpC,OAAO;AACT"}
@@ -23,7 +23,7 @@ import { getFilteredLocalesContent, getFilteredLocalesDictionary } from "./deepT
23
23
  import { cond as condition } from "./transpiler/condition/condition.mjs";
24
24
  import { enu as enumeration } from "./transpiler/enumeration/enumeration.mjs";
25
25
  import { gender } from "./transpiler/gender/gender.mjs";
26
- import { VOID_ELEMENTS, validateHTML } from "./transpiler/html/validateHTML.mjs";
26
+ import { VOID_HTML_ELEMENTS, validateHTML } from "./transpiler/html/validateHTML.mjs";
27
27
  import { html } from "./transpiler/html/html.mjs";
28
28
  import { HTML_TAGS } from "./transpiler/html/htmlTags.mjs";
29
29
  import { getInsertionValues } from "./transpiler/insertion/getInsertionValues.mjs";
@@ -86,5 +86,6 @@ import { i18nextToIntlayerFormatter, intlayerToI18nextFormatter } from "./messag
86
86
  import { intlayerToPortableObjectFormatter, portableObjectToIntlayerFormatter } from "./messageFormat/po.mjs";
87
87
  import { intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter } from "./messageFormat/vue-i18n.mjs";
88
88
  import { isSameKeyPath } from "./utils/isSameKeyPath.mjs";
89
+ import { stringifyYaml } from "./utils/stringifyYaml.mjs";
89
90
 
90
- 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, intlayerToPortableObjectFormatter, 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, portableObjectToIntlayerFormatter, 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 };
91
+ 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_HTML_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, intlayerToPortableObjectFormatter, 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, portableObjectToIntlayerFormatter, presets, qualifies, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderNothing, sanitizer, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, stringifyYaml, translation as t, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter };
@@ -9,30 +9,22 @@ import { getDictionaries } from "@intlayer/dictionaries-entry";
9
9
  * stringified. This prevents the app from crashing on undefined access.
10
10
  */
11
11
  const createSafeFallback = (path = "") => {
12
- return new Proxy(() => path, {
13
- get: (_target, prop) => {
14
- if (prop === "toJSON" || prop === Symbol.toPrimitive || prop === "toString") return () => path;
15
- if (prop === "then") return;
16
- if (prop === Symbol.iterator) return function* () {
17
- yield path;
18
- };
19
- return createSafeFallback(path ? `${path}.${String(prop)}` : String(prop));
20
- },
21
- apply: () => {
22
- return path;
23
- }
24
- });
12
+ return new Proxy({}, { get: (_target, prop) => {
13
+ if (prop === "toJSON" || prop === Symbol.toPrimitive || prop === "toString" || prop === "valueOf") return () => path;
14
+ if (prop === "then") return;
15
+ if (prop === Symbol.iterator) return function* () {
16
+ yield path;
17
+ };
18
+ return createSafeFallback(path ? `${path}.${String(prop)}` : String(prop));
19
+ } });
25
20
  };
26
21
  const dictionaryCache = /* @__PURE__ */ new Map();
27
22
  const warnedMissingDictionaries = /* @__PURE__ */ new Set();
28
23
  const getIntlayer = (key, locale, plugins) => {
29
24
  const dictionary = getDictionaries()[key];
30
- if (!dictionary) {
25
+ if (!dictionary && true) {
31
26
  if (!warnedMissingDictionaries.has(key)) {
32
- getAppLogger({ log })(`Dictionary ${colorizeKey(key)} was not found. Using fallback proxy.`, {
33
- level: "warn",
34
- isVerbose: true
35
- });
27
+ getAppLogger({ log })(typeof window === "undefined" ? `Dictionary ${colorizeKey(key)} was not found. Using fallback proxy.` : `Dictionary ${key} was not found. Using fallback proxy.`, { level: "warn" });
36
28
  warnedMissingDictionaries.add(key);
37
29
  }
38
30
  return createSafeFallback(key);