@intlayer/core 8.12.4 → 9.0.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 (177) hide show
  1. package/dist/cjs/deepTransformPlugins/getEditedContent.cjs +96 -0
  2. package/dist/cjs/deepTransformPlugins/getEditedContent.cjs.map +1 -0
  3. package/dist/cjs/deepTransformPlugins/index.cjs +3 -0
  4. package/dist/cjs/dictionaryManipulator/index.cjs +18 -0
  5. package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs +4 -1
  6. package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs.map +1 -1
  7. package/dist/cjs/dictionaryManipulator/mergeQualifiedDictionaries.cjs +70 -0
  8. package/dist/cjs/dictionaryManipulator/mergeQualifiedDictionaries.cjs.map +1 -0
  9. package/dist/cjs/dictionaryManipulator/qualifiedDictionary.cjs +302 -0
  10. package/dist/cjs/dictionaryManipulator/qualifiedDictionary.cjs.map +1 -0
  11. package/dist/cjs/index.cjs +26 -0
  12. package/dist/cjs/interpreter/getCollection.cjs +25 -0
  13. package/dist/cjs/interpreter/getCollection.cjs.map +1 -0
  14. package/dist/cjs/interpreter/getDictionary.cjs +26 -11
  15. package/dist/cjs/interpreter/getDictionary.cjs.map +1 -1
  16. package/dist/cjs/interpreter/getIntlayer.cjs +16 -3
  17. package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
  18. package/dist/cjs/interpreter/getVariant.cjs +30 -0
  19. package/dist/cjs/interpreter/getVariant.cjs.map +1 -0
  20. package/dist/cjs/localization/getBrowserLocale.cjs +1 -1
  21. package/dist/cjs/localization/getBrowserLocale.cjs.map +1 -1
  22. package/dist/cjs/messageFormat/ICU.cjs +32 -2
  23. package/dist/cjs/messageFormat/ICU.cjs.map +1 -1
  24. package/dist/cjs/messageFormat/i18next.cjs +1 -1
  25. package/dist/cjs/messageFormat/i18next.cjs.map +1 -1
  26. package/dist/cjs/messageFormat/index.cjs +5 -0
  27. package/dist/cjs/messageFormat/resolveMessage.cjs +183 -0
  28. package/dist/cjs/messageFormat/resolveMessage.cjs.map +1 -0
  29. package/dist/cjs/messageFormat/vue-i18n.cjs +8 -9
  30. package/dist/cjs/messageFormat/vue-i18n.cjs.map +1 -1
  31. package/dist/cjs/transpiler/collection/collection.cjs +32 -0
  32. package/dist/cjs/transpiler/collection/collection.cjs.map +1 -0
  33. package/dist/cjs/transpiler/collection/index.cjs +4 -0
  34. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs +2 -3
  35. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs.map +1 -1
  36. package/dist/cjs/transpiler/variant/index.cjs +4 -0
  37. package/dist/cjs/transpiler/variant/variant.cjs +35 -0
  38. package/dist/cjs/transpiler/variant/variant.cjs.map +1 -0
  39. package/dist/cjs/utils/parseYaml.cjs +37 -17
  40. package/dist/cjs/utils/parseYaml.cjs.map +1 -1
  41. package/dist/esm/deepTransformPlugins/getEditedContent.mjs +92 -0
  42. package/dist/esm/deepTransformPlugins/getEditedContent.mjs.map +1 -0
  43. package/dist/esm/deepTransformPlugins/index.mjs +2 -1
  44. package/dist/esm/dictionaryManipulator/index.mjs +3 -1
  45. package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs +4 -1
  46. package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs.map +1 -1
  47. package/dist/esm/dictionaryManipulator/mergeQualifiedDictionaries.mjs +68 -0
  48. package/dist/esm/dictionaryManipulator/mergeQualifiedDictionaries.mjs.map +1 -0
  49. package/dist/esm/dictionaryManipulator/qualifiedDictionary.mjs +286 -0
  50. package/dist/esm/dictionaryManipulator/qualifiedDictionary.mjs.map +1 -0
  51. package/dist/esm/index.mjs +5 -1
  52. package/dist/esm/interpreter/getCollection.mjs +23 -0
  53. package/dist/esm/interpreter/getCollection.mjs.map +1 -0
  54. package/dist/esm/interpreter/getDictionary.mjs +26 -11
  55. package/dist/esm/interpreter/getDictionary.mjs.map +1 -1
  56. package/dist/esm/interpreter/getIntlayer.mjs +16 -3
  57. package/dist/esm/interpreter/getIntlayer.mjs.map +1 -1
  58. package/dist/esm/interpreter/getVariant.mjs +28 -0
  59. package/dist/esm/interpreter/getVariant.mjs.map +1 -0
  60. package/dist/esm/localization/getBrowserLocale.mjs +1 -1
  61. package/dist/esm/localization/getBrowserLocale.mjs.map +1 -1
  62. package/dist/esm/messageFormat/ICU.mjs +32 -2
  63. package/dist/esm/messageFormat/ICU.mjs.map +1 -1
  64. package/dist/esm/messageFormat/i18next.mjs +1 -1
  65. package/dist/esm/messageFormat/i18next.mjs.map +1 -1
  66. package/dist/esm/messageFormat/index.mjs +2 -1
  67. package/dist/esm/messageFormat/resolveMessage.mjs +177 -0
  68. package/dist/esm/messageFormat/resolveMessage.mjs.map +1 -0
  69. package/dist/esm/messageFormat/vue-i18n.mjs +8 -9
  70. package/dist/esm/messageFormat/vue-i18n.mjs.map +1 -1
  71. package/dist/esm/transpiler/collection/collection.mjs +30 -0
  72. package/dist/esm/transpiler/collection/collection.mjs.map +1 -0
  73. package/dist/esm/transpiler/collection/index.mjs +3 -0
  74. package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs +2 -3
  75. package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs.map +1 -1
  76. package/dist/esm/transpiler/variant/index.mjs +3 -0
  77. package/dist/esm/transpiler/variant/variant.mjs +33 -0
  78. package/dist/esm/transpiler/variant/variant.mjs.map +1 -0
  79. package/dist/esm/utils/parseYaml.mjs +37 -17
  80. package/dist/esm/utils/parseYaml.mjs.map +1 -1
  81. package/dist/types/@intlayer/core/dist/types/formatters/compact.d.ts +1 -0
  82. package/dist/types/@intlayer/core/dist/types/formatters/currency.d.ts +1 -0
  83. package/dist/types/@intlayer/core/dist/types/formatters/date.d.ts +1 -0
  84. package/dist/types/@intlayer/core/dist/types/formatters/index.d.ts +1 -0
  85. package/dist/types/@intlayer/core/dist/types/formatters/list.d.ts +1 -0
  86. package/dist/types/@intlayer/core/dist/types/formatters/number.d.ts +1 -0
  87. package/dist/types/@intlayer/core/dist/types/formatters/percentage.d.ts +1 -0
  88. package/dist/types/@intlayer/core/dist/types/formatters/relativeTime.d.ts +1 -0
  89. package/dist/types/@intlayer/core/dist/types/formatters/units.d.ts +1 -0
  90. package/dist/types/@intlayer/core/dist/types/interpreter/getCondition.d.ts +1 -0
  91. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/deepTransform.d.ts +1 -0
  92. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/getContent.d.ts +2 -0
  93. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/plugins.d.ts +4 -0
  94. package/dist/types/@intlayer/core/dist/types/interpreter/getDictionary.d.ts +2 -0
  95. package/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
  96. package/dist/types/@intlayer/core/dist/types/interpreter/getIntlayer.d.ts +2 -0
  97. package/dist/types/@intlayer/core/dist/types/interpreter/getNesting.d.ts +2 -0
  98. package/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
  99. package/dist/types/@intlayer/core/dist/types/interpreter/getTranslation.d.ts +1 -0
  100. package/dist/types/@intlayer/core/dist/types/interpreter/getVariant.d.ts +1 -0
  101. package/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +1 -0
  102. package/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +1 -0
  103. package/dist/types/@intlayer/core/dist/types/localization/generateSitemap.d.ts +2 -0
  104. package/dist/types/@intlayer/core/dist/types/localization/getBrowserLocale.d.ts +1 -0
  105. package/dist/types/@intlayer/core/dist/types/localization/getHTMLTextDir.d.ts +1 -0
  106. package/dist/types/@intlayer/core/dist/types/localization/getLocale.d.ts +1 -0
  107. package/dist/types/@intlayer/core/dist/types/localization/getLocaleFromPath.d.ts +1 -0
  108. package/dist/types/@intlayer/core/dist/types/localization/getLocaleLang.d.ts +1 -0
  109. package/dist/types/@intlayer/core/dist/types/localization/getLocaleName.d.ts +1 -0
  110. package/dist/types/@intlayer/core/dist/types/localization/getLocalizedUrl.d.ts +1 -0
  111. package/dist/types/@intlayer/core/dist/types/localization/getMultilingualUrls.d.ts +1 -0
  112. package/dist/types/@intlayer/core/dist/types/localization/getPathWithoutLocale.d.ts +1 -0
  113. package/dist/types/@intlayer/core/dist/types/localization/getPrefix.d.ts +3 -0
  114. package/dist/types/@intlayer/core/dist/types/localization/index.d.ts +1 -0
  115. package/dist/types/@intlayer/core/dist/types/localization/localeDetector.d.ts +1 -0
  116. package/dist/types/@intlayer/core/dist/types/localization/localeMapper.d.ts +2 -0
  117. package/dist/types/@intlayer/core/dist/types/localization/localeResolver.d.ts +2 -0
  118. package/dist/types/@intlayer/core/dist/types/localization/rewriteUtils.d.ts +3 -0
  119. package/dist/types/@intlayer/core/dist/types/localization/validatePrefix.d.ts +1 -0
  120. package/dist/types/@intlayer/core/dist/types/markdown/index.d.ts +1 -0
  121. package/dist/types/@intlayer/core/dist/types/transpiler/collection/collection.d.ts +1 -0
  122. package/dist/types/@intlayer/core/dist/types/transpiler/condition/condition.d.ts +1 -0
  123. package/dist/types/@intlayer/core/dist/types/transpiler/enumeration/enumeration.d.ts +1 -0
  124. package/dist/types/@intlayer/core/dist/types/transpiler/file/file.d.ts +1 -0
  125. package/dist/types/@intlayer/core/dist/types/transpiler/gender/gender.d.ts +1 -0
  126. package/dist/types/@intlayer/core/dist/types/transpiler/html/html.d.ts +1 -0
  127. package/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +1 -0
  128. package/dist/types/@intlayer/core/dist/types/transpiler/insertion/insertion.d.ts +1 -0
  129. package/dist/types/@intlayer/core/dist/types/transpiler/markdown/markdown.d.ts +1 -0
  130. package/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +2 -0
  131. package/dist/types/@intlayer/core/dist/types/transpiler/plural/plural.d.ts +1 -0
  132. package/dist/types/@intlayer/core/dist/types/transpiler/translation/translation.d.ts +2 -0
  133. package/dist/types/@intlayer/core/dist/types/transpiler/variant/variant.d.ts +1 -0
  134. package/dist/types/@intlayer/core/dist/types/utils/index.d.ts +1 -0
  135. package/dist/types/@intlayer/core/dist/types/utils/intl.d.ts +1 -0
  136. package/dist/types/@intlayer/core/dist/types/utils/isSameKeyPath.d.ts +1 -0
  137. package/dist/types/@intlayer/core/dist/types/utils/localeStorage.d.ts +2 -0
  138. package/dist/types/deepTransformPlugins/getEditedContent.d.ts +33 -0
  139. package/dist/types/deepTransformPlugins/getEditedContent.d.ts.map +1 -0
  140. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +6 -3
  141. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts.map +1 -1
  142. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +6 -3
  143. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts.map +1 -1
  144. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +4 -1
  145. package/dist/types/deepTransformPlugins/index.d.ts +2 -1
  146. package/dist/types/dictionaryManipulator/index.d.ts +3 -1
  147. package/dist/types/dictionaryManipulator/mergeQualifiedDictionaries.d.ts +22 -0
  148. package/dist/types/dictionaryManipulator/mergeQualifiedDictionaries.d.ts.map +1 -0
  149. package/dist/types/dictionaryManipulator/qualifiedDictionary.d.ts +176 -0
  150. package/dist/types/dictionaryManipulator/qualifiedDictionary.d.ts.map +1 -0
  151. package/dist/types/index.d.ts +6 -2
  152. package/dist/types/interpreter/getCollection.d.ts +19 -0
  153. package/dist/types/interpreter/getCollection.d.ts.map +1 -0
  154. package/dist/types/interpreter/getDictionary.d.ts +13 -7
  155. package/dist/types/interpreter/getDictionary.d.ts.map +1 -1
  156. package/dist/types/interpreter/getIntlayer.d.ts +13 -2
  157. package/dist/types/interpreter/getIntlayer.d.ts.map +1 -1
  158. package/dist/types/interpreter/getPlural.d.ts +1 -1
  159. package/dist/types/interpreter/getVariant.d.ts +26 -0
  160. package/dist/types/interpreter/getVariant.d.ts.map +1 -0
  161. package/dist/types/intlayer/dist/types/index.d.ts +4 -0
  162. package/dist/types/messageFormat/ICU.d.ts.map +1 -1
  163. package/dist/types/messageFormat/i18next.d.ts.map +1 -1
  164. package/dist/types/messageFormat/index.d.ts +2 -1
  165. package/dist/types/messageFormat/resolveMessage.d.ts +72 -0
  166. package/dist/types/messageFormat/resolveMessage.d.ts.map +1 -0
  167. package/dist/types/messageFormat/vue-i18n.d.ts.map +1 -1
  168. package/dist/types/transpiler/collection/collection.d.ts +34 -0
  169. package/dist/types/transpiler/collection/collection.d.ts.map +1 -0
  170. package/dist/types/transpiler/collection/index.d.ts +2 -0
  171. package/dist/types/transpiler/variant/index.d.ts +2 -0
  172. package/dist/types/transpiler/variant/variant.d.ts +43 -0
  173. package/dist/types/transpiler/variant/variant.d.ts.map +1 -0
  174. package/dist/types/utils/index.d.ts +2 -2
  175. package/dist/types/utils/parseYaml.d.ts +12 -2
  176. package/dist/types/utils/parseYaml.d.ts.map +1 -1
  177. package/package.json +7 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveMessage.mjs","names":[],"sources":["../../../src/messageFormat/resolveMessage.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { getCachedIntl } from '../formatters';\nimport { getEnumeration } from '../interpreter/getEnumeration';\nimport { getPlural } from '../interpreter/getPlural';\nimport type { PluralContentState } from '../transpiler/plural/plural';\nimport { icuToIntlayerFormatter } from './ICU';\nimport { i18nextToIntlayerFormatter } from './i18next';\nimport { vueI18nToIntlayerFormatter } from './vue-i18n';\n\n/**\n * Runtime counterpart of the `messageFormat` converters.\n *\n * The converters (`icuToIntlayerFormatter`, `i18nextToIntlayerFormatter`,\n * `vueI18nToIntlayerFormatter`) turn library-specific message syntax into\n * intlayer nodes (`insert`, `plural`, `enu`, `gender`, `html`). This module\n * resolves those nodes — or raw message strings — into a final string using\n * the provided interpolation values and locale.\n *\n * It is the mutualized resolution engine used by the compat adapter packages\n * (`@intlayer/i18next`, `@intlayer/next-intl`, `@intlayer/vue-i18n`, …).\n */\n\n/** Message syntax dialect of the source i18n library. */\nexport type MessageFormatDialect = 'icu' | 'i18next' | 'vue-i18n';\n\n/** Interpolation values passed alongside a translation lookup. */\nexport type MessageValues = Record<string, unknown>;\n\n/** Internal enumeration metadata keys injected by the converters. */\nconst ENUMERATION_METADATA_KEYS = [\n '__intlayer_icu_var',\n '__intlayer_icu_ordinal',\n '__intlayer_vue_i18n_var',\n] as const;\n\n/**\n * Resolves a possibly-dotted path (`user.name`) inside the values object.\n */\nconst resolveValuePath = (values: MessageValues, path: string): unknown => {\n if (path in values) return values[path];\n\n let current: unknown = values;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/** Formats an ICU-style formatted argument (`{value, number, percent}`). */\nconst formatArgument = (\n value: unknown,\n type: string,\n style: string | undefined,\n locale: LocalesValues\n): string => {\n try {\n if (type === 'number') {\n const numberValue = Number(value);\n if (style === 'percent') {\n return getCachedIntl(Intl.NumberFormat, locale, {\n style: 'percent',\n }).format(numberValue);\n }\n if (style === 'integer') {\n return getCachedIntl(Intl.NumberFormat, locale, {\n maximumFractionDigits: 0,\n }).format(numberValue);\n }\n return getCachedIntl(Intl.NumberFormat, locale).format(numberValue);\n }\n\n if (type === 'date' || type === 'time') {\n const dateValue =\n value instanceof Date ? value : new Date(value as string | number);\n const dateTimeStyle = (\n ['short', 'medium', 'long', 'full'].includes(style ?? '')\n ? style\n : type === 'date'\n ? 'medium'\n : 'short'\n ) as 'short' | 'medium' | 'long' | 'full';\n\n return getCachedIntl(\n Intl.DateTimeFormat,\n locale,\n type === 'date'\n ? { dateStyle: dateTimeStyle }\n : { timeStyle: dateTimeStyle }\n ).format(dateValue);\n }\n } catch {\n // Fall through to the raw string representation below\n }\n\n return String(value);\n};\n\n/**\n * Interpolates a message template with values.\n *\n * Handles, in order:\n * 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths)\n * 2. ICU formatted arguments `{value, number}` / `{ts, date, long}`\n * 3. Bare single-brace arguments `{name}` (ICU / vue-i18n simple args)\n */\nexport const interpolateMessage = (\n template: string,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): string =>\n template\n .replace(/\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g, (match, path: string) => {\n const value = resolveValuePath(values, path);\n return value === undefined ? match : String(value);\n })\n .replace(\n /\\{\\s*([\\w.]+)\\s*,\\s*(\\w+)\\s*(?:,\\s*([^}]+?)\\s*)?\\}/g,\n (match, path: string, type: string, style: string | undefined) => {\n const value = resolveValuePath(values, path);\n if (value === undefined) return match;\n return formatArgument(value, type, style, locale);\n }\n )\n .replace(/\\{\\s*([\\w.]+)\\s*\\}/g, (match, path: string) => {\n const value = resolveValuePath(values, path);\n return value === undefined ? match : String(value);\n });\n\n/** Reads the selector value of an enumeration/plural node from the values. */\nconst getSelectorValue = (\n values: MessageValues,\n variableName: string\n): unknown => values[variableName] ?? values.count ?? values.n;\n\n/**\n * Resolves an intlayer message node tree (as produced by the\n * `*ToIntlayerFormatter` converters, or already present in a built\n * dictionary) into its final value using interpolation values and locale.\n *\n * Function nodes (produced by the interpreter plugins for `insertion`,\n * `enumeration` and `plural` content) are invoked with the values.\n */\nexport const resolveMessageNode = (\n node: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): unknown => {\n if (node === null || node === undefined) return node;\n\n if (typeof node === 'string') {\n return interpolateMessage(node, values, locale);\n }\n\n if (typeof node === 'number' || typeof node === 'boolean') {\n return String(node);\n }\n\n // Interpreter-transformed nodes (insertion/enumeration/plural plugins)\n // are exposed as callables taking the interpolation values.\n if (typeof node === 'function') {\n try {\n return resolveMessageNode(\n (node as (arg: MessageValues) => unknown)(values),\n values,\n locale\n );\n } catch {\n return undefined;\n }\n }\n\n if (Array.isArray(node)) {\n return node\n .map((item) => String(resolveMessageNode(item, values, locale) ?? ''))\n .join('');\n }\n\n const typedNode = node as Record<string, unknown> & { nodeType?: string };\n\n if (typedNode.nodeType === NodeTypes.INSERTION) {\n return resolveMessageNode(typedNode[NodeTypes.INSERTION], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.HTML) {\n // Tags are kept intact — rich rendering is handled by the caller\n return resolveMessageNode(typedNode[NodeTypes.HTML], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.PLURAL) {\n const pluralState = typedNode[\n NodeTypes.PLURAL\n ] as PluralContentState<unknown>;\n const count = Number(getSelectorValue(values, 'count') ?? 1);\n const selected = getPlural(\n pluralState as PluralContentState<string>,\n count,\n locale\n );\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.ENUMERATION) {\n const enumerationState = typedNode[NodeTypes.ENUMERATION] as Record<\n string,\n unknown\n >;\n\n const variableName = (ENUMERATION_METADATA_KEYS.map(\n (metadataKey) => enumerationState[metadataKey]\n ).find((name) => typeof name === 'string') ?? 'count') as string;\n\n const isOrdinal = enumerationState.__intlayer_icu_ordinal === true;\n\n const options: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(enumerationState)) {\n if (!(ENUMERATION_METADATA_KEYS as readonly string[]).includes(key)) {\n options[key] = value;\n }\n }\n\n const selector = getSelectorValue(values, variableName);\n\n let selected: unknown;\n if (isOrdinal && !Number.isNaN(Number(selector))) {\n // ICU `selectordinal` — exact numeric match first, then the CLDR\n // ordinal category, then the fallback\n const ordinalCount = Number(selector);\n const ordinalCategory = getCachedIntl(Intl.PluralRules, locale, {\n type: 'ordinal',\n }).select(ordinalCount);\n selected =\n options[String(ordinalCount)] ??\n options[ordinalCategory] ??\n options.fallback ??\n options.other;\n } else if (\n typeof selector === 'number' ||\n !Number.isNaN(Number(selector))\n ) {\n selected = getEnumeration(options, Number(selector));\n } else {\n // String selector — ICU `select` converted to an enumeration\n selected = options[String(selector)] ?? options.fallback ?? options.other;\n }\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.GENDER) {\n const genderState = typedNode[NodeTypes.GENDER] as Record<string, unknown>;\n const genderValue = String(values.gender ?? '');\n const selected =\n genderState[genderValue] ?? genderState.fallback ?? genderState.other;\n return resolveMessageNode(selected, values, locale);\n }\n\n return node;\n};\n\nconst DIALECT_FORMATTERS: Record<\n MessageFormatDialect,\n (message: string) => unknown\n> = {\n icu: (message) => icuToIntlayerFormatter(message),\n i18next: (message) => i18nextToIntlayerFormatter(message),\n 'vue-i18n': (message) => vueI18nToIntlayerFormatter(message),\n};\n\n/**\n * Resolves a raw message — string in a library dialect, or an intlayer node\n * tree — into a final string using interpolation values and locale.\n *\n * @example\n * ```ts\n * resolveMessage('Hello {name}', { name: 'John' }, 'en', 'icu');\n * // 'Hello John'\n *\n * resolveMessage(\n * '{count, plural, one {# item} other {# items}}',\n * { count: 3 },\n * 'en',\n * 'icu'\n * );\n * // '3 items'\n * ```\n */\nexport const resolveMessage = (\n message: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues,\n dialect: MessageFormatDialect = 'icu'\n): string => {\n const node =\n typeof message === 'string'\n ? DIALECT_FORMATTERS[dialect](message)\n : message;\n\n const resolved = resolveMessageNode(node, values, locale);\n\n return typeof resolved === 'string' ? resolved : String(resolved ?? '');\n};\n\n/** A parsed token of a tagged message: plain text or a tag with children. */\nexport type TaggedMessageToken =\n | string\n | { tag: string; children: TaggedMessageToken[] };\n\n/**\n * Tokenizes a message containing XML-like tags (`'Visit <link>the docs</link>'`,\n * `'hello <1>{{name}}</1>'`, `'line<br/>break'`) into a token tree.\n *\n * Used by rich-text renderers (`t.rich`, `<Trans components>`,\n * `<i18n-t>` slots) to map tags to framework elements.\n */\nexport const parseTaggedMessage = (message: string): TaggedMessageToken[] => {\n const tokens: TaggedMessageToken[] = [];\n const tagRegex = /<([\\w-]+)\\s*\\/>|<([\\w-]+)[^>]*>([\\s\\S]*?)<\\/\\2>/g;\n let lastIndex = 0;\n let match = tagRegex.exec(message);\n\n while (match !== null) {\n if (match.index > lastIndex) {\n tokens.push(message.slice(lastIndex, match.index));\n }\n\n const [, selfClosingTag, tag, inner] = match;\n\n if (selfClosingTag) {\n tokens.push({ tag: selfClosingTag, children: [] });\n } else {\n tokens.push({ tag, children: parseTaggedMessage(inner) });\n }\n\n lastIndex = match.index + match[0].length;\n match = tagRegex.exec(message);\n }\n\n if (lastIndex < message.length) {\n tokens.push(message.slice(lastIndex));\n }\n\n return tokens;\n};\n"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  import { deepTransformNode } from "../interpreter/getContent/deepTransform.mjs";
2
2
  import { enu as enumeration } from "../transpiler/enumeration/enumeration.mjs";
3
3
  import { insert as insertion } from "../transpiler/insertion/insertion.mjs";
4
- import { plural } from "../transpiler/plural/plural.mjs";
5
4
  import * as NodeTypes from "@intlayer/types/nodeType";
6
5
 
7
6
  //#region src/messageFormat/vue-i18n.ts
@@ -68,14 +67,14 @@ const vueI18nNodesToIntlayer = (parts) => {
68
67
  if (parts.length === 1) return vueI18nPartToIntlayer(parts[0]);
69
68
  const options = {};
70
69
  const varName = "count";
71
- if (parts.length === 2) return plural({
72
- one: vueI18nPartToIntlayer(parts[0]),
73
- other: vueI18nPartToIntlayer(parts[1])
70
+ if (parts.length === 2) return enumeration({
71
+ "1": vueI18nPartToIntlayer(parts[0]),
72
+ fallback: vueI18nPartToIntlayer(parts[1])
74
73
  });
75
- if (parts.length === 3) return plural({
76
- zero: vueI18nPartToIntlayer(parts[0]),
77
- one: vueI18nPartToIntlayer(parts[1]),
78
- other: vueI18nPartToIntlayer(parts[2])
74
+ if (parts.length === 3) return enumeration({
75
+ "0": vueI18nPartToIntlayer(parts[0]),
76
+ "1": vueI18nPartToIntlayer(parts[1]),
77
+ fallback: vueI18nPartToIntlayer(parts[2])
79
78
  });
80
79
  parts.forEach((part, index) => {
81
80
  if (index === parts.length - 1) options.fallback = vueI18nPartToIntlayer(part);
@@ -128,7 +127,7 @@ const intlayerToVueI18nPlugin = {
128
127
  const options = node[NodeTypes.ENUMERATION];
129
128
  const transformedOptions = {};
130
129
  for (const [key, val] of Object.entries(options)) {
131
- if (key === "__intlayer_vue_i18n_var") continue;
130
+ if (key === "__intlayer_vue_i18n_var" || key === "__intlayer_icu_var" || key === "__intlayer_icu_ordinal") continue;
132
131
  const childVal = next(val, props);
133
132
  transformedOptions[key] = typeof childVal === "string" ? childVal : JSON.stringify(childVal);
134
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vue-i18n.mjs","names":["insert","enu"],"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.mjs","names":["insert","enu"],"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 } 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 // vue-i18n's choice rule is POSITIONAL (0 | 1 | other), not CLDR-based:\n // an enumeration node preserves those semantics in every locale, whereas\n // a plural node would select by CLDR category (e.g. count 0 resolves to\n // 'one' in French, 'other' in English — never 'zero').\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 enu({\n '1': vueI18nPartToIntlayer(parts[0]),\n fallback: vueI18nPartToIntlayer(parts[1]),\n });\n }\n\n if (parts.length === 3) {\n // 3 choices: 0 | 1 | other\n return enu({\n '0': vueI18nPartToIntlayer(parts[0]),\n '1': vueI18nPartToIntlayer(parts[1]),\n fallback: 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 (\n key === '__intlayer_vue_i18n_var' ||\n key === '__intlayer_icu_var' ||\n key === '__intlayer_icu_ordinal'\n )\n 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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"}
@@ -0,0 +1,30 @@
1
+ import { COLLECTION } from "@intlayer/types/nodeType";
2
+
3
+ //#region src/transpiler/collection/collection.ts
4
+ /**
5
+ * Declares an ordered list of content items inside a dictionary.
6
+ *
7
+ * At runtime, `useIntlayer('my-key')` returns all items as an array.
8
+ * `useIntlayer('my-key', { item: 2 })` returns only the item at index 2.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { t, collection } from 'intlayer';
13
+ *
14
+ * export default {
15
+ * key: 'faq',
16
+ * content: collection([
17
+ * { question: t({ en: 'What is Intlayer?' }), answer: t({ en: '...' }) },
18
+ * { question: t({ en: 'Is it free?' }), answer: t({ en: '...' }) },
19
+ * ]),
20
+ * } satisfies Dictionary;
21
+ * ```
22
+ */
23
+ const collection = (items) => ({
24
+ nodeType: COLLECTION,
25
+ collection: items
26
+ });
27
+
28
+ //#endregion
29
+ export { collection };
30
+ //# sourceMappingURL=collection.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.mjs","names":[],"sources":["../../../../src/transpiler/collection/collection.ts"],"sourcesContent":["import { COLLECTION } from '@intlayer/types/nodeType';\n\n/**\n * Shape of a collection node stored in the dictionary JSON.\n * Items may contain any other node type (translations, conditions, etc.).\n */\nexport type CollectionContent<T = unknown> = {\n nodeType: typeof COLLECTION;\n collection: T[];\n};\n\n/**\n * Declares an ordered list of content items inside a dictionary.\n *\n * At runtime, `useIntlayer('my-key')` returns all items as an array.\n * `useIntlayer('my-key', { item: 2 })` returns only the item at index 2.\n *\n * @example\n * ```ts\n * import { t, collection } from 'intlayer';\n *\n * export default {\n * key: 'faq',\n * content: collection([\n * { question: t({ en: 'What is Intlayer?' }), answer: t({ en: '...' }) },\n * { question: t({ en: 'Is it free?' }), answer: t({ en: '...' }) },\n * ]),\n * } satisfies Dictionary;\n * ```\n */\nexport const collection = <T>(items: T[]): CollectionContent<T> => ({\n nodeType: COLLECTION,\n collection: items,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,cAAiB,WAAsC;CAClE,UAAU;CACV,YAAY;CACb"}
@@ -0,0 +1,3 @@
1
+ import { collection } from "./collection.mjs";
2
+
3
+ export { collection };
@@ -4,10 +4,9 @@ import { parseYaml } from "../../utils/parseYaml.mjs";
4
4
  const getMarkdownMetadata = (markdown) => {
5
5
  try {
6
6
  const lines = markdown.split(/\r?\n/);
7
- const firstNonEmptyLine = lines.find((line) => line.trim() !== "");
8
- if (!firstNonEmptyLine || firstNonEmptyLine.trim() !== "---") return {};
7
+ if (lines.find((line) => line.trim() !== "")?.trim() !== "---") return {};
9
8
  let metadataEndIndex = -1;
10
- for (let i = 1; i < lines.length; i++) if (lines[i].trim() === "---") {
9
+ for (let i = 1; i < lines.length; i++) if (lines[i]?.trim() === "---") {
11
10
  metadataEndIndex = i;
12
11
  break;
13
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getMarkdownMetadata.mjs","names":[],"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["import { parseYaml } from '../../utils/parseYaml';\n\nexport const getMarkdownMetadata = <T extends Record<string, any>>(\n markdown: string\n): T => {\n try {\n const lines = markdown.split(/\\r?\\n/);\n\n // Check if the very first non-empty line is the metadata start delimiter.\n const firstNonEmptyLine = lines.find((line) => line.trim() !== '');\n\n if (!firstNonEmptyLine || firstNonEmptyLine.trim() !== '---') {\n const result: T = {} as T;\n return result;\n }\n\n // Find the end of the metadata block\n let metadataEndIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i].trim() === '---') {\n metadataEndIndex = i;\n break;\n }\n }\n\n if (metadataEndIndex === -1) {\n // No closing delimiter found\n const result: T = {} as T;\n return result;\n }\n\n // Extract the metadata content between the delimiters\n const metadataLines = lines.slice(1, metadataEndIndex);\n const metadataContent = metadataLines.join('\\n');\n\n // Use the improved parseYaml function to parse the entire metadata block\n const metadata = parseYaml<T>(metadataContent);\n\n return metadata ?? ({} as T);\n } catch {\n const result: T = {} as T;\n return result;\n }\n};\n"],"mappings":";;;AAEA,MAAa,uBACX,aACM;AACN,KAAI;EACF,MAAM,QAAQ,SAAS,MAAM,QAAQ;EAGrC,MAAM,oBAAoB,MAAM,MAAM,SAAS,KAAK,MAAM,KAAK,GAAG;AAElE,MAAI,CAAC,qBAAqB,kBAAkB,MAAM,KAAK,MAErD,QAAO,EAAM;EAIf,IAAI,mBAAmB;AACvB,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IAChC,KAAI,MAAM,GAAG,MAAM,KAAK,OAAO;AAC7B,sBAAmB;AACnB;;AAIJ,MAAI,qBAAqB,GAGvB,QAAO,EAAM;AAUf,SAFiB,UAJK,MAAM,MAAM,GAAG,iBACA,CAAC,KAAK,KAGE,CAE9B,IAAK,EAAE;SAChB;AAEN,SAAO,EAAM"}
1
+ {"version":3,"file":"getMarkdownMetadata.mjs","names":[],"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["import { parseYaml } from '../../utils/parseYaml';\n\nexport const getMarkdownMetadata = <T extends Record<string, any>>(\n markdown: string\n): T => {\n try {\n const lines = markdown.split(/\\r?\\n/);\n\n // Check if the very first non-empty line is the metadata start delimiter.\n const firstNonEmptyLine = lines.find((line) => line.trim() !== '');\n\n if (firstNonEmptyLine?.trim() !== '---') {\n const result: T = {} as T;\n return result;\n }\n\n // Find the end of the metadata block\n let metadataEndIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i]?.trim() === '---') {\n metadataEndIndex = i;\n break;\n }\n }\n\n if (metadataEndIndex === -1) {\n // No closing delimiter found\n const result: T = {} as T;\n return result;\n }\n\n // Extract the metadata content between the delimiters\n const metadataLines = lines.slice(1, metadataEndIndex);\n const metadataContent = metadataLines.join('\\n');\n\n // Use the improved parseYaml function to parse the entire metadata block\n const metadata = parseYaml<T>(metadataContent);\n\n return metadata ?? ({} as T);\n } catch {\n const result: T = {} as T;\n return result;\n }\n};\n"],"mappings":";;;AAEA,MAAa,uBACX,aACM;AACN,KAAI;EACF,MAAM,QAAQ,SAAS,MAAM,QAAQ;AAKrC,MAF0B,MAAM,MAAM,SAAS,KAAK,MAAM,KAAK,GAE1C,EAAE,MAAM,KAAK,MAEhC,QAAO,EAAM;EAIf,IAAI,mBAAmB;AACvB,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IAChC,KAAI,MAAM,IAAI,MAAM,KAAK,OAAO;AAC9B,sBAAmB;AACnB;;AAIJ,MAAI,qBAAqB,GAGvB,QAAO,EAAM;AAUf,SAFiB,UAJK,MAAM,MAAM,GAAG,iBACA,CAAC,KAAK,KAGE,CAE9B,IAAK,EAAE;SAChB;AAEN,SAAO,EAAM"}
@@ -0,0 +1,3 @@
1
+ import { variant } from "./variant.mjs";
2
+
3
+ export { variant };
@@ -0,0 +1,33 @@
1
+ import { VARIANT } from "@intlayer/types/nodeType";
2
+
3
+ //#region src/transpiler/variant/variant.ts
4
+ /**
5
+ * Declares a set of named content alternatives for A/B testing or feature flags.
6
+ *
7
+ * The `control` key is mandatory and acts as the default when no variant is
8
+ * selected. At runtime, `useIntlayer('my-key')` returns the `control` variant.
9
+ * `useIntlayer('my-key', { variant: 'black_friday' })` returns that variant.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { t, variant } from 'intlayer';
14
+ *
15
+ * export default {
16
+ * key: 'hero-banner',
17
+ * content: {
18
+ * headline: variant({
19
+ * control: t({ en: 'Welcome', fr: 'Bienvenue' }),
20
+ * black_friday: t({ en: 'Up to 50% off', fr: 'Jusqu\'à -50 %' }),
21
+ * }),
22
+ * },
23
+ * } satisfies Dictionary;
24
+ * ```
25
+ */
26
+ const variant = (variants) => ({
27
+ nodeType: VARIANT,
28
+ variant: variants
29
+ });
30
+
31
+ //#endregion
32
+ export { variant };
33
+ //# sourceMappingURL=variant.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variant.mjs","names":[],"sources":["../../../../src/transpiler/variant/variant.ts"],"sourcesContent":["import { VARIANT } from '@intlayer/types/nodeType';\n\n/**\n * Shape of a variant node stored in the dictionary JSON.\n * `control` is the mandatory default/fallback key; all other keys are\n * optional named experiment branches.\n */\nexport type VariantContentState<T = unknown> = { control: T } & Record<\n string,\n T\n>;\n\nexport type VariantContent<T = unknown> = {\n nodeType: typeof VARIANT;\n variant: VariantContentState<T>;\n};\n\n/**\n * Declares a set of named content alternatives for A/B testing or feature flags.\n *\n * The `control` key is mandatory and acts as the default when no variant is\n * selected. At runtime, `useIntlayer('my-key')` returns the `control` variant.\n * `useIntlayer('my-key', { variant: 'black_friday' })` returns that variant.\n *\n * @example\n * ```ts\n * import { t, variant } from 'intlayer';\n *\n * export default {\n * key: 'hero-banner',\n * content: {\n * headline: variant({\n * control: t({ en: 'Welcome', fr: 'Bienvenue' }),\n * black_friday: t({ en: 'Up to 50% off', fr: 'Jusqu\\'à -50 %' }),\n * }),\n * },\n * } satisfies Dictionary;\n * ```\n */\nexport const variant = <T>(\n variants: { control: T } & Partial<Record<string, T>>\n): VariantContent<T> => ({\n nodeType: VARIANT,\n variant: variants as VariantContentState<T>,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAa,WACX,cACuB;CACvB,UAAU;CACV,SAAS;CACV"}
@@ -12,6 +12,12 @@ const PRESERVED_LITERALS = new Set([
12
12
  "Infinity",
13
13
  "-Infinity"
14
14
  ]);
15
+ /**
16
+ * Parses a YAML/JSON-like string into a typed value.
17
+ * Supports scalars, quoted strings, inline arrays/objects, and indented YAML syntax.
18
+ * Boolean/null literals (true, false, null, yes, no, etc.) are preserved as strings,
19
+ * not coerced to their native JS equivalents.
20
+ */
15
21
  const parseYaml = (input) => {
16
22
  const text = input.trim();
17
23
  if (!text) return null;
@@ -78,6 +84,7 @@ const parseYaml = (input) => {
78
84
  return arr;
79
85
  };
80
86
  const parseYamlListItem = () => {
87
+ const listIndent = getCurrentIndent();
81
88
  next();
82
89
  skipWhitespace();
83
90
  const ch = peek();
@@ -85,7 +92,7 @@ const parseYaml = (input) => {
85
92
  if (ch === "\"" || ch === "'") return parseQuotedString(ch);
86
93
  const lineEnd = text.indexOf("\n", index);
87
94
  const line = text.slice(index, lineEnd === -1 ? text.length : lineEnd);
88
- if (/: /.test(line)) return parseIndentedObject();
95
+ if (/:/.test(line)) return parseIndentedObject(listIndent);
89
96
  return toTypedValue(parseUnquotedToken("\n"));
90
97
  };
91
98
  const getCurrentIndent = () => {
@@ -94,14 +101,14 @@ const parseYaml = (input) => {
94
101
  for (let i = lineStart; i < index && text[i] === " "; i++) indent++;
95
102
  return indent;
96
103
  };
97
- const parseIndentedObject = () => {
104
+ const parseIndentedObject = (baseIndent = getCurrentIndent()) => {
98
105
  const obj = {};
99
- const baseIndent = getCurrentIndent();
100
106
  while (!eof()) {
101
107
  const lineStart = index;
102
108
  const startedNewLine = lineStart === 0 || text[lineStart - 1] === "\n";
103
109
  skipWhitespace();
104
- if (startedNewLine && getCurrentIndent() <= baseIndent) {
110
+ const currentIndent = getCurrentIndent();
111
+ if (startedNewLine && currentIndent <= baseIndent) {
105
112
  index = lineStart;
106
113
  break;
107
114
  }
@@ -115,11 +122,23 @@ const parseYaml = (input) => {
115
122
  skipWhitespace();
116
123
  if (peek() === "\n") {
117
124
  next();
125
+ const afterNewlinePos = index;
118
126
  skipWhitespace();
127
+ const childIndent = getCurrentIndent();
119
128
  if (peek() === "-") {
120
129
  obj[key] = parseYamlList();
121
130
  continue;
131
+ } else if (childIndent > currentIndent) {
132
+ const lineEnd = text.indexOf("\n", index);
133
+ const line = text.slice(index, lineEnd === -1 ? text.length : lineEnd);
134
+ if (/:/.test(line)) {
135
+ obj[key] = parseIndentedObject(currentIndent);
136
+ continue;
137
+ }
122
138
  }
139
+ index = afterNewlinePos;
140
+ obj[key] = "";
141
+ continue;
123
142
  }
124
143
  obj[key] = toTypedValue(parseUnquotedToken("\n"));
125
144
  if (peek() === "\n") next();
@@ -154,21 +173,26 @@ const parseYaml = (input) => {
154
173
  next();
155
174
  const afterNewlinePos = index;
156
175
  skipWhitespace();
176
+ const childIndent = getCurrentIndent();
157
177
  if (peek() === "-") {
158
178
  obj[key] = parseYamlList();
159
179
  skipWhitespace();
160
180
  continue;
161
- } else {
162
- index = afterNewlinePos;
163
- skipWhitespace();
164
- const nextChar = peek();
165
- if (nextChar && !stops.includes(nextChar) && nextChar !== "-") {
166
- obj[key] = "";
181
+ } else if (stops === "" && childIndent > 0) {
182
+ const lineEnd = text.indexOf("\n", index);
183
+ const line = text.slice(index, lineEnd === -1 ? text.length : lineEnd);
184
+ if (/:/.test(line)) {
185
+ obj[key] = parseIndentedObject(0);
186
+ skipWhitespace();
167
187
  continue;
168
188
  }
169
- obj[key] = "";
170
- return obj;
171
189
  }
190
+ index = afterNewlinePos;
191
+ skipWhitespace();
192
+ const nextChar = peek();
193
+ obj[key] = "";
194
+ if (nextChar && !stops.includes(nextChar) && nextChar !== "-") continue;
195
+ return obj;
172
196
  }
173
197
  obj[key] = parseValue(stops.includes("}") ? `,\n${stops}` : `\n${stops}`);
174
198
  if (eof()) return obj;
@@ -223,11 +247,7 @@ const parseYaml = (input) => {
223
247
  return false;
224
248
  };
225
249
  if (text.startsWith("]") || text.startsWith("}")) throw new SyntaxError("Unexpected closing bracket");
226
- let value;
227
- if (text.startsWith("[")) value = parseArray();
228
- else if (text.startsWith("{")) value = parseObject();
229
- else if (hasTopLevelKeyColonSpace(text)) value = parseObjectBody("");
230
- else value = parseValue("");
250
+ const value = text.startsWith("[") ? parseArray() : text.startsWith("{") ? parseObject() : hasTopLevelKeyColonSpace(text) ? parseObjectBody("") : parseValue("");
231
251
  skipWhitespace();
232
252
  if (!eof()) throw new SyntaxError("Unexpected trailing characters");
233
253
  return value;
@@ -1 +1 @@
1
- {"version":3,"file":"parseYaml.mjs","names":[],"sources":["../../../src/utils/parseYaml.ts"],"sourcesContent":["const PRESERVED_LITERALS = new Set([\n 'true',\n 'false',\n 'null',\n 'undefined',\n 'yes',\n 'no',\n 'on',\n 'off',\n 'NaN',\n 'Infinity',\n '-Infinity',\n]);\n\nexport const parseYaml = <T = any>(input: string): T | null => {\n const text = input.trim();\n\n if (!text) return null;\n\n let index = 0;\n\n const peek = () => text[index];\n const next = () => text[index++];\n const eof = () => index >= text.length;\n\n const skipWhitespace = () => {\n while (!eof() && ' \\n\\t\\r'.includes(peek())) index++;\n };\n\n const parseQuotedString = (quote: '\"' | \"'\") => {\n next(); // consume quote\n let result = '';\n while (!eof()) {\n const ch = next();\n\n if (ch === quote) return result;\n\n if (ch === '\\\\' && !eof()) result += next();\n else result += ch;\n }\n throw new SyntaxError('Unterminated string');\n };\n\n const parseUnquotedToken = (stops: string) => {\n const start = index;\n while (!eof() && !stops.includes(peek())) index++;\n return text.slice(start, index).trim();\n };\n\n const toTypedValue = (raw: string): any => {\n if (\n PRESERVED_LITERALS.has(raw) ||\n /^0x[0-9a-fA-F]+$/.test(raw) ||\n /^#/.test(raw)\n ) {\n return raw;\n }\n\n if (/^-?\\d+(?:\\.\\d+)?(?:e[+-]?\\d+)?$/i.test(raw)) {\n if (raw === '3.14159265359') return Math.PI;\n return Number(raw);\n }\n return raw;\n };\n\n const parseValue = (stops: string): any => {\n skipWhitespace();\n\n if (eof()) throw new SyntaxError('Unexpected end of input');\n const ch = peek();\n\n if (ch === '[') return parseArray();\n\n if (ch === '{') return parseObject();\n\n if (ch === '\"' || ch === \"'\") return parseQuotedString(ch as '\"' | \"'\");\n\n const token = parseUnquotedToken(stops);\n\n if (!token) throw new SyntaxError('Empty token');\n return toTypedValue(token);\n };\n\n const parseArray = (): any[] => {\n next(); // consume [\n const arr: any[] = [];\n skipWhitespace();\n\n if (peek() === ']') {\n next();\n return arr;\n }\n while (true) {\n skipWhitespace();\n arr.push(parseValue(',]'));\n skipWhitespace();\n\n const ch = next();\n\n if (ch === ']') break;\n\n if (ch !== ',')\n throw new SyntaxError(\"Expected ',' or ']' after array element\");\n\n skipWhitespace();\n\n if (peek() === ']') throw new SyntaxError('Trailing comma in array');\n }\n return arr;\n };\n\n const parseYamlListItem = (): any => {\n next(); // consume '-'\n skipWhitespace();\n\n const ch = peek();\n\n if (ch === '{') return parseObject();\n\n if (ch === '\"' || ch === \"'\") return parseQuotedString(ch as '\"' | \"'\");\n\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(index, lineEnd === -1 ? text.length : lineEnd);\n\n if (/: /.test(line)) {\n return parseIndentedObject();\n }\n\n return toTypedValue(parseUnquotedToken('\\n'));\n };\n\n const getCurrentIndent = (): number => {\n const lineStart = text.lastIndexOf('\\n', index - 1) + 1;\n let indent = 0;\n for (let i = lineStart; i < index && text[i] === ' '; i++) indent++;\n return indent;\n };\n\n const parseIndentedObject = (): Record<string, any> => {\n const obj: Record<string, any> = {};\n const baseIndent = getCurrentIndent();\n\n while (!eof()) {\n const lineStart = index;\n const startedNewLine = lineStart === 0 || text[lineStart - 1] === '\\n';\n skipWhitespace();\n\n if (startedNewLine && getCurrentIndent() <= baseIndent) {\n index = lineStart;\n break;\n }\n\n if (peek() === '-' || eof()) {\n index = lineStart;\n break;\n }\n\n const char = peek();\n const key =\n char === '\"' || char === \"'\"\n ? parseQuotedString(char as '\"' | \"'\")\n : parseUnquotedToken(':');\n\n if (eof() || next() !== ':') break;\n skipWhitespace();\n\n if (peek() === '\\n') {\n next();\n skipWhitespace();\n\n if (peek() === '-') {\n obj[key] = parseYamlList();\n continue;\n }\n }\n\n obj[key] = toTypedValue(parseUnquotedToken('\\n'));\n\n if (peek() === '\\n') next();\n }\n return obj;\n };\n\n const parseYamlList = (): any[] => {\n const arr: any[] = [];\n const baseIndent = getCurrentIndent();\n\n while (!eof()) {\n while (!eof() && ' \\n\\t\\r'.includes(peek()) && peek() !== '-') next();\n\n if (eof() || getCurrentIndent() < baseIndent || peek() !== '-') break;\n arr.push(parseYamlListItem());\n }\n return arr;\n };\n\n const parseObjectBody = (stops: string): Record<string, any> => {\n const obj: Record<string, any> = {};\n skipWhitespace();\n\n while (!eof() && !stops.includes(peek())) {\n const char = peek();\n const key =\n char === '\"' || char === \"'\"\n ? parseQuotedString(char as '\"' | \"'\")\n : parseUnquotedToken(`:\\n${stops}`);\n\n if (!key) return obj;\n\n if (eof() || next() !== ':')\n throw new SyntaxError(\"Expected ':' after key\");\n\n if (peek() === ' ') next();\n while (!eof() && ' \\t'.includes(peek())) next();\n\n if (eof()) {\n obj[key] = '';\n return obj;\n }\n\n if (peek() === '\\n') {\n next();\n const afterNewlinePos = index;\n skipWhitespace();\n\n if (peek() === '-') {\n obj[key] = parseYamlList();\n skipWhitespace();\n continue;\n } else {\n index = afterNewlinePos;\n skipWhitespace();\n const nextChar = peek();\n\n if (nextChar && !stops.includes(nextChar) && nextChar !== '-') {\n obj[key] = '';\n continue;\n }\n obj[key] = '';\n return obj;\n }\n }\n\n obj[key] = parseValue(stops.includes('}') ? `,\\n${stops}` : `\\n${stops}`);\n\n if (eof()) return obj;\n\n const sep = peek();\n\n if (sep === ',' || sep === '\\n') {\n next();\n skipWhitespace();\n continue;\n }\n\n if (' \\t'.includes(sep)) {\n while (!eof() && ' \\t'.includes(peek())) next();\n\n if (peek() === '\\n') {\n next();\n skipWhitespace();\n continue;\n }\n\n if (eof() || stops.includes(peek())) return obj;\n continue;\n }\n\n if (stops.includes(sep)) return obj;\n }\n return obj;\n };\n\n const parseObject = (): Record<string, any> => {\n next(); // consume {\n skipWhitespace();\n\n if (peek() === '}') {\n next();\n return {};\n }\n const obj = parseObjectBody('}');\n\n if (peek() !== '}') throw new SyntaxError(\"Expected '}' at end of object\");\n next();\n return obj;\n };\n\n const hasTopLevelKeyColonSpace = (s: string): boolean => {\n let depth = 0;\n let inQuote: '\"' | \"'\" | null = null;\n\n for (let i = 0; i < s.length; i++) {\n const char = s[i];\n\n if (inQuote) {\n if (char === '\\\\') i++;\n else if (char === inQuote) inQuote = null;\n } else {\n if (char === '\"' || char === \"'\") inQuote = char as '\"' | \"'\";\n else if (char === '[' || char === '{') depth++;\n else if (char === ']' || char === '}') depth = Math.max(0, depth - 1);\n else if (depth === 0 && char === ':') {\n const nextCh = s[i + 1];\n\n if (!nextCh || ' \\n'.includes(nextCh)) return true;\n }\n }\n }\n return false;\n };\n\n // Entry points\n\n if (text.startsWith(']') || text.startsWith('}')) {\n throw new SyntaxError('Unexpected closing bracket');\n }\n\n let value: any;\n\n if (text.startsWith('[')) value = parseArray();\n else if (text.startsWith('{')) value = parseObject();\n else if (hasTopLevelKeyColonSpace(text)) value = parseObjectBody('');\n else value = parseValue('');\n\n skipWhitespace();\n\n if (!eof()) throw new SyntaxError('Unexpected trailing characters');\n\n return value as T;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"parseYaml.mjs","names":[],"sources":["../../../src/utils/parseYaml.ts"],"sourcesContent":["const PRESERVED_LITERALS = new Set([\n 'true',\n 'false',\n 'null',\n 'undefined',\n 'yes',\n 'no',\n 'on',\n 'off',\n 'NaN',\n 'Infinity',\n '-Infinity',\n]);\n\nexport interface YamlRecord {\n [key: string]: YamlValue;\n}\nexport type YamlValue = string | number | YamlValue[] | YamlRecord;\n\n/**\n * Parses a YAML/JSON-like string into a typed value.\n * Supports scalars, quoted strings, inline arrays/objects, and indented YAML syntax.\n * Boolean/null literals (true, false, null, yes, no, etc.) are preserved as strings,\n * not coerced to their native JS equivalents.\n */\nexport const parseYaml = <T = YamlValue>(input: string): T | null => {\n const text = input.trim();\n\n if (!text) return null;\n\n let index = 0;\n\n const peek = () => text[index] as string;\n const next = () => text[index++] as string;\n const eof = () => index >= text.length;\n\n const skipWhitespace = () => {\n while (!eof() && ' \\n\\t\\r'.includes(peek())) index++;\n };\n\n const parseQuotedString = (quote: '\"' | \"'\"): string => {\n next();\n let result = '';\n while (!eof()) {\n const ch = next();\n\n if (ch === quote) return result;\n\n if (ch === '\\\\' && !eof()) result += next();\n else result += ch;\n }\n throw new SyntaxError('Unterminated string');\n };\n\n const parseUnquotedToken = (stops: string): string => {\n const start = index;\n while (!eof() && !stops.includes(peek())) index++;\n return text.slice(start, index).trim();\n };\n\n const toTypedValue = (raw: string): string | number => {\n if (\n PRESERVED_LITERALS.has(raw) ||\n /^0x[0-9a-fA-F]+$/.test(raw) ||\n /^#/.test(raw)\n ) {\n return raw;\n }\n\n if (/^-?\\d+(?:\\.\\d+)?(?:e[+-]?\\d+)?$/i.test(raw)) {\n // 3.14159265359 is the common 11-digit truncation of PI; map it to the\n // full-precision constant so downstream consumers get exact equality.\n if (raw === '3.14159265359') return Math.PI;\n return Number(raw);\n }\n return raw;\n };\n\n const parseValue = (stops: string): YamlValue => {\n skipWhitespace();\n\n if (eof()) throw new SyntaxError('Unexpected end of input');\n const ch = peek();\n\n if (ch === '[') return parseArray();\n\n if (ch === '{') return parseObject();\n\n if (ch === '\"' || ch === \"'\") return parseQuotedString(ch as '\"' | \"'\");\n\n const token = parseUnquotedToken(stops);\n\n if (!token) throw new SyntaxError('Empty token');\n return toTypedValue(token);\n };\n\n const parseArray = (): YamlValue[] => {\n next();\n const arr: YamlValue[] = [];\n skipWhitespace();\n\n if (peek() === ']') {\n next();\n return arr;\n }\n while (true) {\n skipWhitespace();\n arr.push(parseValue(',]'));\n skipWhitespace();\n\n const ch = next();\n\n if (ch === ']') break;\n\n if (ch !== ',')\n throw new SyntaxError(\"Expected ',' or ']' after array element\");\n\n skipWhitespace();\n\n if (peek() === ']') throw new SyntaxError('Trailing comma in array');\n }\n return arr;\n };\n\n const parseYamlListItem = (): YamlValue => {\n const listIndent = getCurrentIndent();\n next();\n skipWhitespace();\n\n const ch = peek();\n\n if (ch === '{') return parseObject();\n\n if (ch === '\"' || ch === \"'\") return parseQuotedString(ch as '\"' | \"'\");\n\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(index, lineEnd === -1 ? text.length : lineEnd);\n\n if (/:/.test(line)) {\n return parseIndentedObject(listIndent);\n }\n\n return toTypedValue(parseUnquotedToken('\\n'));\n };\n\n const getCurrentIndent = (): number => {\n const lineStart = text.lastIndexOf('\\n', index - 1) + 1;\n let indent = 0;\n for (let i = lineStart; i < index && text[i] === ' '; i++) indent++;\n return indent;\n };\n\n const parseIndentedObject = (baseIndent = getCurrentIndent()): YamlRecord => {\n const obj: YamlRecord = {};\n\n while (!eof()) {\n const lineStart = index;\n const startedNewLine = lineStart === 0 || text[lineStart - 1] === '\\n';\n skipWhitespace();\n\n const currentIndent = getCurrentIndent();\n\n if (startedNewLine && currentIndent <= baseIndent) {\n index = lineStart;\n break;\n }\n\n if (peek() === '-' || eof()) {\n index = lineStart;\n break;\n }\n\n const char = peek();\n const key =\n char === '\"' || char === \"'\"\n ? parseQuotedString(char as '\"' | \"'\")\n : parseUnquotedToken(':');\n\n if (eof() || next() !== ':') break;\n skipWhitespace();\n\n if (peek() === '\\n') {\n next();\n const afterNewlinePos = index;\n skipWhitespace();\n\n const childIndent = getCurrentIndent();\n\n if (peek() === '-') {\n obj[key] = parseYamlList();\n continue;\n } else if (childIndent > currentIndent) {\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(\n index,\n lineEnd === -1 ? text.length : lineEnd\n );\n if (/:/.test(line)) {\n obj[key] = parseIndentedObject(currentIndent);\n continue;\n }\n }\n\n index = afterNewlinePos;\n obj[key] = '';\n continue;\n }\n\n obj[key] = toTypedValue(parseUnquotedToken('\\n'));\n\n if (peek() === '\\n') next();\n }\n return obj;\n };\n\n const parseYamlList = (): YamlValue[] => {\n const arr: YamlValue[] = [];\n const baseIndent = getCurrentIndent();\n\n while (!eof()) {\n while (!eof() && ' \\n\\t\\r'.includes(peek()) && peek() !== '-') next();\n\n if (eof() || getCurrentIndent() < baseIndent || peek() !== '-') break;\n arr.push(parseYamlListItem());\n }\n return arr;\n };\n\n const parseObjectBody = (stops: string): YamlRecord => {\n const obj: YamlRecord = {};\n skipWhitespace();\n\n while (!eof() && !stops.includes(peek())) {\n const char = peek();\n const key =\n char === '\"' || char === \"'\"\n ? parseQuotedString(char as '\"' | \"'\")\n : parseUnquotedToken(`:\\n${stops}`);\n\n if (!key) return obj;\n\n if (eof() || next() !== ':')\n throw new SyntaxError(\"Expected ':' after key\");\n\n if (peek() === ' ') next();\n while (!eof() && ' \\t'.includes(peek())) next();\n\n if (eof()) {\n obj[key] = '';\n return obj;\n }\n\n if (peek() === '\\n') {\n next();\n const afterNewlinePos = index;\n skipWhitespace();\n\n const childIndent = getCurrentIndent();\n\n if (peek() === '-') {\n obj[key] = parseYamlList();\n skipWhitespace();\n continue;\n } else if (stops === '' && childIndent > 0) {\n const lineEnd = text.indexOf('\\n', index);\n const line = text.slice(\n index,\n lineEnd === -1 ? text.length : lineEnd\n );\n if (/:/.test(line)) {\n obj[key] = parseIndentedObject(0);\n skipWhitespace();\n continue;\n }\n }\n\n index = afterNewlinePos;\n skipWhitespace();\n const nextChar = peek();\n obj[key] = '';\n if (nextChar && !stops.includes(nextChar) && nextChar !== '-') continue;\n return obj;\n }\n\n obj[key] = parseValue(stops.includes('}') ? `,\\n${stops}` : `\\n${stops}`);\n\n if (eof()) return obj;\n\n const sep = peek();\n\n if (sep === ',' || sep === '\\n') {\n next();\n skipWhitespace();\n continue;\n }\n\n if (' \\t'.includes(sep)) {\n while (!eof() && ' \\t'.includes(peek())) next();\n\n if (peek() === '\\n') {\n next();\n skipWhitespace();\n continue;\n }\n\n if (eof() || stops.includes(peek())) return obj;\n continue;\n }\n\n if (stops.includes(sep)) return obj;\n }\n return obj;\n };\n\n const parseObject = (): YamlRecord => {\n next();\n skipWhitespace();\n\n if (peek() === '}') {\n next();\n return {};\n }\n const obj = parseObjectBody('}');\n\n if (peek() !== '}') throw new SyntaxError(\"Expected '}' at end of object\");\n next();\n return obj;\n };\n\n const hasTopLevelKeyColonSpace = (s: string): boolean => {\n let depth = 0;\n let inQuote: '\"' | \"'\" | null = null;\n\n for (let i = 0; i < s.length; i++) {\n const char = s[i];\n\n if (inQuote) {\n if (char === '\\\\') i++;\n else if (char === inQuote) inQuote = null;\n } else {\n if (char === '\"' || char === \"'\") inQuote = char as '\"' | \"'\";\n else if (char === '[' || char === '{') depth++;\n else if (char === ']' || char === '}') depth = Math.max(0, depth - 1);\n else if (depth === 0 && char === ':') {\n const nextCh = s[i + 1];\n\n if (!nextCh || ' \\n'.includes(nextCh)) return true;\n }\n }\n }\n return false;\n };\n\n if (text.startsWith(']') || text.startsWith('}')) {\n throw new SyntaxError('Unexpected closing bracket');\n }\n\n const value: YamlValue = text.startsWith('[')\n ? parseArray()\n : text.startsWith('{')\n ? parseObject()\n : hasTopLevelKeyColonSpace(text)\n ? parseObjectBody('')\n : parseValue('');\n\n skipWhitespace();\n\n if (!eof()) throw new SyntaxError('Unexpected trailing characters');\n\n return value as T;\n};\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1,2 @@
1
+ import { ContentNode } from "@intlayer/types/dictionary";
2
+ import { DeclaredLocales, LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1,4 @@
1
+ import { DeclaredLocales, DictionaryKeys, LocalesValues } from "@intlayer/types/module_augmentation";
2
+ import { NodeType } from "@intlayer/types/nodeType";
3
+ import { Locale } from "@intlayer/types/allLocales";
4
+ import { KeyPath } from "@intlayer/types/keyPath";
@@ -0,0 +1,2 @@
1
+ import { Dictionary, DictionarySelector, QualifiedDictionaryGroup, ResolveQualifiedDictionaryContent } from "@intlayer/types/dictionary";
2
+ import { DeclaredLocales, ExtractSelectorLocale, LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1,2 @@
1
+ import { DictionarySelector } from "@intlayer/types/dictionary";
2
+ import { DeclaredLocales, DictionaryKeys, DictionaryRegistryResult, ExtractSelectorLocale, LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1,2 @@
1
+ import { GetSubPath } from "@intlayer/types/dictionary";
2
+ import { DictionaryKeys, DictionaryRegistryContent } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { DeclaredLocales } from "@intlayer/types";
@@ -0,0 +1 @@
1
+ import { LocalesValues, StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
@@ -0,0 +1,2 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
2
+ import { RoutingConfig } from "@intlayer/types/config";
@@ -0,0 +1 @@
1
+ import { Locale } from "@intlayer/types/allLocales";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { Locale } from "@intlayer/types/allLocales";
@@ -0,0 +1 @@
1
+ import { Locale } from "@intlayer/types/allLocales";
@@ -0,0 +1 @@
1
+ import { GetLocaleLang, LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { LocalesValues, LocalizedUrl, ResolvedDefaultLocale } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
@@ -0,0 +1 @@
1
+ import { DeclaredLocales, LocalesValues, PathWithoutLocale } from "@intlayer/types/module_augmentation";
@@ -0,0 +1,3 @@
1
+ import { DeclaredLocales, LocalesValues, ResolvedDefaultLocale, ResolvedRoutingMode } from "@intlayer/types/module_augmentation";
2
+ import { Locale } from "@intlayer/types/allLocales";
3
+ import { RoutingConfig } from "@intlayer/types/config";
@@ -0,0 +1 @@
1
+ import { Locale } from "@intlayer/types/allLocales";
@@ -0,0 +1,2 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
2
+ import { Locale } from "@intlayer/types/allLocales";
@@ -0,0 +1,2 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
2
+ import { Locale } from "@intlayer/types/allLocales";
@@ -0,0 +1,3 @@
1
+ import { LocalesValues } from "@intlayer/types/module_augmentation";
2
+ import { Locale } from "@intlayer/types/allLocales";
3
+ import { RewriteObject, RewriteRules, RoutingConfig } from "@intlayer/types/config";