@intlayer/core 8.9.7 → 8.10.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/README.md +14 -0
  2. package/dist/cjs/deepTransformPlugins/getFilterMissingTranslationsContent.cjs.map +1 -1
  3. package/dist/cjs/deepTransformPlugins/getFilterTranslationsOnlyContent.cjs.map +1 -1
  4. package/dist/cjs/deepTransformPlugins/getFilteredLocalesContent.cjs.map +1 -1
  5. package/dist/cjs/deepTransformPlugins/getLocalizedContent.cjs.map +1 -1
  6. package/dist/cjs/deepTransformPlugins/getMaskContent.cjs.map +1 -1
  7. package/dist/cjs/deepTransformPlugins/getMissingLocalesContent.cjs.map +1 -1
  8. package/dist/cjs/deepTransformPlugins/getMultilingualDictionary.cjs.map +1 -1
  9. package/dist/cjs/deepTransformPlugins/getReplacedValuesContent.cjs.map +1 -1
  10. package/dist/cjs/deepTransformPlugins/getSplittedContent.cjs.map +1 -1
  11. package/dist/cjs/deepTransformPlugins/insertContentInDictionary.cjs.map +1 -1
  12. package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs +1 -1
  13. package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs.map +1 -1
  14. package/dist/cjs/dictionaryManipulator/getContentNodeByKeyPath.cjs.map +1 -1
  15. package/dist/cjs/dictionaryManipulator/getDefaultNode.cjs.map +1 -1
  16. package/dist/cjs/dictionaryManipulator/getEmptyNode.cjs +1 -1
  17. package/dist/cjs/dictionaryManipulator/getEmptyNode.cjs.map +1 -1
  18. package/dist/cjs/dictionaryManipulator/getNodeChildren.cjs +2 -1
  19. package/dist/cjs/dictionaryManipulator/getNodeChildren.cjs.map +1 -1
  20. package/dist/cjs/dictionaryManipulator/getNodeType.cjs.map +1 -1
  21. package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs.map +1 -1
  22. package/dist/cjs/dictionaryManipulator/normalizeDictionary.cjs.map +1 -1
  23. package/dist/cjs/dictionaryManipulator/orderDictionaries.cjs.map +1 -1
  24. package/dist/cjs/dictionaryManipulator/removeContentNodeByKeyPath.cjs.map +1 -1
  25. package/dist/cjs/dictionaryManipulator/renameContentNodeByKeyPath.cjs.map +1 -1
  26. package/dist/cjs/dictionaryManipulator/updateNodeChildren.cjs.map +1 -1
  27. package/dist/cjs/formatters/compact.cjs.map +1 -1
  28. package/dist/cjs/formatters/currency.cjs.map +1 -1
  29. package/dist/cjs/formatters/date.cjs.map +1 -1
  30. package/dist/cjs/formatters/list.cjs.map +1 -1
  31. package/dist/cjs/formatters/number.cjs.map +1 -1
  32. package/dist/cjs/formatters/percentage.cjs.map +1 -1
  33. package/dist/cjs/formatters/relativeTime.cjs.map +1 -1
  34. package/dist/cjs/formatters/units.cjs.map +1 -1
  35. package/dist/cjs/index.cjs +2 -0
  36. package/dist/cjs/interpreter/getCondition.cjs.map +1 -1
  37. package/dist/cjs/interpreter/getContent/deepTransform.cjs.map +1 -1
  38. package/dist/cjs/interpreter/getContent/getContent.cjs.map +1 -1
  39. package/dist/cjs/interpreter/getContent/plugins.cjs +1 -5
  40. package/dist/cjs/interpreter/getContent/plugins.cjs.map +1 -1
  41. package/dist/cjs/interpreter/getDictionary.cjs.map +1 -1
  42. package/dist/cjs/interpreter/getEnumeration.cjs.map +1 -1
  43. package/dist/cjs/interpreter/getGender.cjs.map +1 -1
  44. package/dist/cjs/interpreter/getHTML.cjs.map +1 -1
  45. package/dist/cjs/interpreter/getInsertion.cjs.map +1 -1
  46. package/dist/cjs/interpreter/getIntlayer.cjs +10 -19
  47. package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
  48. package/dist/cjs/interpreter/getNesting.cjs.map +1 -1
  49. package/dist/cjs/interpreter/getPlural.cjs.map +1 -1
  50. package/dist/cjs/interpreter/getTranslation.cjs.map +1 -1
  51. package/dist/cjs/interpreter/splitAndJoinInsertion.cjs.map +1 -1
  52. package/dist/cjs/localization/generateSitemap.cjs.map +1 -1
  53. package/dist/cjs/localization/getBrowserLocale.cjs.map +1 -1
  54. package/dist/cjs/localization/getHTMLTextDir.cjs.map +1 -1
  55. package/dist/cjs/localization/getLocale.cjs.map +1 -1
  56. package/dist/cjs/localization/getLocaleFromPath.cjs.map +1 -1
  57. package/dist/cjs/localization/getLocaleLang.cjs.map +1 -1
  58. package/dist/cjs/localization/getLocaleName.cjs.map +1 -1
  59. package/dist/cjs/localization/getLocalizedUrl.cjs.map +1 -1
  60. package/dist/cjs/localization/getMultilingualUrls.cjs.map +1 -1
  61. package/dist/cjs/localization/getPathWithoutLocale.cjs.map +1 -1
  62. package/dist/cjs/localization/getPrefix.cjs.map +1 -1
  63. package/dist/cjs/localization/localeDetector.cjs.map +1 -1
  64. package/dist/cjs/localization/localeMapper.cjs.map +1 -1
  65. package/dist/cjs/localization/localeResolver.cjs.map +1 -1
  66. package/dist/cjs/localization/rewriteUtils.cjs.map +1 -1
  67. package/dist/cjs/localization/validatePrefix.cjs.map +1 -1
  68. package/dist/cjs/markdown/compiler.cjs.map +1 -1
  69. package/dist/cjs/markdown/constants.cjs.map +1 -1
  70. package/dist/cjs/markdown/parser.cjs.map +1 -1
  71. package/dist/cjs/markdown/renderer.cjs.map +1 -1
  72. package/dist/cjs/markdown/utils.cjs.map +1 -1
  73. package/dist/cjs/messageFormat/ICU.cjs.map +1 -1
  74. package/dist/cjs/messageFormat/i18next.cjs.map +1 -1
  75. package/dist/cjs/messageFormat/po.cjs.map +1 -1
  76. package/dist/cjs/messageFormat/verify-icu-format.cjs.map +1 -1
  77. package/dist/cjs/messageFormat/vue-i18n.cjs.map +1 -1
  78. package/dist/cjs/transpiler/condition/condition.cjs.map +1 -1
  79. package/dist/cjs/transpiler/enumeration/enumeration.cjs.map +1 -1
  80. package/dist/cjs/transpiler/file/file.cjs +2 -3
  81. package/dist/cjs/transpiler/file/file.cjs.map +1 -1
  82. package/dist/cjs/transpiler/file/fileBrowser.cjs.map +1 -1
  83. package/dist/cjs/transpiler/gender/gender.cjs.map +1 -1
  84. package/dist/cjs/transpiler/html/getHTMLCustomComponents.cjs.map +1 -1
  85. package/dist/cjs/transpiler/html/html.cjs.map +1 -1
  86. package/dist/cjs/transpiler/html/htmlTags.cjs.map +1 -1
  87. package/dist/cjs/transpiler/html/validateHTML.cjs.map +1 -1
  88. package/dist/cjs/transpiler/insertion/getInsertionValues.cjs.map +1 -1
  89. package/dist/cjs/transpiler/insertion/insertion.cjs.map +1 -1
  90. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs.map +1 -1
  91. package/dist/cjs/transpiler/markdown/markdown.cjs.map +1 -1
  92. package/dist/cjs/transpiler/markdown/validateMarkdown.cjs.map +1 -1
  93. package/dist/cjs/transpiler/nesting/nesting.cjs.map +1 -1
  94. package/dist/cjs/transpiler/plural/plural.cjs.map +1 -1
  95. package/dist/cjs/transpiler/translation/translation.cjs.map +1 -1
  96. package/dist/cjs/utils/checkIsURLAbsolute.cjs.map +1 -1
  97. package/dist/cjs/utils/getCookie.cjs.map +1 -1
  98. package/dist/cjs/utils/index.cjs +3 -1
  99. package/dist/cjs/utils/intl.cjs.map +1 -1
  100. package/dist/cjs/utils/isSameKeyPath.cjs.map +1 -1
  101. package/dist/cjs/utils/localeStorage.cjs.map +1 -1
  102. package/dist/cjs/utils/parseYaml.cjs.map +1 -1
  103. package/dist/cjs/utils/stringifyYaml.cjs +59 -0
  104. package/dist/cjs/utils/stringifyYaml.cjs.map +1 -0
  105. package/dist/esm/deepTransformPlugins/getFilterMissingTranslationsContent.mjs.map +1 -1
  106. package/dist/esm/deepTransformPlugins/getFilterTranslationsOnlyContent.mjs.map +1 -1
  107. package/dist/esm/deepTransformPlugins/getFilteredLocalesContent.mjs.map +1 -1
  108. package/dist/esm/deepTransformPlugins/getLocalizedContent.mjs.map +1 -1
  109. package/dist/esm/deepTransformPlugins/getMaskContent.mjs.map +1 -1
  110. package/dist/esm/deepTransformPlugins/getMissingLocalesContent.mjs.map +1 -1
  111. package/dist/esm/deepTransformPlugins/getMultilingualDictionary.mjs.map +1 -1
  112. package/dist/esm/deepTransformPlugins/getReplacedValuesContent.mjs.map +1 -1
  113. package/dist/esm/deepTransformPlugins/getSplittedContent.mjs.map +1 -1
  114. package/dist/esm/deepTransformPlugins/insertContentInDictionary.mjs.map +1 -1
  115. package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs +1 -1
  116. package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs.map +1 -1
  117. package/dist/esm/dictionaryManipulator/getContentNodeByKeyPath.mjs.map +1 -1
  118. package/dist/esm/dictionaryManipulator/getDefaultNode.mjs.map +1 -1
  119. package/dist/esm/dictionaryManipulator/getEmptyNode.mjs +1 -1
  120. package/dist/esm/dictionaryManipulator/getEmptyNode.mjs.map +1 -1
  121. package/dist/esm/dictionaryManipulator/getNodeChildren.mjs +2 -1
  122. package/dist/esm/dictionaryManipulator/getNodeChildren.mjs.map +1 -1
  123. package/dist/esm/dictionaryManipulator/getNodeType.mjs.map +1 -1
  124. package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs.map +1 -1
  125. package/dist/esm/dictionaryManipulator/normalizeDictionary.mjs.map +1 -1
  126. package/dist/esm/dictionaryManipulator/orderDictionaries.mjs.map +1 -1
  127. package/dist/esm/dictionaryManipulator/removeContentNodeByKeyPath.mjs.map +1 -1
  128. package/dist/esm/dictionaryManipulator/renameContentNodeByKeyPath.mjs.map +1 -1
  129. package/dist/esm/dictionaryManipulator/updateNodeChildren.mjs.map +1 -1
  130. package/dist/esm/formatters/compact.mjs.map +1 -1
  131. package/dist/esm/formatters/currency.mjs.map +1 -1
  132. package/dist/esm/formatters/date.mjs.map +1 -1
  133. package/dist/esm/formatters/list.mjs.map +1 -1
  134. package/dist/esm/formatters/number.mjs.map +1 -1
  135. package/dist/esm/formatters/percentage.mjs.map +1 -1
  136. package/dist/esm/formatters/relativeTime.mjs.map +1 -1
  137. package/dist/esm/formatters/units.mjs.map +1 -1
  138. package/dist/esm/index.mjs +2 -1
  139. package/dist/esm/interpreter/getCondition.mjs.map +1 -1
  140. package/dist/esm/interpreter/getContent/deepTransform.mjs.map +1 -1
  141. package/dist/esm/interpreter/getContent/getContent.mjs.map +1 -1
  142. package/dist/esm/interpreter/getContent/plugins.mjs +1 -5
  143. package/dist/esm/interpreter/getContent/plugins.mjs.map +1 -1
  144. package/dist/esm/interpreter/getDictionary.mjs.map +1 -1
  145. package/dist/esm/interpreter/getEnumeration.mjs.map +1 -1
  146. package/dist/esm/interpreter/getGender.mjs.map +1 -1
  147. package/dist/esm/interpreter/getHTML.mjs.map +1 -1
  148. package/dist/esm/interpreter/getInsertion.mjs.map +1 -1
  149. package/dist/esm/interpreter/getIntlayer.mjs +10 -18
  150. package/dist/esm/interpreter/getIntlayer.mjs.map +1 -1
  151. package/dist/esm/interpreter/getNesting.mjs.map +1 -1
  152. package/dist/esm/interpreter/getPlural.mjs.map +1 -1
  153. package/dist/esm/interpreter/getTranslation.mjs.map +1 -1
  154. package/dist/esm/interpreter/splitAndJoinInsertion.mjs.map +1 -1
  155. package/dist/esm/localization/generateSitemap.mjs.map +1 -1
  156. package/dist/esm/localization/getBrowserLocale.mjs.map +1 -1
  157. package/dist/esm/localization/getHTMLTextDir.mjs.map +1 -1
  158. package/dist/esm/localization/getLocale.mjs.map +1 -1
  159. package/dist/esm/localization/getLocaleFromPath.mjs.map +1 -1
  160. package/dist/esm/localization/getLocaleLang.mjs.map +1 -1
  161. package/dist/esm/localization/getLocaleName.mjs.map +1 -1
  162. package/dist/esm/localization/getLocalizedUrl.mjs.map +1 -1
  163. package/dist/esm/localization/getMultilingualUrls.mjs.map +1 -1
  164. package/dist/esm/localization/getPathWithoutLocale.mjs.map +1 -1
  165. package/dist/esm/localization/getPrefix.mjs.map +1 -1
  166. package/dist/esm/localization/localeDetector.mjs.map +1 -1
  167. package/dist/esm/localization/localeMapper.mjs.map +1 -1
  168. package/dist/esm/localization/localeResolver.mjs.map +1 -1
  169. package/dist/esm/localization/rewriteUtils.mjs.map +1 -1
  170. package/dist/esm/localization/validatePrefix.mjs.map +1 -1
  171. package/dist/esm/markdown/compiler.mjs.map +1 -1
  172. package/dist/esm/markdown/constants.mjs.map +1 -1
  173. package/dist/esm/markdown/parser.mjs.map +1 -1
  174. package/dist/esm/markdown/renderer.mjs.map +1 -1
  175. package/dist/esm/markdown/utils.mjs.map +1 -1
  176. package/dist/esm/messageFormat/ICU.mjs.map +1 -1
  177. package/dist/esm/messageFormat/i18next.mjs.map +1 -1
  178. package/dist/esm/messageFormat/po.mjs.map +1 -1
  179. package/dist/esm/messageFormat/verify-icu-format.mjs.map +1 -1
  180. package/dist/esm/messageFormat/vue-i18n.mjs.map +1 -1
  181. package/dist/esm/transpiler/condition/condition.mjs.map +1 -1
  182. package/dist/esm/transpiler/enumeration/enumeration.mjs.map +1 -1
  183. package/dist/esm/transpiler/file/file.mjs +2 -3
  184. package/dist/esm/transpiler/file/file.mjs.map +1 -1
  185. package/dist/esm/transpiler/file/fileBrowser.mjs.map +1 -1
  186. package/dist/esm/transpiler/gender/gender.mjs.map +1 -1
  187. package/dist/esm/transpiler/html/getHTMLCustomComponents.mjs.map +1 -1
  188. package/dist/esm/transpiler/html/html.mjs.map +1 -1
  189. package/dist/esm/transpiler/html/htmlTags.mjs.map +1 -1
  190. package/dist/esm/transpiler/html/validateHTML.mjs.map +1 -1
  191. package/dist/esm/transpiler/insertion/getInsertionValues.mjs.map +1 -1
  192. package/dist/esm/transpiler/insertion/insertion.mjs.map +1 -1
  193. package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs.map +1 -1
  194. package/dist/esm/transpiler/markdown/markdown.mjs.map +1 -1
  195. package/dist/esm/transpiler/markdown/validateMarkdown.mjs.map +1 -1
  196. package/dist/esm/transpiler/nesting/nesting.mjs.map +1 -1
  197. package/dist/esm/transpiler/plural/plural.mjs.map +1 -1
  198. package/dist/esm/transpiler/translation/translation.mjs.map +1 -1
  199. package/dist/esm/utils/checkIsURLAbsolute.mjs.map +1 -1
  200. package/dist/esm/utils/getCookie.mjs.map +1 -1
  201. package/dist/esm/utils/index.mjs +2 -1
  202. package/dist/esm/utils/intl.mjs.map +1 -1
  203. package/dist/esm/utils/isSameKeyPath.mjs.map +1 -1
  204. package/dist/esm/utils/localeStorage.mjs.map +1 -1
  205. package/dist/esm/utils/parseYaml.mjs.map +1 -1
  206. package/dist/esm/utils/stringifyYaml.mjs +57 -0
  207. package/dist/esm/utils/stringifyYaml.mjs.map +1 -0
  208. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +11 -12
  209. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts.map +1 -1
  210. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +11 -12
  211. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts.map +1 -1
  212. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +9 -10
  213. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts.map +1 -1
  214. package/dist/types/deepTransformPlugins/getLocalizedContent.d.ts.map +1 -1
  215. package/dist/types/deepTransformPlugins/getMaskContent.d.ts.map +1 -1
  216. package/dist/types/deepTransformPlugins/getMultilingualDictionary.d.ts.map +1 -1
  217. package/dist/types/deepTransformPlugins/getReplacedValuesContent.d.ts.map +1 -1
  218. package/dist/types/deepTransformPlugins/getSplittedContent.d.ts.map +1 -1
  219. package/dist/types/dictionaryManipulator/getEmptyNode.d.ts.map +1 -1
  220. package/dist/types/dictionaryManipulator/getNodeChildren.d.ts.map +1 -1
  221. package/dist/types/dictionaryManipulator/getNodeType.d.ts.map +1 -1
  222. package/dist/types/dictionaryManipulator/mergeDictionaries.d.ts.map +1 -1
  223. package/dist/types/dictionaryManipulator/orderDictionaries.d.ts.map +1 -1
  224. package/dist/types/formatters/compact.d.ts.map +1 -1
  225. package/dist/types/formatters/currency.d.ts.map +1 -1
  226. package/dist/types/formatters/date.d.ts.map +1 -1
  227. package/dist/types/formatters/list.d.ts.map +1 -1
  228. package/dist/types/formatters/relativeTime.d.ts.map +1 -1
  229. package/dist/types/formatters/units.d.ts.map +1 -1
  230. package/dist/types/index.d.ts +2 -1
  231. package/dist/types/interpreter/getContent/deepTransform.d.ts.map +1 -1
  232. package/dist/types/interpreter/getContent/getContent.d.ts.map +1 -1
  233. package/dist/types/interpreter/getContent/plugins.d.ts +3 -3
  234. package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
  235. package/dist/types/interpreter/getEnumeration.d.ts.map +1 -1
  236. package/dist/types/interpreter/getGender.d.ts.map +1 -1
  237. package/dist/types/interpreter/getHTML.d.ts.map +1 -1
  238. package/dist/types/interpreter/getInsertion.d.ts.map +1 -1
  239. package/dist/types/interpreter/getIntlayer.d.ts.map +1 -1
  240. package/dist/types/interpreter/getNesting.d.ts.map +1 -1
  241. package/dist/types/interpreter/getTranslation.d.ts.map +1 -1
  242. package/dist/types/localization/generateSitemap.d.ts.map +1 -1
  243. package/dist/types/localization/getBrowserLocale.d.ts.map +1 -1
  244. package/dist/types/localization/getHTMLTextDir.d.ts.map +1 -1
  245. package/dist/types/localization/getLocaleFromPath.d.ts.map +1 -1
  246. package/dist/types/localization/getLocaleLang.d.ts.map +1 -1
  247. package/dist/types/localization/getLocaleName.d.ts.map +1 -1
  248. package/dist/types/localization/getLocalizedUrl.d.ts.map +1 -1
  249. package/dist/types/localization/getMultilingualUrls.d.ts.map +1 -1
  250. package/dist/types/localization/getPathWithoutLocale.d.ts.map +1 -1
  251. package/dist/types/localization/getPrefix.d.ts.map +1 -1
  252. package/dist/types/localization/localeDetector.d.ts.map +1 -1
  253. package/dist/types/localization/localeMapper.d.ts.map +1 -1
  254. package/dist/types/localization/rewriteUtils.d.ts.map +1 -1
  255. package/dist/types/localization/validatePrefix.d.ts.map +1 -1
  256. package/dist/types/markdown/compiler.d.ts.map +1 -1
  257. package/dist/types/markdown/constants.d.ts.map +1 -1
  258. package/dist/types/markdown/index.d.ts +1 -1
  259. package/dist/types/markdown/types.d.ts.map +1 -1
  260. package/dist/types/markdown/utils.d.ts.map +1 -1
  261. package/dist/types/messageFormat/ICU.d.ts.map +1 -1
  262. package/dist/types/messageFormat/i18next.d.ts.map +1 -1
  263. package/dist/types/messageFormat/po.d.ts.map +1 -1
  264. package/dist/types/messageFormat/vue-i18n.d.ts.map +1 -1
  265. package/dist/types/transpiler/condition/condition.d.ts.map +1 -1
  266. package/dist/types/transpiler/enumeration/enumeration.d.ts.map +1 -1
  267. package/dist/types/transpiler/file/file.d.ts.map +1 -1
  268. package/dist/types/transpiler/file/fileBrowser.d.ts.map +1 -1
  269. package/dist/types/transpiler/gender/gender.d.ts.map +1 -1
  270. package/dist/types/transpiler/html/getHTMLCustomComponents.d.ts.map +1 -1
  271. package/dist/types/transpiler/html/html.d.ts.map +1 -1
  272. package/dist/types/transpiler/html/htmlTags.d.ts.map +1 -1
  273. package/dist/types/transpiler/html/validateHTML.d.ts.map +1 -1
  274. package/dist/types/transpiler/index.d.ts +1 -1
  275. package/dist/types/transpiler/insertion/getInsertionValues.d.ts.map +1 -1
  276. package/dist/types/transpiler/insertion/insertion.d.ts.map +1 -1
  277. package/dist/types/transpiler/markdown/getMarkdownMetadata.d.ts.map +1 -1
  278. package/dist/types/transpiler/markdown/index.d.ts +1 -1
  279. package/dist/types/transpiler/markdown/markdown.d.ts.map +1 -1
  280. package/dist/types/transpiler/markdown/validateMarkdown.d.ts.map +1 -1
  281. package/dist/types/transpiler/nesting/nesting.d.ts.map +1 -1
  282. package/dist/types/transpiler/plural/plural.d.ts.map +1 -1
  283. package/dist/types/utils/checkIsURLAbsolute.d.ts.map +1 -1
  284. package/dist/types/utils/getCookie.d.ts.map +1 -1
  285. package/dist/types/utils/index.d.ts +2 -1
  286. package/dist/types/utils/intl.d.ts.map +1 -1
  287. package/dist/types/utils/isSameKeyPath.d.ts.map +1 -1
  288. package/dist/types/utils/isValidReactElement.d.ts.map +1 -1
  289. package/dist/types/utils/localeStorage.d.ts.map +1 -1
  290. package/dist/types/utils/parseYaml.d.ts.map +1 -1
  291. package/dist/types/utils/stringifyYaml.d.ts +5 -0
  292. package/dist/types/utils/stringifyYaml.d.ts.map +1 -0
  293. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","names":["UNESCAPE_R","CR_NEWLINE_R","FORMFEED_R","TAB_R","HTML_CUSTOM_ATTR_R","CAPTURE_LETTER_AFTER_HYPHEN","ATTRIBUTES_TO_SANITIZE","INTERPOLATION_R","TABLE_RIGHT_ALIGN","TABLE_CENTER_ALIGN","TABLE_LEFT_ALIGN","TABLE_TRIM_PIPES"],"sources":["../../../src/markdown/utils.ts"],"sourcesContent":["import {\n ATTRIBUTES_TO_SANITIZE,\n CAPTURE_LETTER_AFTER_HYPHEN,\n CR_NEWLINE_R,\n DURATION_DELAY_TRIGGER,\n FORMFEED_R,\n HTML_CUSTOM_ATTR_R,\n INTERPOLATION_R,\n TAB_R,\n TABLE_CENTER_ALIGN,\n TABLE_LEFT_ALIGN,\n TABLE_RIGHT_ALIGN,\n TABLE_TRIM_PIPES,\n UNESCAPE_R,\n} from './constants';\nimport type { NestedParser, ParserResult, ParseState, Rule } from './types';\n\n// ============================================================================\n// STRING UTILITIES\n// ============================================================================\n\n/**\n * Trim trailing whitespace from a string.\n */\nexport const trimEnd = (str: string): string => {\n let end = str.length;\n\n while (end > 0 && str[end - 1] <= ' ') end--;\n\n return str.slice(0, end);\n};\n\n/**\n * Check if string starts with prefix.\n */\nexport const startsWith = (str: string, prefix: string): boolean => {\n return str.startsWith(prefix);\n};\n\n/**\n * Remove symmetrical leading and trailing quotes.\n */\nexport const unquote = (str: string): string => {\n const first = str[0];\n\n if (\n (first === '\"' || first === \"'\") &&\n str.length >= 2 &&\n str[str.length - 1] === first\n ) {\n return str.slice(1, -1);\n }\n\n return str;\n};\n\n/**\n * Unescape backslash-escaped characters.\n */\nexport const unescapeString = (rawString: string): string =>\n rawString ? rawString.replace(UNESCAPE_R, '$1') : rawString;\n\n/**\n * Join class names, filtering out falsy values.\n */\nexport const cx = (...args: any[]): string => args.filter(Boolean).join(' ');\n\n/**\n * Get a nested property from an object using dot notation.\n */\nexport const get = (src: any, path: string, fb?: any): any => {\n let ptr = src;\n const frags = path.split('.');\n\n while (frags.length) {\n ptr = ptr[frags[0]];\n\n if (ptr === undefined) break;\n else frags.shift();\n }\n\n return ptr ?? fb;\n};\n\n// ============================================================================\n// SLUGIFY\n// ============================================================================\n\n/**\n * Convert a string to a URL-safe slug.\n * Based on https://stackoverflow.com/a/18123682/1141611\n */\nexport const slugify = (str: string): string =>\n str\n .replace(/[ÀÁÂÃÄÅàáâãä忯]/g, 'a')\n .replace(/[çÇ]/g, 'c')\n .replace(/[ðÐ]/g, 'd')\n .replace(/[ÈÉÊËéèêë]/g, 'e')\n .replace(/[ÏïÎîÍíÌì]/g, 'i')\n .replace(/[Ññ]/g, 'n')\n .replace(/[øØœŒÕõÔôÓóÒò]/g, 'o')\n .replace(/[ÜüÛûÚúÙù]/g, 'u')\n .replace(/[ŸÿÝý]/g, 'y')\n .replace(/[^a-z0-9- ]/gi, '')\n .replace(/ /gi, '-')\n .toLowerCase();\n\n// ============================================================================\n// SANITIZER\n// ============================================================================\n\nconst SANITIZE_R = /(javascript|vbscript|data(?!:image)):/i;\n\n/**\n * Sanitize URLs to prevent XSS attacks.\n * Returns null if the URL is unsafe.\n */\nexport const sanitizer = (input: string): string | null => {\n try {\n const decoded = decodeURIComponent(input).replace(/[^A-Za-z0-9/:]/g, '');\n\n if (SANITIZE_R.test(decoded)) {\n console.warn(\n 'Input contains an unsafe JavaScript/VBScript/data expression, it will not be rendered.',\n decoded\n );\n\n return null;\n }\n } catch (_e) {\n console.warn(\n 'Input could not be decoded due to malformed syntax or characters, it will not be rendered.',\n input\n );\n\n // decodeURIComponent sometimes throws a URIError\n return null;\n }\n\n return input;\n};\n\n// ============================================================================\n// WHITESPACE NORMALIZATION\n// ============================================================================\n\n/**\n * Normalize whitespace in source string.\n */\nexport const normalizeWhitespace = (source: string): string => {\n const start = performance.now();\n const result = source\n .replace(CR_NEWLINE_R, '\\n')\n .replace(FORMFEED_R, '')\n .replace(TAB_R, ' ');\n\n const duration = performance.now() - start;\n\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `normalizeWhitespace: ${duration.toFixed(3)}ms, source length: ${source.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Safely remove a uniform leading indentation from lines, but do NOT touch\n * the content inside fenced code blocks (``` or ~~~).\n */\nexport const trimLeadingWhitespaceOutsideFences = (\n text: string,\n whitespace: string\n): string => {\n const start = performance.now();\n if (!whitespace) return text;\n\n const lines = text.split('\\n');\n let inFence = false;\n let fenceToken: string | null = null;\n\n const isFenceLine = (line: string): RegExpMatchArray | null =>\n line.match(/^\\s*(`{3,}|~{3,})/);\n\n const maybeToggleFence = (line: string): void => {\n const m = isFenceLine(line);\n\n if (!m) return;\n\n const token = m[1];\n\n if (!inFence) {\n inFence = true;\n fenceToken = token;\n } else if (fenceToken && line.includes(fenceToken)) {\n inFence = false;\n fenceToken = null;\n }\n };\n\n const out = lines.map((line) => {\n const fenceMatch = isFenceLine(line);\n if (fenceMatch) {\n const trimmedFenceLine = line.startsWith(whitespace)\n ? line.slice(whitespace.length)\n : line;\n maybeToggleFence(line);\n return trimmedFenceLine;\n }\n\n if (inFence) {\n return line;\n }\n\n return line.startsWith(whitespace) ? line.slice(whitespace.length) : line;\n });\n\n const result = out.join('\\n');\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `trimLeadingWhitespaceOutsideFences: ${duration.toFixed(3)}ms, text length: ${text.length}, lines count: ${lines.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Normalize HTML attribute key to JSX prop name.\n */\nexport const normalizeAttributeKey = (key: string): string => {\n const hyphenIndex = key.indexOf('-');\n\n if (hyphenIndex !== -1 && key.match(HTML_CUSTOM_ATTR_R) === null) {\n key = key.replace(CAPTURE_LETTER_AFTER_HYPHEN, (_, letter) => {\n return letter.toUpperCase();\n });\n }\n\n return key;\n};\n\ntype StyleTuple = [key: string, value: string];\n\n/**\n * Parse a CSS style string into an array of [key, value] tuples.\n */\nexport const parseStyleAttribute = (styleString: string): StyleTuple[] => {\n const start = performance.now();\n const styles: StyleTuple[] = [];\n let buffer = '';\n let inUrl = false;\n let inQuotes = false;\n let quoteChar: '\"' | \"'\" | '' = '';\n\n if (!styleString) return styles;\n\n for (let i = 0; i < styleString.length; i++) {\n const char = styleString[i];\n\n if ((char === '\"' || char === \"'\") && !inUrl) {\n if (!inQuotes) {\n inQuotes = true;\n quoteChar = char;\n } else if (char === quoteChar) {\n inQuotes = false;\n quoteChar = '';\n }\n }\n\n if (char === '(' && buffer.endsWith('url')) {\n inUrl = true;\n } else if (char === ')' && inUrl) {\n inUrl = false;\n }\n\n if (char === ';' && !inQuotes && !inUrl) {\n const declaration = buffer.trim();\n\n if (declaration) {\n const colonIndex = declaration.indexOf(':');\n\n if (colonIndex > 0) {\n const key = declaration.slice(0, colonIndex).trim();\n const value = declaration.slice(colonIndex + 1).trim();\n styles.push([key, value]);\n }\n }\n buffer = '';\n } else {\n buffer += char;\n }\n }\n\n const declaration = buffer.trim();\n\n if (declaration) {\n const colonIndex = declaration.indexOf(':');\n if (colonIndex > 0) {\n const key = declaration.slice(0, colonIndex).trim();\n const value = declaration.slice(colonIndex + 1).trim();\n styles.push([key, value]);\n }\n }\n\n const duration = performance.now() - start;\n\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseStyleAttribute: ${duration.toFixed(3)}ms, styleString length: ${styleString.length}, styles count: ${styles.length}`\n );\n }\n\n return styles;\n};\n\n/**\n * Convert an attribute value to a Node prop value.\n */\nexport const attributeValueToNodePropValue = (\n tag: string,\n key: string,\n value: string,\n sanitizeUrlFn: (\n value: string,\n tag: string,\n attribute: string\n ) => string | null\n): any => {\n if (key === 'style') {\n return parseStyleAttribute(value).reduce(\n (styles, [styleKey, styleValue]) => {\n const camelCasedKey = styleKey.replace(/(-[a-z])/g, (substr) =>\n substr[1].toUpperCase()\n );\n\n (styles as Record<string, any>)[camelCasedKey] = sanitizeUrlFn(\n styleValue,\n tag,\n styleKey\n );\n\n return styles;\n },\n {} as Record<string, any>\n );\n } else if (ATTRIBUTES_TO_SANITIZE.indexOf(key) !== -1) {\n return sanitizeUrlFn(unescapeString(value), tag, key);\n } else if (value.match(INTERPOLATION_R)) {\n value = unescapeString(value.slice(1, value.length - 1));\n }\n\n if (value === 'true') {\n return true;\n } else if (value === 'false') {\n return false;\n }\n\n return value;\n};\n\n// ============================================================================\n// TABLE PARSING\n// ============================================================================\n\n/**\n * Parse table alignment from a separator row.\n */\nexport const parseTableAlignCapture = (\n alignCapture: string\n): 'left' | 'right' | 'center' => {\n if (TABLE_RIGHT_ALIGN.test(alignCapture)) {\n return 'right';\n } else if (TABLE_CENTER_ALIGN.test(alignCapture)) {\n return 'center';\n } else if (TABLE_LEFT_ALIGN.test(alignCapture)) {\n return 'left';\n }\n\n return 'left';\n};\n\n/**\n * Parse table alignment row.\n */\nexport const parseTableAlign = (\n source: string\n): ('left' | 'right' | 'center')[] => {\n const alignText = source.replace(TABLE_TRIM_PIPES, '').split('|');\n return alignText.map(parseTableAlignCapture);\n};\n\n/**\n * Parse a single table row.\n */\nexport const parseTableRow = (\n source: string,\n parse: NestedParser,\n state: ParseState,\n tableOutput: boolean\n): ParserResult[][] => {\n const start = performance.now();\n const prevInTable = state.inTable;\n\n state.inTable = true;\n\n const cells: ParserResult[][] = [[]];\n let acc = '';\n\n const flush = (): void => {\n if (!acc) return;\n\n const cell = cells[cells.length - 1];\n cell.push.apply(cell, parse(acc, state));\n acc = '';\n };\n\n source\n .trim()\n .split(/(`[^`]*`|\\\\\\||\\|)/)\n .filter(Boolean)\n .forEach((fragment, i, arr) => {\n if (fragment.trim() === '|') {\n flush();\n\n if (tableOutput) {\n if (i !== 0 && i !== arr.length - 1) {\n cells.push([]);\n }\n\n return;\n }\n }\n\n acc += fragment;\n });\n\n flush();\n\n state.inTable = prevInTable;\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseTableRow: ${duration.toFixed(3)}ms, source length: ${source.length}, cells count: ${cells.length}`\n );\n }\n\n return cells;\n};\n\n/**\n * Parse table cells (multiple rows).\n */\nexport const parseTableCells = (\n source: string,\n parse: NestedParser,\n state: ParseState\n): ParserResult[][][] => {\n const start = performance.now();\n const rowsText = source.trim().split('\\n');\n\n const result = rowsText.map((rowText) =>\n parseTableRow(rowText, parse, state, true)\n );\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseTableCells: ${duration.toFixed(3)}ms, source length: ${source.length}, rows count: ${rowsText.length}`\n );\n }\n\n return result;\n};\n\n// ============================================================================\n// PARSING HELPERS\n// ============================================================================\n\n/**\n * Check if a rule qualifies for the current source and state.\n */\nexport const qualifies = (\n source: string,\n state: ParseState,\n qualify: NonNullable<Rule<any>['_qualify']>\n): boolean => {\n if (Array.isArray(qualify)) {\n for (let i = 0; i < qualify.length; i++) {\n if (startsWith(source, qualify[i])) return true;\n }\n\n return false;\n }\n\n return (qualify as (source: string, state: ParseState) => boolean)(\n source,\n state\n );\n};\n\n/**\n * Marks a matcher function as eligible for being run inside an inline context.\n */\nexport const allowInline = <T extends (...args: any[]) => any>(\n fn: T\n): T & { inline: 1 } => {\n (fn as any).inline = 1;\n return fn as T & { inline: 1 };\n};\n\n/**\n * Creates a match function for an inline scoped element from a regex.\n */\nexport const inlineRegex = (regex: RegExp) =>\n allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n if (state.inline) {\n return regex.exec(source);\n } else {\n return null;\n }\n });\n\n/**\n * Creates a match function for inline elements except links.\n */\nexport const simpleInlineRegex = (regex: RegExp) =>\n allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n if (state.inline || state.simple) {\n return regex.exec(source);\n } else {\n return null;\n }\n });\n\n/**\n * Creates a match function for a block scoped element from a regex.\n */\nexport const blockRegex =\n (regex: RegExp) =>\n (source: string, state: ParseState): RegExpMatchArray | null => {\n if (state.inline || state.simple) {\n return null;\n } else {\n return regex.exec(source);\n }\n };\n\n/**\n * Creates a match function from a regex, ignoring block/inline scope.\n */\nexport const anyScopeRegex = (\n fn: RegExp | ((source: string, state: ParseState) => RegExpMatchArray | null)\n) =>\n allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n if (typeof fn === 'function') {\n return fn(source, state);\n }\n return fn.exec(source);\n });\n\n/**\n * Parse inline content (including links).\n */\nexport const parseInline = (\n parse: NestedParser,\n children: string,\n state: ParseState\n): ParserResult[] => {\n const start = performance.now();\n const isCurrentlyInline = state.inline ?? false;\n const isCurrentlySimple = state.simple ?? false;\n state.inline = true;\n state.simple = true;\n const result = parse(children, state);\n state.inline = isCurrentlyInline;\n state.simple = isCurrentlySimple;\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseInline: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Parse simple inline content (no links).\n */\nexport const parseSimpleInline = (\n parse: NestedParser,\n children: string,\n state: ParseState\n): ParserResult[] => {\n const start = performance.now();\n const isCurrentlyInline = state.inline ?? false;\n const isCurrentlySimple = state.simple ?? false;\n\n state.inline = false;\n state.simple = true;\n const result = parse(children, state);\n state.inline = isCurrentlyInline;\n state.simple = isCurrentlySimple;\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseSimpleInline: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Parse block content.\n */\nexport const parseBlock = (\n parse: NestedParser,\n children: string,\n state: ParseState = {}\n): ParserResult[] => {\n const start = performance.now();\n const isCurrentlyInline = state.inline || false;\n state.inline = false;\n const normalizedChildren = trimEnd(children);\n const needsTerminator = /\\n\\n$/.test(normalizedChildren) === false;\n const blockInput = needsTerminator\n ? normalizedChildren.endsWith('\\n')\n ? `${normalizedChildren}\\n`\n : `${normalizedChildren}\\n\\n`\n : normalizedChildren;\n\n const result = parse(blockInput, state);\n state.inline = isCurrentlyInline;\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseBlock: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Helper to parse capture group 2 as inline content.\n */\nexport const parseCaptureInline = (\n capture: RegExpMatchArray,\n parse: NestedParser,\n state: ParseState\n): { children: ParserResult[] } => {\n return {\n children: parseInline(parse, capture[2], state),\n };\n};\n\n/**\n * Helper that captures nothing (empty object).\n */\nexport const captureNothing = (): Record<string, never> => ({});\n\n/**\n * Helper that renders nothing (null).\n */\nexport const renderNothing = (): null => null;\n\n/**\n * Check if any regex in a list matches the input.\n */\nexport const some = (regexes: RegExp[], input: string): boolean => {\n for (let i = 0; i < regexes.length; i++) {\n if (regexes[i].test(input)) {\n return true;\n }\n }\n return false;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"utils.cjs","names":["UNESCAPE_R","CR_NEWLINE_R","FORMFEED_R","TAB_R","HTML_CUSTOM_ATTR_R","CAPTURE_LETTER_AFTER_HYPHEN","ATTRIBUTES_TO_SANITIZE","INTERPOLATION_R","TABLE_RIGHT_ALIGN","TABLE_CENTER_ALIGN","TABLE_LEFT_ALIGN","TABLE_TRIM_PIPES"],"sources":["../../../src/markdown/utils.ts"],"sourcesContent":["import {\n ATTRIBUTES_TO_SANITIZE,\n CAPTURE_LETTER_AFTER_HYPHEN,\n CR_NEWLINE_R,\n DURATION_DELAY_TRIGGER,\n FORMFEED_R,\n HTML_CUSTOM_ATTR_R,\n INTERPOLATION_R,\n TAB_R,\n TABLE_CENTER_ALIGN,\n TABLE_LEFT_ALIGN,\n TABLE_RIGHT_ALIGN,\n TABLE_TRIM_PIPES,\n UNESCAPE_R,\n} from './constants';\nimport type { NestedParser, ParserResult, ParseState, Rule } from './types';\n\n// ============================================================================\n// STRING UTILITIES\n// ============================================================================\n\n/**\n * Trim trailing whitespace from a string.\n */\nexport const trimEnd = (str: string): string => {\n let end = str.length;\n\n while (end > 0 && str[end - 1] <= ' ') end--;\n\n return str.slice(0, end);\n};\n\n/**\n * Check if string starts with prefix.\n */\nexport const startsWith = (str: string, prefix: string): boolean => {\n return str.startsWith(prefix);\n};\n\n/**\n * Remove symmetrical leading and trailing quotes.\n */\nexport const unquote = (str: string): string => {\n const first = str[0];\n\n if (\n (first === '\"' || first === \"'\") &&\n str.length >= 2 &&\n str[str.length - 1] === first\n ) {\n return str.slice(1, -1);\n }\n\n return str;\n};\n\n/**\n * Unescape backslash-escaped characters.\n */\nexport const unescapeString = (rawString: string): string =>\n rawString ? rawString.replace(UNESCAPE_R, '$1') : rawString;\n\n/**\n * Join class names, filtering out falsy values.\n */\nexport const cx = (...args: any[]): string => args.filter(Boolean).join(' ');\n\n/**\n * Get a nested property from an object using dot notation.\n */\nexport const get = (src: any, path: string, fb?: any): any => {\n let ptr = src;\n const frags = path.split('.');\n\n while (frags.length) {\n ptr = ptr[frags[0]];\n\n if (ptr === undefined) break;\n else frags.shift();\n }\n\n return ptr ?? fb;\n};\n\n// ============================================================================\n// SLUGIFY\n// ============================================================================\n\n/**\n * Convert a string to a URL-safe slug.\n * Based on https://stackoverflow.com/a/18123682/1141611\n */\nexport const slugify = (str: string): string =>\n str\n .replace(/[ÀÁÂÃÄÅàáâãä忯]/g, 'a')\n .replace(/[çÇ]/g, 'c')\n .replace(/[ðÐ]/g, 'd')\n .replace(/[ÈÉÊËéèêë]/g, 'e')\n .replace(/[ÏïÎîÍíÌì]/g, 'i')\n .replace(/[Ññ]/g, 'n')\n .replace(/[øØœŒÕõÔôÓóÒò]/g, 'o')\n .replace(/[ÜüÛûÚúÙù]/g, 'u')\n .replace(/[ŸÿÝý]/g, 'y')\n .replace(/[^a-z0-9- ]/gi, '')\n .replace(/ /gi, '-')\n .toLowerCase();\n\n// ============================================================================\n// SANITIZER\n// ============================================================================\n\nconst SANITIZE_R = /(javascript|vbscript|data(?!:image)):/i;\n\n/**\n * Sanitize URLs to prevent XSS attacks.\n * Returns null if the URL is unsafe.\n */\nexport const sanitizer = (input: string): string | null => {\n try {\n const decoded = decodeURIComponent(input).replace(/[^A-Za-z0-9/:]/g, '');\n\n if (SANITIZE_R.test(decoded)) {\n console.warn(\n 'Input contains an unsafe JavaScript/VBScript/data expression, it will not be rendered.',\n decoded\n );\n\n return null;\n }\n } catch (_e) {\n console.warn(\n 'Input could not be decoded due to malformed syntax or characters, it will not be rendered.',\n input\n );\n\n // decodeURIComponent sometimes throws a URIError\n return null;\n }\n\n return input;\n};\n\n// ============================================================================\n// WHITESPACE NORMALIZATION\n// ============================================================================\n\n/**\n * Normalize whitespace in source string.\n */\nexport const normalizeWhitespace = (source: string): string => {\n const start = performance.now();\n const result = source\n .replace(CR_NEWLINE_R, '\\n')\n .replace(FORMFEED_R, '')\n .replace(TAB_R, ' ');\n\n const duration = performance.now() - start;\n\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `normalizeWhitespace: ${duration.toFixed(3)}ms, source length: ${source.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Safely remove a uniform leading indentation from lines, but do NOT touch\n * the content inside fenced code blocks (``` or ~~~).\n */\nexport const trimLeadingWhitespaceOutsideFences = (\n text: string,\n whitespace: string\n): string => {\n const start = performance.now();\n if (!whitespace) return text;\n\n const lines = text.split('\\n');\n let inFence = false;\n let fenceToken: string | null = null;\n\n const isFenceLine = (line: string): RegExpMatchArray | null =>\n line.match(/^\\s*(`{3,}|~{3,})/);\n\n const maybeToggleFence = (line: string): void => {\n const m = isFenceLine(line);\n\n if (!m) return;\n\n const token = m[1];\n\n if (!inFence) {\n inFence = true;\n fenceToken = token;\n } else if (fenceToken && line.includes(fenceToken)) {\n inFence = false;\n fenceToken = null;\n }\n };\n\n const out = lines.map((line) => {\n const fenceMatch = isFenceLine(line);\n if (fenceMatch) {\n const trimmedFenceLine = line.startsWith(whitespace)\n ? line.slice(whitespace.length)\n : line;\n maybeToggleFence(line);\n return trimmedFenceLine;\n }\n\n if (inFence) {\n return line;\n }\n\n return line.startsWith(whitespace) ? line.slice(whitespace.length) : line;\n });\n\n const result = out.join('\\n');\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `trimLeadingWhitespaceOutsideFences: ${duration.toFixed(3)}ms, text length: ${text.length}, lines count: ${lines.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Normalize HTML attribute key to JSX prop name.\n */\nexport const normalizeAttributeKey = (key: string): string => {\n const hyphenIndex = key.indexOf('-');\n\n if (hyphenIndex !== -1 && key.match(HTML_CUSTOM_ATTR_R) === null) {\n key = key.replace(CAPTURE_LETTER_AFTER_HYPHEN, (_, letter) => {\n return letter.toUpperCase();\n });\n }\n\n return key;\n};\n\ntype StyleTuple = [key: string, value: string];\n\n/**\n * Parse a CSS style string into an array of [key, value] tuples.\n */\nexport const parseStyleAttribute = (styleString: string): StyleTuple[] => {\n const start = performance.now();\n const styles: StyleTuple[] = [];\n let buffer = '';\n let inUrl = false;\n let inQuotes = false;\n let quoteChar: '\"' | \"'\" | '' = '';\n\n if (!styleString) return styles;\n\n for (let i = 0; i < styleString.length; i++) {\n const char = styleString[i];\n\n if ((char === '\"' || char === \"'\") && !inUrl) {\n if (!inQuotes) {\n inQuotes = true;\n quoteChar = char;\n } else if (char === quoteChar) {\n inQuotes = false;\n quoteChar = '';\n }\n }\n\n if (char === '(' && buffer.endsWith('url')) {\n inUrl = true;\n } else if (char === ')' && inUrl) {\n inUrl = false;\n }\n\n if (char === ';' && !inQuotes && !inUrl) {\n const declaration = buffer.trim();\n\n if (declaration) {\n const colonIndex = declaration.indexOf(':');\n\n if (colonIndex > 0) {\n const key = declaration.slice(0, colonIndex).trim();\n const value = declaration.slice(colonIndex + 1).trim();\n styles.push([key, value]);\n }\n }\n buffer = '';\n } else {\n buffer += char;\n }\n }\n\n const declaration = buffer.trim();\n\n if (declaration) {\n const colonIndex = declaration.indexOf(':');\n if (colonIndex > 0) {\n const key = declaration.slice(0, colonIndex).trim();\n const value = declaration.slice(colonIndex + 1).trim();\n styles.push([key, value]);\n }\n }\n\n const duration = performance.now() - start;\n\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseStyleAttribute: ${duration.toFixed(3)}ms, styleString length: ${styleString.length}, styles count: ${styles.length}`\n );\n }\n\n return styles;\n};\n\n/**\n * Convert an attribute value to a Node prop value.\n */\nexport const attributeValueToNodePropValue = (\n tag: string,\n key: string,\n value: string,\n sanitizeUrlFn: (\n value: string,\n tag: string,\n attribute: string\n ) => string | null\n): any => {\n if (key === 'style') {\n return parseStyleAttribute(value).reduce(\n (styles, [styleKey, styleValue]) => {\n const camelCasedKey = styleKey.replace(/(-[a-z])/g, (substr) =>\n substr[1].toUpperCase()\n );\n\n (styles as Record<string, any>)[camelCasedKey] = sanitizeUrlFn(\n styleValue,\n tag,\n styleKey\n );\n\n return styles;\n },\n {} as Record<string, any>\n );\n } else if (ATTRIBUTES_TO_SANITIZE.indexOf(key) !== -1) {\n return sanitizeUrlFn(unescapeString(value), tag, key);\n } else if (value.match(INTERPOLATION_R)) {\n value = unescapeString(value.slice(1, value.length - 1));\n }\n\n if (value === 'true') {\n return true;\n } else if (value === 'false') {\n return false;\n }\n\n return value;\n};\n\n// ============================================================================\n// TABLE PARSING\n// ============================================================================\n\n/**\n * Parse table alignment from a separator row.\n */\nexport const parseTableAlignCapture = (\n alignCapture: string\n): 'left' | 'right' | 'center' => {\n if (TABLE_RIGHT_ALIGN.test(alignCapture)) {\n return 'right';\n } else if (TABLE_CENTER_ALIGN.test(alignCapture)) {\n return 'center';\n } else if (TABLE_LEFT_ALIGN.test(alignCapture)) {\n return 'left';\n }\n\n return 'left';\n};\n\n/**\n * Parse table alignment row.\n */\nexport const parseTableAlign = (\n source: string\n): ('left' | 'right' | 'center')[] => {\n const alignText = source.replace(TABLE_TRIM_PIPES, '').split('|');\n return alignText.map(parseTableAlignCapture);\n};\n\n/**\n * Parse a single table row.\n */\nexport const parseTableRow = (\n source: string,\n parse: NestedParser,\n state: ParseState,\n tableOutput: boolean\n): ParserResult[][] => {\n const start = performance.now();\n const prevInTable = state.inTable;\n\n state.inTable = true;\n\n const cells: ParserResult[][] = [[]];\n let acc = '';\n\n const flush = (): void => {\n if (!acc) return;\n\n const cell = cells[cells.length - 1];\n cell.push.apply(cell, parse(acc, state));\n acc = '';\n };\n\n source\n .trim()\n .split(/(`[^`]*`|\\\\\\||\\|)/)\n .filter(Boolean)\n .forEach((fragment, i, arr) => {\n if (fragment.trim() === '|') {\n flush();\n\n if (tableOutput) {\n if (i !== 0 && i !== arr.length - 1) {\n cells.push([]);\n }\n\n return;\n }\n }\n\n acc += fragment;\n });\n\n flush();\n\n state.inTable = prevInTable;\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseTableRow: ${duration.toFixed(3)}ms, source length: ${source.length}, cells count: ${cells.length}`\n );\n }\n\n return cells;\n};\n\n/**\n * Parse table cells (multiple rows).\n */\nexport const parseTableCells = (\n source: string,\n parse: NestedParser,\n state: ParseState\n): ParserResult[][][] => {\n const start = performance.now();\n const rowsText = source.trim().split('\\n');\n\n const result = rowsText.map((rowText) =>\n parseTableRow(rowText, parse, state, true)\n );\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseTableCells: ${duration.toFixed(3)}ms, source length: ${source.length}, rows count: ${rowsText.length}`\n );\n }\n\n return result;\n};\n\n// ============================================================================\n// PARSING HELPERS\n// ============================================================================\n\n/**\n * Check if a rule qualifies for the current source and state.\n */\nexport const qualifies = (\n source: string,\n state: ParseState,\n qualify: NonNullable<Rule<any>['_qualify']>\n): boolean => {\n if (Array.isArray(qualify)) {\n for (let i = 0; i < qualify.length; i++) {\n if (startsWith(source, qualify[i])) return true;\n }\n\n return false;\n }\n\n return (qualify as (source: string, state: ParseState) => boolean)(\n source,\n state\n );\n};\n\n/**\n * Marks a matcher function as eligible for being run inside an inline context.\n */\nexport const allowInline = <T extends (...args: any[]) => any>(\n fn: T\n): T & { inline: 1 } => {\n (fn as any).inline = 1;\n return fn as T & { inline: 1 };\n};\n\n/**\n * Creates a match function for an inline scoped element from a regex.\n */\nexport const inlineRegex = (regex: RegExp) =>\n allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n if (state.inline) {\n return regex.exec(source);\n } else {\n return null;\n }\n });\n\n/**\n * Creates a match function for inline elements except links.\n */\nexport const simpleInlineRegex = (regex: RegExp) =>\n allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n if (state.inline || state.simple) {\n return regex.exec(source);\n } else {\n return null;\n }\n });\n\n/**\n * Creates a match function for a block scoped element from a regex.\n */\nexport const blockRegex =\n (regex: RegExp) =>\n (source: string, state: ParseState): RegExpMatchArray | null => {\n if (state.inline || state.simple) {\n return null;\n } else {\n return regex.exec(source);\n }\n };\n\n/**\n * Creates a match function from a regex, ignoring block/inline scope.\n */\nexport const anyScopeRegex = (\n fn: RegExp | ((source: string, state: ParseState) => RegExpMatchArray | null)\n) =>\n allowInline((source: string, state: ParseState): RegExpMatchArray | null => {\n if (typeof fn === 'function') {\n return fn(source, state);\n }\n return fn.exec(source);\n });\n\n/**\n * Parse inline content (including links).\n */\nexport const parseInline = (\n parse: NestedParser,\n children: string,\n state: ParseState\n): ParserResult[] => {\n const start = performance.now();\n const isCurrentlyInline = state.inline ?? false;\n const isCurrentlySimple = state.simple ?? false;\n state.inline = true;\n state.simple = true;\n const result = parse(children, state);\n state.inline = isCurrentlyInline;\n state.simple = isCurrentlySimple;\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseInline: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Parse simple inline content (no links).\n */\nexport const parseSimpleInline = (\n parse: NestedParser,\n children: string,\n state: ParseState\n): ParserResult[] => {\n const start = performance.now();\n const isCurrentlyInline = state.inline ?? false;\n const isCurrentlySimple = state.simple ?? false;\n\n state.inline = false;\n state.simple = true;\n const result = parse(children, state);\n state.inline = isCurrentlyInline;\n state.simple = isCurrentlySimple;\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseSimpleInline: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Parse block content.\n */\nexport const parseBlock = (\n parse: NestedParser,\n children: string,\n state: ParseState = {}\n): ParserResult[] => {\n const start = performance.now();\n const isCurrentlyInline = state.inline || false;\n state.inline = false;\n const normalizedChildren = trimEnd(children);\n const needsTerminator = /\\n\\n$/.test(normalizedChildren) === false;\n const blockInput = needsTerminator\n ? normalizedChildren.endsWith('\\n')\n ? `${normalizedChildren}\\n`\n : `${normalizedChildren}\\n\\n`\n : normalizedChildren;\n\n const result = parse(blockInput, state);\n state.inline = isCurrentlyInline;\n\n const duration = performance.now() - start;\n if (duration > DURATION_DELAY_TRIGGER) {\n console.log(\n `parseBlock: ${duration.toFixed(3)}ms, children length: ${children.length}, result count: ${result.length}`\n );\n }\n\n return result;\n};\n\n/**\n * Helper to parse capture group 2 as inline content.\n */\nexport const parseCaptureInline = (\n capture: RegExpMatchArray,\n parse: NestedParser,\n state: ParseState\n): { children: ParserResult[] } => {\n return {\n children: parseInline(parse, capture[2], state),\n };\n};\n\n/**\n * Helper that captures nothing (empty object).\n */\nexport const captureNothing = (): Record<string, never> => ({});\n\n/**\n * Helper that renders nothing (null).\n */\nexport const renderNothing = (): null => null;\n\n/**\n * Check if any regex in a list matches the input.\n */\nexport const some = (regexes: RegExp[], input: string): boolean => {\n for (let i = 0; i < regexes.length; i++) {\n if (regexes[i].test(input)) {\n return true;\n }\n }\n return false;\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ICU.cjs","names":["html","insert","enu","plural","gender","NodeTypes","deepTransformNode"],"sources":["../../../src/messageFormat/ICU.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\n\n/**\n * ICU MessageFormat Converter\n *\n * This module converts between ICU MessageFormat and Intlayer's internal format.\n *\n * IMPORTANT: Two different formats are used:\n *\n * 1. ICU MessageFormat (external format):\n * - Simple variables: {name}\n * - Formatted variables: {amount, number, currency}\n * - Plural: {count, plural, =0 {none} other {# items}}\n * - Select: {gender, select, male {He} female {She} other {They}}\n *\n * 2. Intlayer Internal Format:\n * - Simple variables: {{name}} (double braces for clarity and to distinguish from literal text)\n * - Formatted variables: {amount, number, currency} (keeps ICU format)\n * - Plural: enu({ 0: 'none', fallback: '{{count}} items' })\n * - Select/Gender: gender({ male: 'He', female: 'She', fallback: 'They' })\n *\n * Conversion flow:\n * - ICU → Intlayer: {name} → {{name}}\n * - Intlayer → ICU: {{name}} → {name}\n *\n * The double braces in Intlayer format serve to:\n * - Distinguish variables from literal text containing braces\n * - Work with getInsertion() runtime function which expects {{var}} patterns\n * - Provide clear visual distinction in content dictionaries\n */\n\n// Types for our AST\ntype ICUNode =\n | string\n | {\n type: 'argument';\n name: string;\n format?: { type: string; style?: string };\n }\n | { type: 'plural'; name: string; options: Record<string, ICUNode[]> }\n | { type: 'select'; name: string; options: Record<string, ICUNode[]> };\n\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\n\nconst parseICU = (text: string): ICUNode[] => {\n let index = 0;\n\n const parseNodes = (): ICUNode[] => {\n const nodes: ICUNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n nodes.push(parseArgument());\n } else if (char === '}') {\n // End of current block\n break;\n } else if (char === \"'\") {\n // Escaping\n if (index + 1 < text.length && text[index + 1] === \"'\") {\n currentText += \"'\";\n index += 2;\n } else {\n // Find next quote\n const nextQuote = text.indexOf(\"'\", index + 1);\n if (nextQuote !== -1) {\n // Determine if this is escaping syntax characters\n // For simplicity, we'll treat content between single quotes as literal\n // provided it contains syntax chars.\n // Standard ICU: ' quoted string '\n // If it is just an apostrophe, it should be doubled.\n // But simplified: take content between quotes literally.\n currentText += text.substring(index + 1, nextQuote);\n index = nextQuote + 1;\n } else {\n currentText += \"'\";\n index++;\n }\n }\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n return nodes;\n };\n\n const parseArgument = (): ICUNode => {\n // We are past '{'\n // Parse name\n let name = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n name += text[index];\n index++;\n }\n name = name.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name };\n }\n\n // Must be comma\n if (text[index] === ',') {\n index++;\n // Parse type\n let type = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n type += text[index];\n index++;\n }\n type = type.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name, format: { type } };\n }\n\n if (text[index] === ',') {\n index++;\n\n // If plural or select, parse options\n if (type === 'plural' || type === 'select') {\n // Parse options\n const options: Record<string, ICUNode[]> = {};\n\n while (index < text.length && text[index] !== '}') {\n // skip whitespace\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n // parse key\n let key = '';\n while (index < text.length && /[^{\\s]/.test(text[index])) {\n key += text[index];\n index++;\n }\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n if (text[index] !== '{')\n throw new Error('Expected { after option key');\n index++; // skip {\n\n const value = parseNodes();\n\n if (text[index] !== '}')\n throw new Error('Expected } after option value');\n index++; // skip }\n\n options[key] = value;\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n }\n\n index++; // skip closing argument }\n\n if (type === 'plural') {\n return { type: 'plural', name, options };\n } else if (type === 'select') {\n return { type: 'select', name, options };\n }\n } else {\n // Parse style for number/date/time\n let style = '';\n while (index < text.length && text[index] !== '}') {\n style += text[index];\n index++;\n }\n if (index >= text.length) throw new Error('Unclosed argument');\n\n style = style.trim();\n index++; // skip }\n\n return { type: 'argument', name, format: { type, style } };\n }\n }\n }\n\n throw new Error('Malformed argument');\n };\n\n return parseNodes();\n};\n\nconst icuNodesToIntlayer = (nodes: ICUNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') {\n const node = nodes[0];\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n // Check if we can flatten to a single string (insert)\n const canFlatten = nodes.every(\n (node) => typeof node === 'string' || node.type === 'argument'\n );\n if (canFlatten) {\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else if (typeof node !== 'string' && node.type === 'argument') {\n if (node.format) {\n // Formatted variables keep ICU format: {var, type, style}\n str += `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`;\n } else {\n // Simple variables use Intlayer format: {{var}}\n str += `{{${node.name}}}`;\n }\n }\n }\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(str)) {\n return html(str);\n }\n return insert(str);\n }\n\n // Mix of string and complex types.\n // If we have just one complex type and it covers everything?\n if (nodes.length === 1) {\n const node = nodes[0];\n\n if (typeof node === 'string') {\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n if (node.type === 'argument') {\n if (node.format) {\n return insert(\n `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`\n );\n }\n return insert(`{{${node.name}}}`);\n }\n if (node.type === 'plural') {\n const options: Record<string, any> = {};\n let hasExactMatch = false;\n\n for (const key of Object.keys(node.options)) {\n if (key.startsWith('=')) {\n hasExactMatch = true;\n break;\n }\n }\n\n if (hasExactMatch) {\n for (const [key, val] of Object.entries(node.options)) {\n // Map ICU keys to Intlayer keys\n let newKey = key;\n if (key.startsWith('=')) {\n newKey = key.substring(1); // =0 -> 0\n } else if (key === 'one') {\n newKey = '1';\n } else if (key === 'two') {\n newKey = '2';\n } else if (key === 'few') {\n newKey = '<=3';\n } else if (key === 'many') {\n newKey = '>=4';\n } else if (key === 'other') {\n newKey = 'fallback';\n }\n // Handle # in plural value\n // For plural, we need to pass the variable name down or replace #\n // Intlayer uses {{n}} (or whatever var name) for simple variables\n // We should replace # with {{n}} in the string parts of val\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[newKey] = icuNodesToIntlayer(replacedVal);\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n } else {\n for (const [key, val] of Object.entries(node.options)) {\n // Handle # in plural value\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[key] = icuNodesToIntlayer(replacedVal);\n }\n\n return plural(options as any);\n }\n }\n if (node.type === 'select') {\n const options: Record<string, any> = {};\n\n for (const [key, val] of Object.entries(node.options)) {\n options[key] = icuNodesToIntlayer(val);\n }\n\n // Check if it looks like gender\n const optionKeys = Object.keys(options);\n // It is gender if it has 'male' OR 'female' AND only contains gender keys (male, female, other)\n const isGender =\n (options.male || options.female) &&\n optionKeys.every((k) =>\n ['male', 'female', 'other', 'fallback'].includes(k)\n );\n\n if (isGender) {\n return gender({\n fallback: options.other,\n male: options.male,\n female: options.female,\n });\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n }\n\n // If multiple nodes, return array\n return nodes.map((node) => icuNodesToIntlayer([node]));\n};\n\nconst icuToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' &&\n (node.includes('{') ||\n node.includes('}') ||\n /<[a-zA-Z0-9-]+[^>]*>/.test(node)),\n transform: (node: any) => {\n try {\n const ast = parseICU(node);\n return icuNodesToIntlayer(ast);\n } catch {\n // If parsing fails, return original string\n return node;\n }\n },\n};\n\nconst intlayerToIcuPlugin = {\n canHandle: (node: any) => {\n if (\n typeof node === 'string' &&\n (node.includes('{') || node.includes('}'))\n ) {\n return true;\n }\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n // Convert Intlayer's double-brace format {{var}} to ICU's single-brace format {var}\n if (typeof node === 'string') {\n return node.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n return node[NodeTypes.INSERTION].replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.HTML) {\n return node[NodeTypes.HTML];\n }\n\n if (node.nodeType === NodeTypes.PLURAL) {\n const options = node[NodeTypes.PLURAL];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = 'count';\n\n const fallbackVal =\n transformedOptions.other || Object.values(transformedOptions)[0];\n\n if (fallbackVal) {\n const match = fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const parts = [];\n\n for (const [key, val] of Object.entries(transformedOptions)) {\n let strVal = val;\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n parts.push(`${key} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_icu_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = options.__intlayer_icu_var || 'n';\n\n if (!options.__intlayer_icu_var) {\n const fallbackVal =\n transformedOptions.fallback ||\n transformedOptions.other ||\n Object.values(transformedOptions)[0];\n const match = fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const keys = Object.keys(transformedOptions);\n const pluralKeys = [\n '1',\n '2',\n '<=3',\n '>=4',\n 'fallback',\n 'other',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n ];\n\n const isPlural = keys.every(\n (k) => pluralKeys.includes(k) || /^[<>=]?\\d+(\\.\\d+)?$/.test(k)\n );\n\n const parts = [];\n\n if (isPlural) {\n for (const [key, val] of Object.entries(transformedOptions)) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n else if (key === '<=3') icuKey = 'few';\n else if (key === '>=4') icuKey = 'many';\n else if (/^\\d+$/.test(key)) icuKey = `=${key}`;\n else if (['zero', 'few', 'many'].includes(key)) icuKey = key;\n else icuKey = 'other';\n\n let strVal = val;\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n } else {\n const entries = Object.entries(transformedOptions).sort(\n ([keyA], [keyB]) => {\n if (keyA === 'fallback' || keyA === 'other') return 1;\n if (keyB === 'fallback' || keyB === 'other') return -1;\n return 0;\n }\n );\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n parts.push(`${icuKey} {${val}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const varName = 'gender';\n const parts = [];\n\n const entries = Object.entries(options).sort(([keyA], [keyB]) => {\n if (keyA === 'fallback') return 1;\n if (keyB === 'fallback') return -1;\n return 0;\n });\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n const childVal = next(val, props);\n const strVal =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n // handle array/composite strings that passed canHandle\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToICUFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'icu',\n keyPath: [],\n plugins: [{ id: 'icu', ...intlayerToIcuPlugin }],\n });\n};\n\nexport const icuToIntlayerFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'icu',\n keyPath: [],\n plugins: [{ id: 'icu', ...icuToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ICU.cjs","names":["html","insert","enu","plural","gender","NodeTypes","deepTransformNode"],"sources":["../../../src/messageFormat/ICU.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\n\n/**\n * ICU MessageFormat Converter\n *\n * This module converts between ICU MessageFormat and Intlayer's internal format.\n *\n * IMPORTANT: Two different formats are used:\n *\n * 1. ICU MessageFormat (external format):\n * - Simple variables: {name}\n * - Formatted variables: {amount, number, currency}\n * - Plural: {count, plural, =0 {none} other {# items}}\n * - Select: {gender, select, male {He} female {She} other {They}}\n *\n * 2. Intlayer Internal Format:\n * - Simple variables: {{name}} (double braces for clarity and to distinguish from literal text)\n * - Formatted variables: {amount, number, currency} (keeps ICU format)\n * - Plural: enu({ 0: 'none', fallback: '{{count}} items' })\n * - Select/Gender: gender({ male: 'He', female: 'She', fallback: 'They' })\n *\n * Conversion flow:\n * - ICU → Intlayer: {name} → {{name}}\n * - Intlayer → ICU: {{name}} → {name}\n *\n * The double braces in Intlayer format serve to:\n * - Distinguish variables from literal text containing braces\n * - Work with getInsertion() runtime function which expects {{var}} patterns\n * - Provide clear visual distinction in content dictionaries\n */\n\n// Types for our AST\ntype ICUNode =\n | string\n | {\n type: 'argument';\n name: string;\n format?: { type: string; style?: string };\n }\n | { type: 'plural'; name: string; options: Record<string, ICUNode[]> }\n | { type: 'select'; name: string; options: Record<string, ICUNode[]> };\n\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\n\nconst parseICU = (text: string): ICUNode[] => {\n let index = 0;\n\n const parseNodes = (): ICUNode[] => {\n const nodes: ICUNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n nodes.push(parseArgument());\n } else if (char === '}') {\n // End of current block\n break;\n } else if (char === \"'\") {\n // Escaping\n if (index + 1 < text.length && text[index + 1] === \"'\") {\n currentText += \"'\";\n index += 2;\n } else {\n // Find next quote\n const nextQuote = text.indexOf(\"'\", index + 1);\n if (nextQuote !== -1) {\n // Determine if this is escaping syntax characters\n // For simplicity, we'll treat content between single quotes as literal\n // provided it contains syntax chars.\n // Standard ICU: ' quoted string '\n // If it is just an apostrophe, it should be doubled.\n // But simplified: take content between quotes literally.\n currentText += text.substring(index + 1, nextQuote);\n index = nextQuote + 1;\n } else {\n currentText += \"'\";\n index++;\n }\n }\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n return nodes;\n };\n\n const parseArgument = (): ICUNode => {\n // We are past '{'\n // Parse name\n let name = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n name += text[index];\n index++;\n }\n name = name.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name };\n }\n\n // Must be comma\n if (text[index] === ',') {\n index++;\n // Parse type\n let type = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n type += text[index];\n index++;\n }\n type = type.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name, format: { type } };\n }\n\n if (text[index] === ',') {\n index++;\n\n // If plural or select, parse options\n if (type === 'plural' || type === 'select') {\n // Parse options\n const options: Record<string, ICUNode[]> = {};\n\n while (index < text.length && text[index] !== '}') {\n // skip whitespace\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n // parse key\n let key = '';\n while (index < text.length && /[^{\\s]/.test(text[index])) {\n key += text[index];\n index++;\n }\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n if (text[index] !== '{')\n throw new Error('Expected { after option key');\n index++; // skip {\n\n const value = parseNodes();\n\n if (text[index] !== '}')\n throw new Error('Expected } after option value');\n index++; // skip }\n\n options[key] = value;\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n }\n\n index++; // skip closing argument }\n\n if (type === 'plural') {\n return { type: 'plural', name, options };\n } else if (type === 'select') {\n return { type: 'select', name, options };\n }\n } else {\n // Parse style for number/date/time\n let style = '';\n while (index < text.length && text[index] !== '}') {\n style += text[index];\n index++;\n }\n if (index >= text.length) throw new Error('Unclosed argument');\n\n style = style.trim();\n index++; // skip }\n\n return { type: 'argument', name, format: { type, style } };\n }\n }\n }\n\n throw new Error('Malformed argument');\n };\n\n return parseNodes();\n};\n\nconst icuNodesToIntlayer = (nodes: ICUNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') {\n const node = nodes[0];\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n // Check if we can flatten to a single string (insert)\n const canFlatten = nodes.every(\n (node) => typeof node === 'string' || node.type === 'argument'\n );\n if (canFlatten) {\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else if (typeof node !== 'string' && node.type === 'argument') {\n if (node.format) {\n // Formatted variables keep ICU format: {var, type, style}\n str += `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`;\n } else {\n // Simple variables use Intlayer format: {{var}}\n str += `{{${node.name}}}`;\n }\n }\n }\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(str)) {\n return html(str);\n }\n return insert(str);\n }\n\n // Mix of string and complex types.\n // If we have just one complex type and it covers everything?\n if (nodes.length === 1) {\n const node = nodes[0];\n\n if (typeof node === 'string') {\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n if (node.type === 'argument') {\n if (node.format) {\n return insert(\n `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`\n );\n }\n return insert(`{{${node.name}}}`);\n }\n if (node.type === 'plural') {\n const options: Record<string, any> = {};\n let hasExactMatch = false;\n\n for (const key of Object.keys(node.options)) {\n if (key.startsWith('=')) {\n hasExactMatch = true;\n break;\n }\n }\n\n if (hasExactMatch) {\n for (const [key, val] of Object.entries(node.options)) {\n // Map ICU keys to Intlayer keys\n let newKey = key;\n if (key.startsWith('=')) {\n newKey = key.substring(1); // =0 -> 0\n } else if (key === 'one') {\n newKey = '1';\n } else if (key === 'two') {\n newKey = '2';\n } else if (key === 'few') {\n newKey = '<=3';\n } else if (key === 'many') {\n newKey = '>=4';\n } else if (key === 'other') {\n newKey = 'fallback';\n }\n // Handle # in plural value\n // For plural, we need to pass the variable name down or replace #\n // Intlayer uses {{n}} (or whatever var name) for simple variables\n // We should replace # with {{n}} in the string parts of val\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[newKey] = icuNodesToIntlayer(replacedVal);\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n } else {\n for (const [key, val] of Object.entries(node.options)) {\n // Handle # in plural value\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[key] = icuNodesToIntlayer(replacedVal);\n }\n\n return plural(options as any);\n }\n }\n if (node.type === 'select') {\n const options: Record<string, any> = {};\n\n for (const [key, val] of Object.entries(node.options)) {\n options[key] = icuNodesToIntlayer(val);\n }\n\n // Check if it looks like gender\n const optionKeys = Object.keys(options);\n // It is gender if it has 'male' OR 'female' AND only contains gender keys (male, female, other)\n const isGender =\n (options.male || options.female) &&\n optionKeys.every((k) =>\n ['male', 'female', 'other', 'fallback'].includes(k)\n );\n\n if (isGender) {\n return gender({\n fallback: options.other,\n male: options.male,\n female: options.female,\n });\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n }\n\n // If multiple nodes, return array\n return nodes.map((node) => icuNodesToIntlayer([node]));\n};\n\nconst icuToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' &&\n (node.includes('{') ||\n node.includes('}') ||\n /<[a-zA-Z0-9-]+[^>]*>/.test(node)),\n transform: (node: any) => {\n try {\n const ast = parseICU(node);\n return icuNodesToIntlayer(ast);\n } catch {\n // If parsing fails, return original string\n return node;\n }\n },\n};\n\nconst intlayerToIcuPlugin = {\n canHandle: (node: any) => {\n if (\n typeof node === 'string' &&\n (node.includes('{') || node.includes('}'))\n ) {\n return true;\n }\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n // Convert Intlayer's double-brace format {{var}} to ICU's single-brace format {var}\n if (typeof node === 'string') {\n return node.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n return node[NodeTypes.INSERTION].replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.HTML) {\n return node[NodeTypes.HTML];\n }\n\n if (node.nodeType === NodeTypes.PLURAL) {\n const options = node[NodeTypes.PLURAL];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = 'count';\n\n const fallbackVal =\n transformedOptions.other || Object.values(transformedOptions)[0];\n\n if (fallbackVal) {\n const match = fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const parts = [];\n\n for (const [key, val] of Object.entries(transformedOptions)) {\n let strVal = val;\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n parts.push(`${key} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_icu_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = options.__intlayer_icu_var || 'n';\n\n if (!options.__intlayer_icu_var) {\n const fallbackVal =\n transformedOptions.fallback ||\n transformedOptions.other ||\n Object.values(transformedOptions)[0];\n const match = fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const keys = Object.keys(transformedOptions);\n const pluralKeys = [\n '1',\n '2',\n '<=3',\n '>=4',\n 'fallback',\n 'other',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n ];\n\n const isPlural = keys.every(\n (k) => pluralKeys.includes(k) || /^[<>=]?\\d+(\\.\\d+)?$/.test(k)\n );\n\n const parts = [];\n\n if (isPlural) {\n for (const [key, val] of Object.entries(transformedOptions)) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n else if (key === '<=3') icuKey = 'few';\n else if (key === '>=4') icuKey = 'many';\n else if (/^\\d+$/.test(key)) icuKey = `=${key}`;\n else if (['zero', 'few', 'many'].includes(key)) icuKey = key;\n else icuKey = 'other';\n\n let strVal = val;\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n } else {\n const entries = Object.entries(transformedOptions).sort(\n ([keyA], [keyB]) => {\n if (keyA === 'fallback' || keyA === 'other') return 1;\n if (keyB === 'fallback' || keyB === 'other') return -1;\n return 0;\n }\n );\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n parts.push(`${icuKey} {${val}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const varName = 'gender';\n const parts = [];\n\n const entries = Object.entries(options).sort(([keyA], [keyB]) => {\n if (keyA === 'fallback') return 1;\n if (keyB === 'fallback') return -1;\n return 0;\n });\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n const childVal = next(val, props);\n const strVal =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n // handle array/composite strings that passed canHandle\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToICUFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'icu',\n keyPath: [],\n plugins: [{ id: 'icu', ...intlayerToIcuPlugin }],\n });\n};\n\nexport const icuToIntlayerFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'icu',\n keyPath: [],\n plugins: [{ id: 'icu', ...icuToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"i18next.cjs","names":["html","insert","enu","plural","gender","NodeTypes","deepTransformNode"],"sources":["../../../src/messageFormat/i18next.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\n// Types for our AST\ntype I18NextNode =\n | string\n | {\n type: 'argument';\n name: string;\n format?: { type: string; style?: string };\n }\n | { type: 'plural'; name: string; options: Record<string, I18NextNode[]> }\n | { type: 'select'; name: string; options: Record<string, I18NextNode[]> };\n\nconst parseI18Next = (text: string): I18NextNode[] => {\n let index = 0;\n\n const parseNodes = (): I18NextNode[] => {\n const nodes: I18NextNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n // Standard i18next variable: {{var}}\n if (char === '{' && text[index + 1] === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index += 2; // skip {{\n nodes.push(parseStandardArgument());\n }\n // ICU syntax: {var} or {var, plural, ...}\n else if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n nodes.push(parseICUArgument());\n } else if (char === '}') {\n // End of current block (likely ICU block end)\n break;\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n return nodes;\n };\n\n const parseStandardArgument = (): I18NextNode => {\n // We are past '{{'\n let name = '';\n while (index < text.length) {\n // Check for closing }}\n if (text[index] === '}' && text[index + 1] === '}') {\n index += 2; // skip }}\n return { type: 'argument', name: name.trim() };\n }\n name += text[index];\n index++;\n }\n throw new Error('Unclosed i18next variable');\n };\n\n const parseICUArgument = (): I18NextNode => {\n // We are past '{'\n let name = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n name += text[index];\n index++;\n }\n name = name.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name };\n }\n\n // Must be comma\n if (text[index] === ',') {\n index++;\n // Parse type\n let type = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n type += text[index];\n index++;\n }\n type = type.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name, format: { type } };\n }\n\n if (text[index] === ',') {\n index++;\n\n // If plural or select, parse options\n if (type === 'plural' || type === 'select') {\n const options: Record<string, I18NextNode[]> = {};\n\n while (index < text.length && text[index] !== '}') {\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n let key = '';\n while (index < text.length && /[^{\\s]/.test(text[index])) {\n key += text[index];\n index++;\n }\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n if (text[index] !== '{')\n throw new Error('Expected { after option key');\n index++; // skip {\n\n const value = parseNodes();\n\n if (text[index] !== '}')\n throw new Error('Expected } after option value');\n index++; // skip }\n\n options[key] = value;\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n }\n\n index++; // skip closing argument }\n\n if (type === 'plural') {\n return { type: 'plural', name, options };\n } else if (type === 'select') {\n return { type: 'select', name, options };\n }\n } else {\n // Parse style for number/date/time\n let style = '';\n while (index < text.length && text[index] !== '}') {\n style += text[index];\n index++;\n }\n if (index >= text.length) throw new Error('Unclosed argument');\n\n style = style.trim();\n index++; // skip }\n\n return { type: 'argument', name, format: { type, style } };\n }\n }\n }\n\n throw new Error('Malformed argument');\n };\n\n return parseNodes();\n};\n\nconst i18nextNodesToIntlayer = (nodes: I18NextNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') {\n const node = nodes[0];\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n const canFlatten = nodes.every(\n (node) => typeof node === 'string' || node.type === 'argument'\n );\n\n if (canFlatten) {\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else if (typeof node !== 'string' && node.type === 'argument') {\n if (node.format) {\n // For formatted arguments, use ICU syntax: {name, type, style}\n str += `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`;\n } else {\n // For simple arguments, use standard i18next: {{name}}\n str += `{{${node.name}}}`;\n }\n }\n }\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(str)) {\n return html(str);\n }\n return insert(str);\n }\n\n if (nodes.length === 1) {\n const node = nodes[0];\n if (typeof node === 'string') {\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n if (node.type === 'argument') {\n if (node.format) {\n return insert(\n `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`\n );\n }\n return insert(`{{${node.name}}}`);\n }\n\n if (node.type === 'plural') {\n const options: Record<string, any> = {};\n let hasExactMatch = false;\n\n for (const key of Object.keys(node.options)) {\n if (key.startsWith('=')) {\n hasExactMatch = true;\n break;\n }\n }\n\n if (hasExactMatch) {\n for (const [key, val] of Object.entries(node.options)) {\n let newKey = key;\n if (key.startsWith('=')) {\n newKey = key.substring(1);\n } else if (key === 'one') {\n newKey = '1';\n } else if (key === 'two') {\n newKey = '2';\n } else if (key === 'few') {\n newKey = '<=3';\n } else if (key === 'many') {\n newKey = '>=4';\n } else if (key === 'other') {\n newKey = 'fallback';\n }\n // Handle # replacement\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n // In ICU plural, # is replaced by the number\n // In i18next, if using ICU plugin, it behaves same.\n // We map it to {{varName}} in Intlayer\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[newKey] = i18nextNodesToIntlayer(replacedVal);\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n } else {\n for (const [key, val] of Object.entries(node.options)) {\n // Handle # replacement\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[key] = i18nextNodesToIntlayer(replacedVal);\n }\n\n return plural(options as any);\n }\n }\n\n if (node.type === 'select') {\n const options: Record<string, any> = {};\n for (const [key, val] of Object.entries(node.options)) {\n options[key] = i18nextNodesToIntlayer(val);\n }\n\n // Check for gender\n const optionKeys = Object.keys(options);\n const isGender =\n (options.male || options.female) &&\n optionKeys.every((k) =>\n ['male', 'female', 'other', 'fallback'].includes(k)\n );\n\n if (isGender) {\n return gender({\n fallback: options.other,\n male: options.male,\n female: options.female,\n });\n }\n\n // Preserve variable name for generic select\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n }\n\n return nodes.map((node) => i18nextNodesToIntlayer([node]));\n};\n\nconst i18nextToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' &&\n (node.includes('{') ||\n node.includes('}') ||\n /<[a-zA-Z0-9-]+[^>]*>/.test(node)),\n transform: (node: any) => {\n try {\n const ast = parseI18Next(node);\n return i18nextNodesToIntlayer(ast);\n } catch {\n return node;\n }\n },\n};\n\nconst intlayerToI18nextPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n return node;\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n if (node[NodeTypes.INSERTION].match(/\\{[^}]*,[^}]*\\}/)) {\n return node[NodeTypes.INSERTION];\n }\n return node[NodeTypes.INSERTION];\n }\n\n if (node.nodeType === NodeTypes.HTML) {\n return node[NodeTypes.HTML];\n }\n\n if (node.nodeType === NodeTypes.PLURAL) {\n const options = node[NodeTypes.PLURAL];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = 'count';\n\n const fallbackVal =\n transformedOptions.other || Object.values(transformedOptions)[0];\n\n if (fallbackVal) {\n const match =\n fallbackVal.match(/\\{\\{([a-zA-Z0-9_]+)\\}\\}/) ||\n fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const parts = [];\n\n for (const [key, val] of Object.entries(transformedOptions)) {\n const icuKey = key;\n let strVal = val;\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_icu_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = options.__intlayer_icu_var || 'count';\n\n if (!options.__intlayer_icu_var) {\n const fallbackVal =\n transformedOptions.fallback ||\n transformedOptions.other ||\n Object.values(transformedOptions)[0];\n\n const match =\n fallbackVal.match(/\\{\\{([a-zA-Z0-9_]+)\\}\\}/) ||\n fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const keys = Object.keys(transformedOptions);\n const pluralKeys = [\n '1',\n '2',\n '<=3',\n '>=4',\n 'fallback',\n 'other',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n ];\n const isPlural = keys.every(\n (k) => pluralKeys.includes(k) || /^[<>=]?\\d+(\\.\\d+)?$/.test(k)\n );\n\n const parts = [];\n\n if (isPlural) {\n for (const [key, val] of Object.entries(transformedOptions)) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n else if (key === '<=3') icuKey = 'few';\n else if (key === '>=4') icuKey = 'many';\n else if (/^\\d+$/.test(key)) icuKey = `=${key}`;\n\n let strVal = val;\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n } else {\n const entries = Object.entries(transformedOptions).sort(\n ([keyA], [keyB]) => {\n if (keyA === 'fallback' || keyA === 'other') return 1;\n if (keyB === 'fallback' || keyB === 'other') return -1;\n return 0;\n }\n );\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n let strVal = val;\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const varName = 'gender';\n const parts = [];\n\n const entries = Object.entries(options).sort(([keyA], [keyB]) => {\n if (keyA === 'fallback') return 1;\n if (keyB === 'fallback') return -1;\n return 0;\n });\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n const childVal = next(val, props);\n let strVal =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToI18nextFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'i18next',\n keyPath: [],\n plugins: [{ id: 'i18next', ...intlayerToI18nextPlugin }],\n });\n};\n\nexport const i18nextToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'i18next',\n keyPath: [],\n plugins: [{ id: 'i18next', ...i18nextToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"i18next.cjs","names":["html","insert","enu","plural","gender","NodeTypes","deepTransformNode"],"sources":["../../../src/messageFormat/i18next.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\n// Types for our AST\ntype I18NextNode =\n | string\n | {\n type: 'argument';\n name: string;\n format?: { type: string; style?: string };\n }\n | { type: 'plural'; name: string; options: Record<string, I18NextNode[]> }\n | { type: 'select'; name: string; options: Record<string, I18NextNode[]> };\n\nconst parseI18Next = (text: string): I18NextNode[] => {\n let index = 0;\n\n const parseNodes = (): I18NextNode[] => {\n const nodes: I18NextNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n // Standard i18next variable: {{var}}\n if (char === '{' && text[index + 1] === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index += 2; // skip {{\n nodes.push(parseStandardArgument());\n }\n // ICU syntax: {var} or {var, plural, ...}\n else if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n nodes.push(parseICUArgument());\n } else if (char === '}') {\n // End of current block (likely ICU block end)\n break;\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n return nodes;\n };\n\n const parseStandardArgument = (): I18NextNode => {\n // We are past '{{'\n let name = '';\n while (index < text.length) {\n // Check for closing }}\n if (text[index] === '}' && text[index + 1] === '}') {\n index += 2; // skip }}\n return { type: 'argument', name: name.trim() };\n }\n name += text[index];\n index++;\n }\n throw new Error('Unclosed i18next variable');\n };\n\n const parseICUArgument = (): I18NextNode => {\n // We are past '{'\n let name = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n name += text[index];\n index++;\n }\n name = name.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name };\n }\n\n // Must be comma\n if (text[index] === ',') {\n index++;\n // Parse type\n let type = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n type += text[index];\n index++;\n }\n type = type.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name, format: { type } };\n }\n\n if (text[index] === ',') {\n index++;\n\n // If plural or select, parse options\n if (type === 'plural' || type === 'select') {\n const options: Record<string, I18NextNode[]> = {};\n\n while (index < text.length && text[index] !== '}') {\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n let key = '';\n while (index < text.length && /[^{\\s]/.test(text[index])) {\n key += text[index];\n index++;\n }\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n if (text[index] !== '{')\n throw new Error('Expected { after option key');\n index++; // skip {\n\n const value = parseNodes();\n\n if (text[index] !== '}')\n throw new Error('Expected } after option value');\n index++; // skip }\n\n options[key] = value;\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n }\n\n index++; // skip closing argument }\n\n if (type === 'plural') {\n return { type: 'plural', name, options };\n } else if (type === 'select') {\n return { type: 'select', name, options };\n }\n } else {\n // Parse style for number/date/time\n let style = '';\n while (index < text.length && text[index] !== '}') {\n style += text[index];\n index++;\n }\n if (index >= text.length) throw new Error('Unclosed argument');\n\n style = style.trim();\n index++; // skip }\n\n return { type: 'argument', name, format: { type, style } };\n }\n }\n }\n\n throw new Error('Malformed argument');\n };\n\n return parseNodes();\n};\n\nconst i18nextNodesToIntlayer = (nodes: I18NextNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') {\n const node = nodes[0];\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n const canFlatten = nodes.every(\n (node) => typeof node === 'string' || node.type === 'argument'\n );\n\n if (canFlatten) {\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else if (typeof node !== 'string' && node.type === 'argument') {\n if (node.format) {\n // For formatted arguments, use ICU syntax: {name, type, style}\n str += `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`;\n } else {\n // For simple arguments, use standard i18next: {{name}}\n str += `{{${node.name}}}`;\n }\n }\n }\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(str)) {\n return html(str);\n }\n return insert(str);\n }\n\n if (nodes.length === 1) {\n const node = nodes[0];\n if (typeof node === 'string') {\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n if (node.type === 'argument') {\n if (node.format) {\n return insert(\n `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`\n );\n }\n return insert(`{{${node.name}}}`);\n }\n\n if (node.type === 'plural') {\n const options: Record<string, any> = {};\n let hasExactMatch = false;\n\n for (const key of Object.keys(node.options)) {\n if (key.startsWith('=')) {\n hasExactMatch = true;\n break;\n }\n }\n\n if (hasExactMatch) {\n for (const [key, val] of Object.entries(node.options)) {\n let newKey = key;\n if (key.startsWith('=')) {\n newKey = key.substring(1);\n } else if (key === 'one') {\n newKey = '1';\n } else if (key === 'two') {\n newKey = '2';\n } else if (key === 'few') {\n newKey = '<=3';\n } else if (key === 'many') {\n newKey = '>=4';\n } else if (key === 'other') {\n newKey = 'fallback';\n }\n // Handle # replacement\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n // In ICU plural, # is replaced by the number\n // In i18next, if using ICU plugin, it behaves same.\n // We map it to {{varName}} in Intlayer\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[newKey] = i18nextNodesToIntlayer(replacedVal);\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n } else {\n for (const [key, val] of Object.entries(node.options)) {\n // Handle # replacement\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[key] = i18nextNodesToIntlayer(replacedVal);\n }\n\n return plural(options as any);\n }\n }\n\n if (node.type === 'select') {\n const options: Record<string, any> = {};\n for (const [key, val] of Object.entries(node.options)) {\n options[key] = i18nextNodesToIntlayer(val);\n }\n\n // Check for gender\n const optionKeys = Object.keys(options);\n const isGender =\n (options.male || options.female) &&\n optionKeys.every((k) =>\n ['male', 'female', 'other', 'fallback'].includes(k)\n );\n\n if (isGender) {\n return gender({\n fallback: options.other,\n male: options.male,\n female: options.female,\n });\n }\n\n // Preserve variable name for generic select\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n }\n\n return nodes.map((node) => i18nextNodesToIntlayer([node]));\n};\n\nconst i18nextToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' &&\n (node.includes('{') ||\n node.includes('}') ||\n /<[a-zA-Z0-9-]+[^>]*>/.test(node)),\n transform: (node: any) => {\n try {\n const ast = parseI18Next(node);\n return i18nextNodesToIntlayer(ast);\n } catch {\n return node;\n }\n },\n};\n\nconst intlayerToI18nextPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n return node;\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n if (node[NodeTypes.INSERTION].match(/\\{[^}]*,[^}]*\\}/)) {\n return node[NodeTypes.INSERTION];\n }\n return node[NodeTypes.INSERTION];\n }\n\n if (node.nodeType === NodeTypes.HTML) {\n return node[NodeTypes.HTML];\n }\n\n if (node.nodeType === NodeTypes.PLURAL) {\n const options = node[NodeTypes.PLURAL];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = 'count';\n\n const fallbackVal =\n transformedOptions.other || Object.values(transformedOptions)[0];\n\n if (fallbackVal) {\n const match =\n fallbackVal.match(/\\{\\{([a-zA-Z0-9_]+)\\}\\}/) ||\n fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const parts = [];\n\n for (const [key, val] of Object.entries(transformedOptions)) {\n const icuKey = key;\n let strVal = val;\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_icu_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = options.__intlayer_icu_var || 'count';\n\n if (!options.__intlayer_icu_var) {\n const fallbackVal =\n transformedOptions.fallback ||\n transformedOptions.other ||\n Object.values(transformedOptions)[0];\n\n const match =\n fallbackVal.match(/\\{\\{([a-zA-Z0-9_]+)\\}\\}/) ||\n fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const keys = Object.keys(transformedOptions);\n const pluralKeys = [\n '1',\n '2',\n '<=3',\n '>=4',\n 'fallback',\n 'other',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n ];\n const isPlural = keys.every(\n (k) => pluralKeys.includes(k) || /^[<>=]?\\d+(\\.\\d+)?$/.test(k)\n );\n\n const parts = [];\n\n if (isPlural) {\n for (const [key, val] of Object.entries(transformedOptions)) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n else if (key === '<=3') icuKey = 'few';\n else if (key === '>=4') icuKey = 'many';\n else if (/^\\d+$/.test(key)) icuKey = `=${key}`;\n\n let strVal = val;\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n } else {\n const entries = Object.entries(transformedOptions).sort(\n ([keyA], [keyB]) => {\n if (keyA === 'fallback' || keyA === 'other') return 1;\n if (keyB === 'fallback' || keyB === 'other') return -1;\n return 0;\n }\n );\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n let strVal = val;\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const varName = 'gender';\n const parts = [];\n\n const entries = Object.entries(options).sort(([keyA], [keyB]) => {\n if (keyA === 'fallback') return 1;\n if (keyB === 'fallback') return -1;\n return 0;\n });\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n const childVal = next(val, props);\n let strVal =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToI18nextFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'i18next',\n keyPath: [],\n plugins: [{ id: 'i18next', ...intlayerToI18nextPlugin }],\n });\n};\n\nexport const i18nextToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'i18next',\n keyPath: [],\n plugins: [{ id: 'i18next', ...i18nextToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"po.cjs","names":["NodeTypes","html","insert","gender","enu","plural","deepTransformNode"],"sources":["../../../src/messageFormat/po.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\nexport type PortableObject = {\n msgid: string;\n msgctxt?: string;\n msgid_plural?: string;\n msgstr: string[];\n};\n\n/**\n * Extracts the string value from a transformed AST node or generic object.\n */\nconst extractStringValue = (val: any): string => {\n if (typeof val === 'string') return val;\n if (val && typeof val === 'object' && 'msgstr' in val) {\n return val.msgstr[0] || '';\n }\n return JSON.stringify(val);\n};\n\nconst intlayerToPoPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n // Handle structural string arrays (composite phrases)\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.PLURAL ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n if (hasPlainObjectOrArray) return false;\n if (!hasNode) return false;\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any): PortableObject => {\n // 1. Strings\n if (typeof node === 'string') {\n const poVal = node.replace(/\\{\\{([^}]+)\\}\\}/g, '%($1)s');\n return { msgid: poVal, msgstr: [poVal] };\n }\n\n // 2. Insertions & Variables\n if (node.nodeType === NodeTypes.INSERTION) {\n return next(node[NodeTypes.INSERTION], props);\n }\n\n // 3. HTML\n if (node.nodeType === NodeTypes.HTML) {\n const val = node[NodeTypes.HTML];\n return { msgid: val, msgstr: [val] };\n }\n\n // 4. Plurals & Enumerations\n if (\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.ENUMERATION\n ) {\n const isPlural = node.nodeType === NodeTypes.PLURAL;\n const options = isPlural\n ? node[NodeTypes.PLURAL]\n : node[NodeTypes.ENUMERATION];\n\n const rawMsgid = isPlural\n ? options.one || options.other || options.fallback\n : options.fallback || options['0'];\n\n const msgid = extractStringValue(next(rawMsgid, props));\n const msgid_plural = isPlural\n ? extractStringValue(\n next(options.other || options.fallback || rawMsgid, props)\n )\n : extractStringValue(next(options.fallback || rawMsgid, props));\n\n const msgstr: string[] = [];\n\n if (isPlural) {\n // Standard CLDR/Gettext mapping fallback\n if ('zero' in options)\n msgstr.push(extractStringValue(next(options.zero, props)));\n msgstr.push(\n extractStringValue(next(options.one || options.fallback, props))\n );\n if ('two' in options)\n msgstr.push(extractStringValue(next(options.two, props)));\n if ('few' in options)\n msgstr.push(extractStringValue(next(options.few, props)));\n if ('many' in options)\n msgstr.push(extractStringValue(next(options.many, props)));\n\n // Ensure 'other' is always the last fallback if others are missing\n const otherVal = extractStringValue(\n next(options.other || options.fallback, props)\n );\n if (!msgstr.includes(otherVal)) msgstr.push(otherVal);\n } else {\n // Enums don't have standard PO mapping, pack linearly\n msgstr[0] = extractStringValue(\n next(options.fallback || options['0'], props)\n );\n msgstr[1] = msgstr[0];\n }\n\n return {\n msgctxt: isPlural ? undefined : 'enumeration',\n msgid,\n msgid_plural,\n msgstr,\n };\n }\n\n // 5. Gender (mapped to PO via msgctxt)\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const fallback = extractStringValue(next(options.fallback, props));\n return {\n msgctxt: 'gender',\n msgid: fallback,\n msgstr: [\n extractStringValue(next(options.male || options.fallback, props)),\n extractStringValue(next(options.female || options.fallback, props)),\n fallback,\n ],\n };\n }\n\n // 6. Arrays / Composites\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const combined = arr\n .map((item: any) => extractStringValue(next(item, props)))\n .join('');\n return { msgid: combined, msgstr: [combined] };\n }\n\n return node;\n },\n};\n\nconst poToIntlayerPlugin = {\n canHandle: (node: any) =>\n node && typeof node === 'object' && 'msgid' in node && 'msgstr' in node,\n\n transform: (node: PortableObject) => {\n const msgstr = node.msgstr || [];\n const isPlural = Boolean(node.msgid_plural) || msgstr.length > 1;\n\n const processString = (str: string) => {\n if (!str) return '';\n // Convert Python/C-style gettext variables %(name)s or %(name)d -> {{name}}\n const parsed = str.replace(/%\\(([a-zA-Z0-9_-]+)\\)[sdf]/g, '{{$1}}');\n\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(parsed)) return html(parsed);\n if (parsed.includes('{{')) return insert(parsed);\n return parsed;\n };\n\n // Fast-path: Single string translation\n if (!isPlural) {\n return processString(msgstr[0] || node.msgid || '');\n }\n\n // Handle Plural/Enum/Gender matrix\n const options: Record<string, any> = {};\n\n if (node.msgctxt === 'gender') {\n return gender({\n male: processString(msgstr[0] || node.msgid),\n female: processString(msgstr[1] || msgstr[0]),\n fallback: processString(msgstr[2] || msgstr[msgstr.length - 1]),\n });\n }\n\n if (node.msgctxt === 'enumeration') {\n return enu({\n '0': processString(msgstr[0]),\n fallback: processString(msgstr[msgstr.length - 1]),\n });\n }\n\n // Plural Form Mapping based on array length (Gettext Plural-Forms approximation)\n if (msgstr.length === 2) {\n options.one = processString(msgstr[0]);\n options.other = processString(msgstr[1]);\n } else if (msgstr.length === 3) {\n // E.g., Polish/Russian: one, few, many/other\n options.one = processString(msgstr[0]);\n options.few = processString(msgstr[1]);\n options.other = processString(msgstr[2]);\n } else if (msgstr.length === 6) {\n // E.g., Arabic: zero, one, two, few, many, other\n options.zero = processString(msgstr[0]);\n options.one = processString(msgstr[1]);\n options.two = processString(msgstr[2]);\n options.few = processString(msgstr[3]);\n options.many = processString(msgstr[4]);\n options.other = processString(msgstr[5]);\n } else {\n // Generic arbitrary length mapping\n options.one = processString(msgstr[0]);\n options.other = processString(msgstr[msgstr.length - 1]);\n for (let i = 1; i < msgstr.length - 1; i++) {\n options[`${i + 1}`] = processString(msgstr[i]);\n }\n }\n\n return plural(options as any);\n },\n};\n\nexport const intlayerToPortableObjectFormatter = (\n dictionary: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(dictionary, {\n dictionaryKey: 'po',\n keyPath: [],\n plugins: [{ id: 'po', ...intlayerToPoPlugin }],\n });\n};\n\nexport const portableObjectToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'po',\n keyPath: [],\n plugins: [{ id: 'po', ...poToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"po.cjs","names":["NodeTypes","html","insert","gender","enu","plural","deepTransformNode"],"sources":["../../../src/messageFormat/po.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\nexport type PortableObject = {\n msgid: string;\n msgctxt?: string;\n msgid_plural?: string;\n msgstr: string[];\n};\n\n/**\n * Extracts the string value from a transformed AST node or generic object.\n */\nconst extractStringValue = (val: any): string => {\n if (typeof val === 'string') return val;\n if (val && typeof val === 'object' && 'msgstr' in val) {\n return val.msgstr[0] || '';\n }\n return JSON.stringify(val);\n};\n\nconst intlayerToPoPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n // Handle structural string arrays (composite phrases)\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.PLURAL ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n if (hasPlainObjectOrArray) return false;\n if (!hasNode) return false;\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any): PortableObject => {\n // 1. Strings\n if (typeof node === 'string') {\n const poVal = node.replace(/\\{\\{([^}]+)\\}\\}/g, '%($1)s');\n return { msgid: poVal, msgstr: [poVal] };\n }\n\n // 2. Insertions & Variables\n if (node.nodeType === NodeTypes.INSERTION) {\n return next(node[NodeTypes.INSERTION], props);\n }\n\n // 3. HTML\n if (node.nodeType === NodeTypes.HTML) {\n const val = node[NodeTypes.HTML];\n return { msgid: val, msgstr: [val] };\n }\n\n // 4. Plurals & Enumerations\n if (\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.ENUMERATION\n ) {\n const isPlural = node.nodeType === NodeTypes.PLURAL;\n const options = isPlural\n ? node[NodeTypes.PLURAL]\n : node[NodeTypes.ENUMERATION];\n\n const rawMsgid = isPlural\n ? options.one || options.other || options.fallback\n : options.fallback || options['0'];\n\n const msgid = extractStringValue(next(rawMsgid, props));\n const msgid_plural = isPlural\n ? extractStringValue(\n next(options.other || options.fallback || rawMsgid, props)\n )\n : extractStringValue(next(options.fallback || rawMsgid, props));\n\n const msgstr: string[] = [];\n\n if (isPlural) {\n // Standard CLDR/Gettext mapping fallback\n if ('zero' in options)\n msgstr.push(extractStringValue(next(options.zero, props)));\n msgstr.push(\n extractStringValue(next(options.one || options.fallback, props))\n );\n if ('two' in options)\n msgstr.push(extractStringValue(next(options.two, props)));\n if ('few' in options)\n msgstr.push(extractStringValue(next(options.few, props)));\n if ('many' in options)\n msgstr.push(extractStringValue(next(options.many, props)));\n\n // Ensure 'other' is always the last fallback if others are missing\n const otherVal = extractStringValue(\n next(options.other || options.fallback, props)\n );\n if (!msgstr.includes(otherVal)) msgstr.push(otherVal);\n } else {\n // Enums don't have standard PO mapping, pack linearly\n msgstr[0] = extractStringValue(\n next(options.fallback || options['0'], props)\n );\n msgstr[1] = msgstr[0];\n }\n\n return {\n msgctxt: isPlural ? undefined : 'enumeration',\n msgid,\n msgid_plural,\n msgstr,\n };\n }\n\n // 5. Gender (mapped to PO via msgctxt)\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const fallback = extractStringValue(next(options.fallback, props));\n return {\n msgctxt: 'gender',\n msgid: fallback,\n msgstr: [\n extractStringValue(next(options.male || options.fallback, props)),\n extractStringValue(next(options.female || options.fallback, props)),\n fallback,\n ],\n };\n }\n\n // 6. Arrays / Composites\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const combined = arr\n .map((item: any) => extractStringValue(next(item, props)))\n .join('');\n return { msgid: combined, msgstr: [combined] };\n }\n\n return node;\n },\n};\n\nconst poToIntlayerPlugin = {\n canHandle: (node: any) =>\n node && typeof node === 'object' && 'msgid' in node && 'msgstr' in node,\n\n transform: (node: PortableObject) => {\n const msgstr = node.msgstr || [];\n const isPlural = Boolean(node.msgid_plural) || msgstr.length > 1;\n\n const processString = (str: string) => {\n if (!str) return '';\n // Convert Python/C-style gettext variables %(name)s or %(name)d -> {{name}}\n const parsed = str.replace(/%\\(([a-zA-Z0-9_-]+)\\)[sdf]/g, '{{$1}}');\n\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(parsed)) return html(parsed);\n if (parsed.includes('{{')) return insert(parsed);\n return parsed;\n };\n\n // Fast-path: Single string translation\n if (!isPlural) {\n return processString(msgstr[0] || node.msgid || '');\n }\n\n // Handle Plural/Enum/Gender matrix\n const options: Record<string, any> = {};\n\n if (node.msgctxt === 'gender') {\n return gender({\n male: processString(msgstr[0] || node.msgid),\n female: processString(msgstr[1] || msgstr[0]),\n fallback: processString(msgstr[2] || msgstr[msgstr.length - 1]),\n });\n }\n\n if (node.msgctxt === 'enumeration') {\n return enu({\n '0': processString(msgstr[0]),\n fallback: processString(msgstr[msgstr.length - 1]),\n });\n }\n\n // Plural Form Mapping based on array length (Gettext Plural-Forms approximation)\n if (msgstr.length === 2) {\n options.one = processString(msgstr[0]);\n options.other = processString(msgstr[1]);\n } else if (msgstr.length === 3) {\n // E.g., Polish/Russian: one, few, many/other\n options.one = processString(msgstr[0]);\n options.few = processString(msgstr[1]);\n options.other = processString(msgstr[2]);\n } else if (msgstr.length === 6) {\n // E.g., Arabic: zero, one, two, few, many, other\n options.zero = processString(msgstr[0]);\n options.one = processString(msgstr[1]);\n options.two = processString(msgstr[2]);\n options.few = processString(msgstr[3]);\n options.many = processString(msgstr[4]);\n options.other = processString(msgstr[5]);\n } else {\n // Generic arbitrary length mapping\n options.one = processString(msgstr[0]);\n options.other = processString(msgstr[msgstr.length - 1]);\n for (let i = 1; i < msgstr.length - 1; i++) {\n options[`${i + 1}`] = processString(msgstr[i]);\n }\n }\n\n return plural(options as any);\n },\n};\n\nexport const intlayerToPortableObjectFormatter = (\n dictionary: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(dictionary, {\n dictionaryKey: 'po',\n keyPath: [],\n plugins: [{ id: 'po', ...intlayerToPoPlugin }],\n });\n};\n\nexport const portableObjectToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'po',\n keyPath: [],\n plugins: [{ id: 'po', ...poToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"verify-icu-format.cjs","names":["insert","intlayerToICUFormatter","enu","icuToIntlayerFormatter","gender"],"sources":["../../../src/messageFormat/verify-icu-format.ts"],"sourcesContent":["/**\n * Verification script to demonstrate ICU format conversion\n * This script shows that Intlayer correctly converts {{var}} (internal format)\n * to {var} (ICU format) when outputting.\n */\n\nimport { enu, gender, insert } from '../transpiler';\nimport { icuToIntlayerFormatter, intlayerToICUFormatter } from './ICU';\n\nconsole.log('=== ICU Format Verification ===\\n');\n\n// Test 1: Simple interpolation\nconsole.log('Test 1: Simple Interpolation');\nconsole.log('Intlayer input:', insert('Hello {{name}}'));\nconst test1 = intlayerToICUFormatter(insert('Hello {{name}}'));\nconsole.log('ICU output:', test1);\nconsole.log('✓ Expected: Single braces {name}');\nconsole.log(\n '✓ Result:',\n test1.includes('{name}') && !test1.includes('{{name}}') ? 'PASS' : 'FAIL'\n);\nconsole.log();\n\n// Test 2: Formatted variable\nconsole.log('Test 2: Formatted Variable');\nconsole.log('Intlayer input:', insert('Price: {amount, number, currency}'));\nconst test2 = intlayerToICUFormatter(\n insert('Price: {amount, number, currency}')\n);\nconsole.log('ICU output:', test2);\nconsole.log('✓ Expected: Single braces {amount, number, currency}');\nconsole.log(\n '✓ Result:',\n test2.includes('{amount, number, currency}') ? 'PASS' : 'FAIL'\n);\nconsole.log();\n\n// Test 3: Plural with variable\nconsole.log('Test 3: Plural with Variable');\nconst pluralInput = enu({\n '0': 'No items',\n '1': 'One item',\n fallback: '{{count}} items',\n});\nconsole.log('Intlayer input:', JSON.stringify(pluralInput, null, 2));\nconst test3 = intlayerToICUFormatter(pluralInput);\nconsole.log('ICU output:', test3);\nconsole.log('✓ Expected: {count, plural, ...} with # for count');\nconsole.log(\n '✓ Result:',\n test3.includes('{count, plural,') &&\n test3.includes('# items') &&\n !test3.includes('{{')\n ? 'PASS'\n : 'FAIL'\n);\nconsole.log();\n\n// Test 4: Roundtrip conversion\nconsole.log('Test 4: Roundtrip Conversion (ICU → Intlayer → ICU)');\nconst original =\n 'Hello {name}, you have {count, plural, =0 {no messages} =1 {one message} other {# messages}}';\nconsole.log('Original ICU:', original);\nconst toIntlayer = icuToIntlayerFormatter(original);\nconsole.log('Converted to Intlayer:', JSON.stringify(toIntlayer, null, 2));\nconst backToICU = intlayerToICUFormatter(toIntlayer);\nconsole.log('Back to ICU:', backToICU);\nconsole.log('✓ Expected: No {{...}} in output');\nconsole.log('✓ Result:', !String(backToICU).includes('{{') ? 'PASS' : 'FAIL');\nconsole.log();\n\n// Test 5: Gender with nested plural\nconsole.log('Test 5: Gender with Nested Structures');\nconst genderInput = gender({\n male: 'He has items',\n female: 'She has items',\n fallback: 'They have items',\n});\nconst test5 = intlayerToICUFormatter(genderInput);\nconsole.log('ICU output:', test5);\nconsole.log('✓ Expected: Single braces only');\nconsole.log('✓ Result:', !test5.includes('{{') ? 'PASS' : 'FAIL');\nconsole.log();\n\nconsole.log('=== Summary ===');\nconsole.log('ICU MessageFormat uses single braces: {var}');\nconsole.log('Intlayer internal format uses double braces: {{var}}');\nconsole.log('The conversion between these formats is handled automatically.');\n"],"mappings":";;;;;;;;;;;AASA,QAAQ,IAAI,oCAAoC;AAGhD,QAAQ,IAAI,+BAA+B;AAC3C,QAAQ,IAAI,mBAAmBA,8CAAO,iBAAiB,CAAC;AACxD,MAAM,QAAQC,iDAAuBD,8CAAO,iBAAiB,CAAC;AAC9D,QAAQ,IAAI,eAAe,MAAM;AACjC,QAAQ,IAAI,mCAAmC;AAC/C,QAAQ,IACN,aACA,MAAM,SAAS,SAAS,IAAI,CAAC,MAAM,SAAS,WAAW,GAAG,SAAS,OACpE;AACD,QAAQ,KAAK;AAGb,QAAQ,IAAI,6BAA6B;AACzC,QAAQ,IAAI,mBAAmBA,8CAAO,oCAAoC,CAAC;AAC3E,MAAM,QAAQC,iDACZD,8CAAO,oCAAoC,CAC5C;AACD,QAAQ,IAAI,eAAe,MAAM;AACjC,QAAQ,IAAI,uDAAuD;AACnE,QAAQ,IACN,aACA,MAAM,SAAS,6BAA6B,GAAG,SAAS,OACzD;AACD,QAAQ,KAAK;AAGb,QAAQ,IAAI,+BAA+B;AAC3C,MAAM,cAAcE,+CAAI;CACtB,KAAK;CACL,KAAK;CACL,UAAU;CACX,CAAC;AACF,QAAQ,IAAI,mBAAmB,KAAK,UAAU,aAAa,MAAM,EAAE,CAAC;AACpE,MAAM,QAAQD,iDAAuB,YAAY;AACjD,QAAQ,IAAI,eAAe,MAAM;AACjC,QAAQ,IAAI,oDAAoD;AAChE,QAAQ,IACN,aACA,MAAM,SAAS,kBAAkB,IAC/B,MAAM,SAAS,UAAU,IACzB,CAAC,MAAM,SAAS,KAAK,GACnB,SACA,OACL;AACD,QAAQ,KAAK;AAGb,QAAQ,IAAI,sDAAsD;AAClE,MAAM,WACJ;AACF,QAAQ,IAAI,iBAAiB,SAAS;AACtC,MAAM,aAAaE,iDAAuB,SAAS;AACnD,QAAQ,IAAI,0BAA0B,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;AAC1E,MAAM,YAAYF,iDAAuB,WAAW;AACpD,QAAQ,IAAI,gBAAgB,UAAU;AACtC,QAAQ,IAAI,mCAAmC;AAC/C,QAAQ,IAAI,aAAa,CAAC,OAAO,UAAU,CAAC,SAAS,KAAK,GAAG,SAAS,OAAO;AAC7E,QAAQ,KAAK;AAGb,QAAQ,IAAI,wCAAwC;AAMpD,MAAM,QAAQA,iDALMG,wCAAO;CACzB,MAAM;CACN,QAAQ;CACR,UAAU;CACX,CAC+C,CAAC;AACjD,QAAQ,IAAI,eAAe,MAAM;AACjC,QAAQ,IAAI,iCAAiC;AAC7C,QAAQ,IAAI,aAAa,CAAC,MAAM,SAAS,KAAK,GAAG,SAAS,OAAO;AACjE,QAAQ,KAAK;AAEb,QAAQ,IAAI,kBAAkB;AAC9B,QAAQ,IAAI,8CAA8C;AAC1D,QAAQ,IAAI,uDAAuD;AACnE,QAAQ,IAAI,iEAAiE"}
1
+ {"version":3,"file":"verify-icu-format.cjs","names":["insert","intlayerToICUFormatter","enu","icuToIntlayerFormatter","gender"],"sources":["../../../src/messageFormat/verify-icu-format.ts"],"sourcesContent":["/**\n * Verification script to demonstrate ICU format conversion\n * This script shows that Intlayer correctly converts {{var}} (internal format)\n * to {var} (ICU format) when outputting.\n */\n\nimport { enu, gender, insert } from '../transpiler';\nimport { icuToIntlayerFormatter, intlayerToICUFormatter } from './ICU';\n\nconsole.log('=== ICU Format Verification ===\\n');\n\n// Test 1: Simple interpolation\nconsole.log('Test 1: Simple Interpolation');\nconsole.log('Intlayer input:', insert('Hello {{name}}'));\nconst test1 = intlayerToICUFormatter(insert('Hello {{name}}'));\nconsole.log('ICU output:', test1);\nconsole.log('✓ Expected: Single braces {name}');\nconsole.log(\n '✓ Result:',\n test1.includes('{name}') && !test1.includes('{{name}}') ? 'PASS' : 'FAIL'\n);\nconsole.log();\n\n// Test 2: Formatted variable\nconsole.log('Test 2: Formatted Variable');\nconsole.log('Intlayer input:', insert('Price: {amount, number, currency}'));\nconst test2 = intlayerToICUFormatter(\n insert('Price: {amount, number, currency}')\n);\nconsole.log('ICU output:', test2);\nconsole.log('✓ Expected: Single braces {amount, number, currency}');\nconsole.log(\n '✓ Result:',\n test2.includes('{amount, number, currency}') ? 'PASS' : 'FAIL'\n);\nconsole.log();\n\n// Test 3: Plural with variable\nconsole.log('Test 3: Plural with Variable');\nconst pluralInput = enu({\n '0': 'No items',\n '1': 'One item',\n fallback: '{{count}} items',\n});\nconsole.log('Intlayer input:', JSON.stringify(pluralInput, null, 2));\nconst test3 = intlayerToICUFormatter(pluralInput);\nconsole.log('ICU output:', test3);\nconsole.log('✓ Expected: {count, plural, ...} with # for count');\nconsole.log(\n '✓ Result:',\n test3.includes('{count, plural,') &&\n test3.includes('# items') &&\n !test3.includes('{{')\n ? 'PASS'\n : 'FAIL'\n);\nconsole.log();\n\n// Test 4: Roundtrip conversion\nconsole.log('Test 4: Roundtrip Conversion (ICU → Intlayer → ICU)');\nconst original =\n 'Hello {name}, you have {count, plural, =0 {no messages} =1 {one message} other {# messages}}';\nconsole.log('Original ICU:', original);\nconst toIntlayer = icuToIntlayerFormatter(original);\nconsole.log('Converted to Intlayer:', JSON.stringify(toIntlayer, null, 2));\nconst backToICU = intlayerToICUFormatter(toIntlayer);\nconsole.log('Back to ICU:', backToICU);\nconsole.log('✓ Expected: No {{...}} in output');\nconsole.log('✓ Result:', !String(backToICU).includes('{{') ? 'PASS' : 'FAIL');\nconsole.log();\n\n// Test 5: Gender with nested plural\nconsole.log('Test 5: Gender with Nested Structures');\nconst genderInput = gender({\n male: 'He has items',\n female: 'She has items',\n fallback: 'They have items',\n});\nconst test5 = intlayerToICUFormatter(genderInput);\nconsole.log('ICU output:', test5);\nconsole.log('✓ Expected: Single braces only');\nconsole.log('✓ Result:', !test5.includes('{{') ? 'PASS' : 'FAIL');\nconsole.log();\n\nconsole.log('=== Summary ===');\nconsole.log('ICU MessageFormat uses single braces: {var}');\nconsole.log('Intlayer internal format uses double braces: {{var}}');\nconsole.log('The conversion between these formats is handled automatically.');\n"],"mappings":";;;;;;;;;;;AASA,QAAQ,IAAI,mCAAmC;AAG/C,QAAQ,IAAI,8BAA8B;AAC1C,QAAQ,IAAI,mBAAmBA,8CAAO,gBAAgB,CAAC;AACvD,MAAM,QAAQC,iDAAuBD,8CAAO,gBAAgB,CAAC;AAC7D,QAAQ,IAAI,eAAe,KAAK;AAChC,QAAQ,IAAI,kCAAkC;AAC9C,QAAQ,IACN,aACA,MAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,SAAS,UAAU,IAAI,SAAS,MACrE;AACA,QAAQ,IAAI;AAGZ,QAAQ,IAAI,4BAA4B;AACxC,QAAQ,IAAI,mBAAmBA,8CAAO,mCAAmC,CAAC;AAC1E,MAAM,QAAQC,iDACZD,8CAAO,mCAAmC,CAC5C;AACA,QAAQ,IAAI,eAAe,KAAK;AAChC,QAAQ,IAAI,sDAAsD;AAClE,QAAQ,IACN,aACA,MAAM,SAAS,4BAA4B,IAAI,SAAS,MAC1D;AACA,QAAQ,IAAI;AAGZ,QAAQ,IAAI,8BAA8B;AAC1C,MAAM,cAAcE,+CAAI;CACtB,KAAK;CACL,KAAK;CACL,UAAU;AACZ,CAAC;AACD,QAAQ,IAAI,mBAAmB,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AACnE,MAAM,QAAQD,iDAAuB,WAAW;AAChD,QAAQ,IAAI,eAAe,KAAK;AAChC,QAAQ,IAAI,mDAAmD;AAC/D,QAAQ,IACN,aACA,MAAM,SAAS,iBAAiB,KAC9B,MAAM,SAAS,SAAS,KACxB,CAAC,MAAM,SAAS,IAAI,IAClB,SACA,MACN;AACA,QAAQ,IAAI;AAGZ,QAAQ,IAAI,qDAAqD;AACjE,MAAM,WACJ;AACF,QAAQ,IAAI,iBAAiB,QAAQ;AACrC,MAAM,aAAaE,iDAAuB,QAAQ;AAClD,QAAQ,IAAI,0BAA0B,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;AACzE,MAAM,YAAYF,iDAAuB,UAAU;AACnD,QAAQ,IAAI,gBAAgB,SAAS;AACrC,QAAQ,IAAI,kCAAkC;AAC9C,QAAQ,IAAI,aAAa,CAAC,OAAO,SAAS,EAAE,SAAS,IAAI,IAAI,SAAS,MAAM;AAC5E,QAAQ,IAAI;AAGZ,QAAQ,IAAI,uCAAuC;AAMnD,MAAM,QAAQA,iDALMG,wCAAO;CACzB,MAAM;CACN,QAAQ;CACR,UAAU;AACZ,CAC+C,CAAC;AAChD,QAAQ,IAAI,eAAe,KAAK;AAChC,QAAQ,IAAI,gCAAgC;AAC5C,QAAQ,IAAI,aAAa,CAAC,MAAM,SAAS,IAAI,IAAI,SAAS,MAAM;AAChE,QAAQ,IAAI;AAEZ,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,6CAA6C;AACzD,QAAQ,IAAI,sDAAsD;AAClE,QAAQ,IAAI,gEAAgE"}
@@ -1 +1 @@
1
- {"version":3,"file":"vue-i18n.cjs","names":["insert","plural","enu","NodeTypes","deepTransformNode"],"sources":["../../../src/messageFormat/vue-i18n.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\n// Types for our AST\ntype VueI18nNode =\n | string\n | {\n type: 'argument';\n name: string;\n };\n\nconst parseVueI18nPart = (text: string): VueI18nNode[] => {\n let index = 0;\n const nodes: VueI18nNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n let name = '';\n while (index < text.length && text[index] !== '}') {\n name += text[index];\n index++;\n }\n if (index < text.length) {\n index++; // skip }\n }\n nodes.push({ type: 'argument', name: name.trim() });\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n\n return nodes;\n};\n\nconst parseVueI18n = (text: string): VueI18nNode[][] => {\n // Split by | but handle escaped \\|\n const parts: string[] = [];\n let currentPart = '';\n let index = 0;\n\n while (index < text.length) {\n const char = text[index];\n if (char === '\\\\' && index + 1 < text.length && text[index + 1] === '|') {\n currentPart += '|';\n index += 2;\n } else if (char === '|') {\n parts.push(currentPart.trim()); // Trim to remove surrounding spaces\n currentPart = '';\n index++;\n } else {\n currentPart += char;\n index++;\n }\n }\n parts.push(currentPart.trim()); // Trim last part too\n\n return parts.map(parseVueI18nPart);\n};\n\nconst vueI18nPartToIntlayer = (nodes: VueI18nNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') return nodes[0];\n\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else {\n str += `{{${node.name}}}`;\n }\n }\n return insert(str);\n};\n\nconst vueI18nNodesToIntlayer = (parts: VueI18nNode[][]): any => {\n if (parts.length === 1) {\n return vueI18nPartToIntlayer(parts[0]);\n }\n\n // Handle pluralization (choice)\n const options: Record<string, any> = {};\n const varName = 'count'; // Default variable for vue-i18n choices\n\n if (parts.length === 2) {\n // 2 choices: 1 | other\n return plural({\n one: vueI18nPartToIntlayer(parts[0]),\n other: vueI18nPartToIntlayer(parts[1]),\n });\n }\n\n if (parts.length === 3) {\n // 3 choices: 0 | 1 | other\n return plural({\n zero: vueI18nPartToIntlayer(parts[0]),\n one: vueI18nPartToIntlayer(parts[1]),\n other: vueI18nPartToIntlayer(parts[2]),\n });\n }\n\n // > 3 choices: 0 | 1 | 2 | ... | other\n parts.forEach((part, index) => {\n if (index === parts.length - 1) {\n options.fallback = vueI18nPartToIntlayer(part);\n } else {\n options[index.toString()] = vueI18nPartToIntlayer(part);\n }\n });\n\n // Preserve variable name\n options.__intlayer_vue_i18n_var = varName;\n\n return enu(options);\n};\n\nconst vueI18nToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' && (node.includes('{') || node.includes('|')),\n transform: (node: any) => {\n try {\n const ast = parseVueI18n(node);\n return vueI18nNodesToIntlayer(ast);\n } catch {\n return node;\n }\n },\n};\n\nconst intlayerToVueI18nPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n // replace {{...}} with {...} even in strings\n return node.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n // {{name}} -> {name}\n return node[NodeTypes.INSERTION].replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.PLURAL) {\n const options = node[NodeTypes.PLURAL];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n if (\n transformedOptions.zero &&\n transformedOptions.one &&\n transformedOptions.other\n ) {\n return `${transformedOptions.zero} | ${transformedOptions.one} | ${transformedOptions.other}`;\n }\n\n if (transformedOptions.one && transformedOptions.other) {\n return `${transformedOptions.one} | ${transformedOptions.other}`;\n }\n\n return transformedOptions.other || Object.values(transformedOptions)[0];\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_vue_i18n_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n const keys = Object.keys(transformedOptions);\n\n if (keys.includes('0')) {\n const indices = keys.filter((key) => /^\\d+$/.test(key)).map(Number);\n const maxIndex = Math.max(...indices);\n\n const fallback =\n transformedOptions.fallback || transformedOptions.other;\n const resultParts = [];\n\n if (maxIndex <= 1 && !keys.includes('2')) {\n const zero = transformedOptions['0'] || '';\n const one = transformedOptions['1'] || '';\n return `${zero} | ${one} | ${fallback}`;\n }\n\n const limit = Math.max(1, maxIndex);\n\n for (let i = 0; i <= limit; i++) {\n const key = i.toString();\n if (transformedOptions[key]) {\n resultParts.push(transformedOptions[key]);\n } else {\n resultParts.push('');\n }\n }\n resultParts.push(fallback);\n return resultParts.join(' | ').replace(/ \\| {2}\\| /g, ' | | ');\n }\n\n if (\n keys.includes('1') &&\n (keys.includes('fallback') || keys.includes('other'))\n ) {\n return `${transformedOptions['1']} | ${transformedOptions.fallback || transformedOptions.other}`;\n }\n\n if (\n keys.length === 1 &&\n (keys.includes('fallback') || keys.includes('other'))\n ) {\n return transformedOptions.fallback || transformedOptions.other;\n }\n\n return (\n transformedOptions.fallback || Object.values(transformedOptions)[0]\n );\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const transformedOptions: Record<string, any> = {};\n\n for (const [key, val] of Object.entries(options)) {\n let newKey = key;\n if (key === 'fallback') newKey = 'other';\n\n const childVal = next(val, props);\n transformedOptions[newKey] = childVal;\n }\n return transformedOptions;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToVueI18nFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'vue-i18n',\n keyPath: [],\n plugins: [{ id: 'vue-i18n', ...intlayerToVueI18nPlugin }],\n });\n};\n\nexport const vueI18nToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'vue-i18n',\n keyPath: [],\n plugins: [{ id: 'vue-i18n', ...vueI18nToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"vue-i18n.cjs","names":["insert","plural","enu","NodeTypes","deepTransformNode"],"sources":["../../../src/messageFormat/vue-i18n.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\n// Types for our AST\ntype VueI18nNode =\n | string\n | {\n type: 'argument';\n name: string;\n };\n\nconst parseVueI18nPart = (text: string): VueI18nNode[] => {\n let index = 0;\n const nodes: VueI18nNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n let name = '';\n while (index < text.length && text[index] !== '}') {\n name += text[index];\n index++;\n }\n if (index < text.length) {\n index++; // skip }\n }\n nodes.push({ type: 'argument', name: name.trim() });\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n\n return nodes;\n};\n\nconst parseVueI18n = (text: string): VueI18nNode[][] => {\n // Split by | but handle escaped \\|\n const parts: string[] = [];\n let currentPart = '';\n let index = 0;\n\n while (index < text.length) {\n const char = text[index];\n if (char === '\\\\' && index + 1 < text.length && text[index + 1] === '|') {\n currentPart += '|';\n index += 2;\n } else if (char === '|') {\n parts.push(currentPart.trim()); // Trim to remove surrounding spaces\n currentPart = '';\n index++;\n } else {\n currentPart += char;\n index++;\n }\n }\n parts.push(currentPart.trim()); // Trim last part too\n\n return parts.map(parseVueI18nPart);\n};\n\nconst vueI18nPartToIntlayer = (nodes: VueI18nNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') return nodes[0];\n\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else {\n str += `{{${node.name}}}`;\n }\n }\n return insert(str);\n};\n\nconst vueI18nNodesToIntlayer = (parts: VueI18nNode[][]): any => {\n if (parts.length === 1) {\n return vueI18nPartToIntlayer(parts[0]);\n }\n\n // Handle pluralization (choice)\n const options: Record<string, any> = {};\n const varName = 'count'; // Default variable for vue-i18n choices\n\n if (parts.length === 2) {\n // 2 choices: 1 | other\n return plural({\n one: vueI18nPartToIntlayer(parts[0]),\n other: vueI18nPartToIntlayer(parts[1]),\n });\n }\n\n if (parts.length === 3) {\n // 3 choices: 0 | 1 | other\n return plural({\n zero: vueI18nPartToIntlayer(parts[0]),\n one: vueI18nPartToIntlayer(parts[1]),\n other: vueI18nPartToIntlayer(parts[2]),\n });\n }\n\n // > 3 choices: 0 | 1 | 2 | ... | other\n parts.forEach((part, index) => {\n if (index === parts.length - 1) {\n options.fallback = vueI18nPartToIntlayer(part);\n } else {\n options[index.toString()] = vueI18nPartToIntlayer(part);\n }\n });\n\n // Preserve variable name\n options.__intlayer_vue_i18n_var = varName;\n\n return enu(options);\n};\n\nconst vueI18nToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' && (node.includes('{') || node.includes('|')),\n transform: (node: any) => {\n try {\n const ast = parseVueI18n(node);\n return vueI18nNodesToIntlayer(ast);\n } catch {\n return node;\n }\n },\n};\n\nconst intlayerToVueI18nPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n // replace {{...}} with {...} even in strings\n return node.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n // {{name}} -> {name}\n return node[NodeTypes.INSERTION].replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.PLURAL) {\n const options = node[NodeTypes.PLURAL];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n if (\n transformedOptions.zero &&\n transformedOptions.one &&\n transformedOptions.other\n ) {\n return `${transformedOptions.zero} | ${transformedOptions.one} | ${transformedOptions.other}`;\n }\n\n if (transformedOptions.one && transformedOptions.other) {\n return `${transformedOptions.one} | ${transformedOptions.other}`;\n }\n\n return transformedOptions.other || Object.values(transformedOptions)[0];\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_vue_i18n_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n const keys = Object.keys(transformedOptions);\n\n if (keys.includes('0')) {\n const indices = keys.filter((key) => /^\\d+$/.test(key)).map(Number);\n const maxIndex = Math.max(...indices);\n\n const fallback =\n transformedOptions.fallback || transformedOptions.other;\n const resultParts = [];\n\n if (maxIndex <= 1 && !keys.includes('2')) {\n const zero = transformedOptions['0'] || '';\n const one = transformedOptions['1'] || '';\n return `${zero} | ${one} | ${fallback}`;\n }\n\n const limit = Math.max(1, maxIndex);\n\n for (let i = 0; i <= limit; i++) {\n const key = i.toString();\n if (transformedOptions[key]) {\n resultParts.push(transformedOptions[key]);\n } else {\n resultParts.push('');\n }\n }\n resultParts.push(fallback);\n return resultParts.join(' | ').replace(/ \\| {2}\\| /g, ' | | ');\n }\n\n if (\n keys.includes('1') &&\n (keys.includes('fallback') || keys.includes('other'))\n ) {\n return `${transformedOptions['1']} | ${transformedOptions.fallback || transformedOptions.other}`;\n }\n\n if (\n keys.length === 1 &&\n (keys.includes('fallback') || keys.includes('other'))\n ) {\n return transformedOptions.fallback || transformedOptions.other;\n }\n\n return (\n transformedOptions.fallback || Object.values(transformedOptions)[0]\n );\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const transformedOptions: Record<string, any> = {};\n\n for (const [key, val] of Object.entries(options)) {\n let newKey = key;\n if (key === 'fallback') newKey = 'other';\n\n const childVal = next(val, props);\n transformedOptions[newKey] = childVal;\n }\n return transformedOptions;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToVueI18nFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'vue-i18n',\n keyPath: [],\n plugins: [{ id: 'vue-i18n', ...intlayerToVueI18nPlugin }],\n });\n};\n\nexport const vueI18nToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'vue-i18n',\n keyPath: [],\n plugins: [{ id: 'vue-i18n', ...vueI18nToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"condition.cjs","names":["CONDITION"],"sources":["../../../../src/transpiler/condition/condition.ts"],"sourcesContent":["import type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { CONDITION, formatNodeType } from '@intlayer/types/nodeType';\n\nexport type ConditionContentStates<Content> = Record<`${boolean}`, Content> & {\n fallback?: Content;\n};\n\nexport type ConditionContent<Content = unknown> = TypedNodeModel<\n typeof CONDITION,\n ConditionContentStates<Content>\n>;\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow to pick a content based on a condition.\n *\n * Usage:\n *\n * ```ts\n * cond({\n * 'true': 'The condition is validated',\n * 'false': 'The condition is not validated',\n * });\n * ```\n *\n * The last key provided will be used as the fallback value.\n *\n */\nconst condition = <Content>(\n content?: ConditionContentStates<Content>\n): ConditionContent<Content> => formatNodeType(CONDITION, content);\n\nexport { condition as cond };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAM,aACJ,yDAC6CA,oCAAW,QAAQ"}
1
+ {"version":3,"file":"condition.cjs","names":["CONDITION"],"sources":["../../../../src/transpiler/condition/condition.ts"],"sourcesContent":["import type { TypedNodeModel } from '@intlayer/types/nodeType';\nimport { CONDITION, formatNodeType } from '@intlayer/types/nodeType';\n\nexport type ConditionContentStates<Content> = Record<`${boolean}`, Content> & {\n fallback?: Content;\n};\n\nexport type ConditionContent<Content = unknown> = TypedNodeModel<\n typeof CONDITION,\n ConditionContentStates<Content>\n>;\n\n/**\n * Function intended to be used to build intlayer dictionaries.\n *\n * Allow to pick a content based on a condition.\n *\n * Usage:\n *\n * ```ts\n * cond({\n * 'true': 'The condition is validated',\n * 'false': 'The condition is not validated',\n * });\n * ```\n *\n * The last key provided will be used as the fallback value.\n *\n */\nconst condition = <Content>(\n content?: ConditionContentStates<Content>\n): ConditionContent<Content> => formatNodeType(CONDITION, content);\n\nexport { condition as cond };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAM,aACJ,yDAC6CA,oCAAW,OAAO"}