@intlayer/core 8.12.5-canary.0 → 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":"qualifiedDictionary.cjs","names":[],"sources":["../../../src/dictionaryManipulator/qualifiedDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionaryQualifierType,\n DictionarySelector,\n QualifiedDictionaryGroup,\n} from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\n/**\n * Selector keys that are reserved for dictionary resolution and therefore\n * excluded from meta field matching.\n */\nconst RESERVED_SELECTOR_KEYS = ['locale', 'item', 'variant'] as const;\n\n/**\n * Canonical order of qualifier dimensions. A key that declares several\n * dimensions always nests them in this order, with `item` innermost so it can\n * act as the collection (array) axis.\n */\nexport const QUALIFIER_ORDER = [\n 'variant',\n 'meta',\n 'item',\n] as const satisfies readonly DictionaryQualifierType[];\n\n/**\n * Separator joining per-dimension ids into a composite entry id. Also used as\n * the chunk path separator in dynamic mode.\n */\nexport const COMPOSITE_ID_SEPARATOR = '/';\n\n/**\n * Returns the qualifier dimensions declared on a dictionary, in canonical\n * order (`variant → meta → item`). Empty when the dictionary is unqualified\n * (plain dictionary or shared base content of a qualified group).\n */\nexport const getDictionaryQualifierTypes = (\n dictionary: Dictionary\n): DictionaryQualifierType[] => {\n const declaredQualifiers: DictionaryQualifierType[] = [];\n\n if (typeof dictionary.variant === 'string')\n declaredQualifiers.push('variant');\n if (dictionary.meta !== undefined) declaredQualifiers.push('meta');\n if (typeof dictionary.item === 'number') declaredQualifiers.push('item');\n\n return declaredQualifiers;\n};\n\n/**\n * Returns the qualifier identifier of a dictionary for the given qualifier\n * dimension — one segment of the composite entry id.\n *\n * - 'variant' → the variant name\n * - 'meta' → the `meta.id` discriminator\n * - 'item' → the item index as string\n */\nexport const getDictionaryQualifierId = (\n dictionary: Dictionary,\n qualifierType: DictionaryQualifierType\n): string | undefined => {\n if (qualifierType === 'variant') return dictionary.variant;\n if (qualifierType === 'meta') {\n const metaId = dictionary.meta?.id;\n return metaId === undefined ? undefined : String(metaId);\n }\n return dictionary.item === undefined ? undefined : String(dictionary.item);\n};\n\n/**\n * Returns the per-dimension id segments of a dictionary for the given ordered\n * dimension set, or `undefined` when the dictionary does not declare every\n * dimension of the set.\n */\nexport const getDictionaryQualifierSegments = (\n dictionary: Dictionary,\n qualifierTypes: DictionaryQualifierType[]\n): string[] | undefined => {\n const segments: string[] = [];\n\n for (const qualifierType of qualifierTypes) {\n const id = getDictionaryQualifierId(dictionary, qualifierType);\n if (id === undefined) return undefined;\n segments.push(id);\n }\n\n return segments;\n};\n\n/**\n * Builds the composite entry id of a dictionary — its per-dimension id segments\n * joined in canonical order. `undefined` when a dimension is missing.\n */\nexport const getDictionaryCompositeId = (\n dictionary: Dictionary,\n qualifierTypes: DictionaryQualifierType[]\n): string | undefined =>\n getDictionaryQualifierSegments(dictionary, qualifierTypes)?.join(\n COMPOSITE_ID_SEPARATOR\n );\n\n/**\n * Checks that every declared meta field is provided and equal in the selector.\n * Reserved keys (`locale`, `item`, `variant`) are skipped; `meta.id` is part of\n * the equality check.\n */\nconst metaFieldsMatch = (\n meta: Dictionary['meta'] | undefined,\n selector: DictionarySelector | undefined\n): boolean => {\n if (!meta) return false;\n\n return Object.entries(meta).every(([metaField, declaredValue]) => {\n if ((RESERVED_SELECTOR_KEYS as readonly string[]).includes(metaField)) {\n return true;\n }\n\n const providedValue = selector?.[metaField];\n\n return (\n providedValue !== undefined &&\n String(providedValue) === String(declaredValue)\n );\n });\n};\n\n/**\n * Tests whether a group entry matches a selector across every declared\n * dimension. The `item` dimension matches any value when the selector does not\n * provide one (open collection axis).\n */\nconst entryMatchesSelector = (\n entry: Dictionary,\n qualifierTypes: DictionaryQualifierType[],\n selector: DictionarySelector | undefined\n): boolean =>\n qualifierTypes.every((qualifierType) => {\n if (qualifierType === 'variant') {\n return entry.variant === (selector?.variant ?? 'default');\n }\n\n if (qualifierType === 'item') {\n return (\n selector?.item === undefined ||\n String(entry.item) === String(selector.item)\n );\n }\n\n // qualifierType === 'meta'\n return metaFieldsMatch(entry.meta, selector);\n });\n\n/**\n * Type guard discriminating a `QualifiedDictionaryGroup` (merge output of a\n * qualified key) from a plain `Dictionary`. Both carry a `content` field; only\n * the group declares `qualifierTypes`, which is therefore the discriminator.\n */\nexport const isQualifiedDictionaryGroup = (\n value: unknown\n): value is QualifiedDictionaryGroup =>\n typeof value === 'object' &&\n value !== null &&\n 'qualifierTypes' in value &&\n Array.isArray((value as { qualifierTypes: unknown }).qualifierTypes) &&\n 'content' in value;\n\n/**\n * Reconstructs a resolvable {@link Dictionary} from a single entry of a\n * qualified group: the content node stored under its composite id, plus the\n * qualifier coordinates decoded from that id (`variant`, `item`) and the\n * preserved `meta` object for the meta dimension.\n *\n * This keeps the resolver's matching/transform code unchanged: it still sees a\n * `{ key, content, variant?, item?, meta? }` shape, even though the stored\n * format no longer duplicates those fields per entry.\n */\nexport const reconstructQualifiedEntry = (\n group: QualifiedDictionaryGroup,\n compositeId: string\n): Dictionary => {\n const segments = compositeId.split(COMPOSITE_ID_SEPARATOR);\n\n const entry = {\n key: group.key,\n content: group.content[compositeId],\n } as Dictionary;\n\n group.qualifierTypes.forEach((qualifierType, index) => {\n if (qualifierType === 'variant') {\n entry.variant = segments[index];\n } else if (qualifierType === 'item') {\n entry.item = Number(segments[index]);\n }\n });\n\n if (group.qualifierTypes.includes('meta')) {\n const metaIndex = group.qualifierTypes.indexOf('meta');\n entry.meta = group.meta?.[compositeId] ?? { id: segments[metaIndex] };\n }\n\n return entry;\n};\n\n/**\n * Resolves a dictionary (or qualified dictionary group) against a selector,\n * across every declared dimension.\n *\n * - Plain dictionary → returned as-is (selector ignored)\n * - `item` declared but not selected → every matching entry ordered by index\n * - `item` selected → the matching entry or null\n * - `variant` defaults to the `default` entry when not selected\n * - `meta` requires `{ id }` and every declared meta field to match\n *\n * Dimensions compose: e.g. a variant × item key with `{ variant: 'promo' }`\n * returns every promo item as an array; adding `{ item: 2 }` narrows to one.\n */\nexport const resolveQualifiedDictionary = (\n dictionaryOrGroup: Dictionary | QualifiedDictionaryGroup,\n selector?: DictionarySelector\n): Dictionary | Dictionary[] | null => {\n if (!isQualifiedDictionaryGroup(dictionaryOrGroup)) {\n return dictionaryOrGroup;\n }\n\n const { qualifierTypes, content } = dictionaryOrGroup;\n\n // The meta dimension cannot resolve without an id discriminator.\n if (qualifierTypes.includes('meta') && selector?.id === undefined) {\n return null;\n }\n\n const itemAxisOpen =\n qualifierTypes.includes('item') && selector?.item === undefined;\n\n const matchedEntries = Object.keys(content)\n .map((compositeId) =>\n reconstructQualifiedEntry(dictionaryOrGroup, compositeId)\n )\n .filter((entry) => entryMatchesSelector(entry, qualifierTypes, selector));\n\n if (itemAxisOpen) {\n return matchedEntries.sort(\n (left, right) => (left.item ?? 0) - (right.item ?? 0)\n );\n }\n\n return matchedEntries[0] ?? null;\n};\n\n/**\n * Splits the second argument of `getIntlayer` / `getDictionary` into the\n * effective locale and the selector object (if any).\n */\nexport const parseDictionarySelector = <L extends LocalesValues>(\n localeOrSelector?: L | DictionarySelector\n): { locale?: L; selector?: DictionarySelector } => {\n if (typeof localeOrSelector === 'object' && localeOrSelector !== null) {\n return {\n locale: localeOrSelector.locale as L | undefined,\n selector: localeOrSelector,\n };\n }\n\n return { locale: localeOrSelector };\n};\n\n/**\n * Builds a stable string identity of a selector (excluding `locale`), suitable\n * for cache keys and memoization dependencies.\n */\nexport const getDictionarySelectorCacheKey = (\n selector?: DictionarySelector\n): string => {\n if (!selector) return '';\n\n return Object.keys(selector)\n .filter((selectorKey) => selectorKey !== 'locale')\n .sort()\n .map((selectorKey) => `${selectorKey}:${String(selector[selectorKey])}`)\n .join('|');\n};\n\n/**\n * Marker property carrying the ordered qualifier dimensions on a dynamic loader\n * map. Its presence distinguishes a qualified group loader map (a nested tree\n * of chunks) from a plain dynamic loader map (one chunk per `locale`). Prefixed\n * and unlikely to collide with a real locale code.\n */\nexport const QUALIFIER_DYNAMIC_TYPES_KEY = '__intlayerQualifierTypes';\n\n/**\n * A lazily-imported per-locale dictionary chunk loader.\n */\nexport type DynamicDictionaryLoader = () => Promise<Dictionary>;\n\n/**\n * Nested tree of chunk loaders: one nesting level per declared dimension (in\n * canonical order), leaves are loaders.\n */\nexport type QualifiedDynamicLoaderTree = {\n [segment: string]: QualifiedDynamicLoaderTree | DynamicDictionaryLoader;\n};\n\n/**\n * Default export shape of a generated dynamic entry point for a qualified key.\n * One nesting level per dimension under each locale, plus the dimension marker.\n *\n * ```ts\n * {\n * __intlayerQualifierTypes: ['variant', 'item'],\n * en: { promo: { '1': () => import('./json/x/promo/1/en.json'), … }, … },\n * fr: { … },\n * }\n * ```\n */\nexport type QualifiedDynamicLoaderMap = {\n [QUALIFIER_DYNAMIC_TYPES_KEY]: DictionaryQualifierType[];\n [locale: string]: QualifiedDynamicLoaderTree | DictionaryQualifierType[];\n};\n\n/**\n * Type guard discriminating a qualified dynamic loader map (collections /\n * variants / meta records, possibly combined) from a plain dynamic loader map.\n */\nexport const isQualifiedDynamicLoaderMap = (\n value: unknown\n): value is QualifiedDynamicLoaderMap =>\n typeof value === 'object' &&\n value !== null &&\n QUALIFIER_DYNAMIC_TYPES_KEY in value;\n\n/**\n * Resolves the content of a qualified dynamic loader map against a selector,\n * loading only the chunk(s) the selector actually targets.\n *\n * Walks the nested loader tree one dimension at a time (canonical order\n * `variant → meta → item`): `variant` defaults to `default`, `meta` descends by\n * `id`, and `item` either narrows to the selected index or — when no item is\n * given — expands into every sibling chunk (the collection axis). Meta-equality\n * is verified on the loaded chunk. Semantics mirror\n * {@link resolveQualifiedDictionary} so dynamic and static modes behave alike.\n *\n * The Suspense mechanism is injected through `loadChunk` so the same logic\n * serves both the client (suspender cache) and the server (`react.use`). Every\n * targeted loader is started before the first chunk is read, so sibling chunks\n * load in parallel rather than waterfalling.\n *\n * @param loaderMap - The qualified dynamic loader map (entry point default export).\n * @param key - The dictionary key (used to build stable chunk cache keys).\n * @param locale - The resolved locale to load chunks for.\n * @param selector - The selector splitting the qualifier dimensions.\n * @param loadChunk - Reads a started chunk promise, suspending until it resolves.\n * @param transform - Turns a resolved chunk dictionary into final content.\n */\n/** One targeted chunk: its stable cache key and lazy loader. */\ntype CollectedChunk = {\n cacheKey: string;\n loader: DynamicDictionaryLoader;\n};\n\ntype CollectedChunks = {\n /** True when the `item` axis is open (collection result → array). */\n itemAxisOpen: boolean;\n /** True when a required coordinate is absent (result → [] or null). */\n missed: boolean;\n /** The chunks the selector targets (in collection order for the item axis). */\n chunks: CollectedChunk[];\n};\n\n/**\n * Walks the loader tree following the selector and collects the chunk loaders\n * it targets — shared by the sync ({@link resolveQualifiedDynamicContent}) and\n * async ({@link resolveQualifiedDynamicContentAsync}) resolvers.\n */\nconst collectQualifiedChunks = (\n loaderMap: QualifiedDynamicLoaderMap,\n key: string,\n locale: string,\n selector: DictionarySelector | undefined\n): CollectedChunks => {\n const qualifierTypes = loaderMap[QUALIFIER_DYNAMIC_TYPES_KEY];\n const localeTree = loaderMap[locale] as\n | QualifiedDynamicLoaderTree\n | undefined;\n\n const itemAxisOpen =\n qualifierTypes.includes('item') && selector?.item === undefined;\n\n if (!localeTree) return { itemAxisOpen, missed: true, chunks: [] };\n\n // The meta dimension cannot resolve without an id discriminator.\n if (qualifierTypes.includes('meta') && selector?.id === undefined) {\n return { itemAxisOpen, missed: true, chunks: [] };\n }\n\n const chunks: CollectedChunk[] = [];\n\n const walk = (\n node: QualifiedDynamicLoaderTree | DynamicDictionaryLoader,\n dimensions: DictionaryQualifierType[],\n segments: string[]\n ): boolean => {\n if (dimensions.length === 0) {\n chunks.push({\n cacheKey: `${key}.${locale}.${segments.join(COMPOSITE_ID_SEPARATOR)}`,\n loader: node as DynamicDictionaryLoader,\n });\n return true;\n }\n\n const [dimension, ...rest] = dimensions;\n const tree = node as QualifiedDynamicLoaderTree;\n\n if (dimension === 'item' && selector?.item === undefined) {\n // Open collection axis: fan out into every sibling chunk, ordered.\n for (const segment of Object.keys(tree).sort(\n (left, right) => Number(left) - Number(right)\n )) {\n walk(tree[segment]!, rest, [...segments, segment]);\n }\n return true;\n }\n\n const segment =\n dimension === 'variant'\n ? (selector?.variant ?? 'default')\n : dimension === 'meta'\n ? String(selector?.id)\n : String(selector?.item);\n\n const child = tree[segment];\n if (!child) return false;\n\n return walk(child, rest, [...segments, segment]);\n };\n\n const found = walk(localeTree, qualifierTypes, []);\n\n return { itemAxisOpen, missed: !found, chunks };\n};\n\n/**\n * Whether a loaded chunk satisfies the selector's meta fields (no-op unless the\n * key declares a `meta` dimension).\n */\nconst chunkMatchesMeta = (\n loaderMap: QualifiedDynamicLoaderMap,\n dictionary: Dictionary,\n selector: DictionarySelector | undefined\n): boolean =>\n !loaderMap[QUALIFIER_DYNAMIC_TYPES_KEY].includes('meta') ||\n metaFieldsMatch(dictionary.meta, selector);\n\n/**\n * Resolves the content of a qualified dynamic loader map against a selector,\n * loading only the chunk(s) the selector actually targets.\n *\n * Walks the nested loader tree one dimension at a time (canonical order\n * `variant → meta → item`): `variant` defaults to `default`, `meta` descends by\n * `id`, and `item` either narrows to the selected index or — when no item is\n * given — expands into every sibling chunk (the collection axis). Meta-equality\n * is verified on the loaded chunk. Semantics mirror\n * {@link resolveQualifiedDictionary} so dynamic and static modes behave alike.\n *\n * The Suspense mechanism is injected through `loadChunk` so the same logic\n * serves both the client (suspender cache) and the server (`react.use`). Every\n * targeted loader is started before the first chunk is read, so sibling chunks\n * load in parallel rather than waterfalling.\n *\n * @param loaderMap - The qualified dynamic loader map (entry point default export).\n * @param key - The dictionary key (used to build stable chunk cache keys).\n * @param locale - The resolved locale to load chunks for.\n * @param selector - The selector splitting the qualifier dimensions.\n * @param loadChunk - Reads a started chunk promise, suspending until it resolves.\n * @param transform - Turns a resolved chunk dictionary into final content.\n */\nexport const resolveQualifiedDynamicContent = <Content>(params: {\n loaderMap: QualifiedDynamicLoaderMap;\n key: string;\n locale: string;\n selector: DictionarySelector | undefined;\n loadChunk: (cacheKey: string, promise: Promise<Dictionary>) => Dictionary;\n transform: (dictionary: Dictionary) => Content;\n}): Content | Content[] | null => {\n const { loaderMap, key, locale, selector, loadChunk, transform } = params;\n\n const { itemAxisOpen, missed, chunks } = collectQualifiedChunks(\n loaderMap,\n key,\n locale,\n selector\n );\n\n if (missed) return itemAxisOpen ? [] : null;\n\n // Start every loader before reading, so siblings load in parallel.\n const dictionaries = chunks\n .map(({ cacheKey, loader }) => loadChunk(cacheKey, loader()))\n .filter((dictionary) => chunkMatchesMeta(loaderMap, dictionary, selector));\n\n if (itemAxisOpen) return dictionaries.map(transform);\n\n const [dictionary] = dictionaries;\n return dictionary ? transform(dictionary) : null;\n};\n\n/**\n * Async counterpart of {@link resolveQualifiedDynamicContent} for frameworks\n * that load dictionaries with `await` instead of Suspense (Vue, Svelte, Lit,\n * vanilla). Awaits every targeted chunk in parallel, then resolves identically.\n *\n * @param loaderMap - The qualified dynamic loader map.\n * @param key - The dictionary key (used to build stable chunk cache keys).\n * @param locale - The resolved locale to load chunks for.\n * @param selector - The selector splitting the qualifier dimensions.\n * @param transform - Turns a resolved chunk dictionary into final content.\n */\nexport const resolveQualifiedDynamicContentAsync = async <Content>(params: {\n loaderMap: QualifiedDynamicLoaderMap;\n key: string;\n locale: string;\n selector: DictionarySelector | undefined;\n transform: (dictionary: Dictionary) => Content;\n}): Promise<Content | Content[] | null> => {\n const { loaderMap, key, locale, selector, transform } = params;\n\n const { itemAxisOpen, missed, chunks } = collectQualifiedChunks(\n loaderMap,\n key,\n locale,\n selector\n );\n\n if (missed) return itemAxisOpen ? [] : null;\n\n const dictionaries = (\n await Promise.all(chunks.map(({ loader }) => loader()))\n ).filter((dictionary) => chunkMatchesMeta(loaderMap, dictionary, selector));\n\n if (itemAxisOpen) return dictionaries.map(transform);\n\n const [dictionary] = dictionaries;\n return dictionary ? transform(dictionary) : null;\n};\n"],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_deepTransformPlugins_getEditedContent = require('./deepTransformPlugins/getEditedContent.cjs');
2
3
  const require_interpreter_getCondition = require('./interpreter/getCondition.cjs');
3
4
  const require_interpreter_getContent_deepTransform = require('./interpreter/getContent/deepTransform.cjs');
4
5
  const require_interpreter_getEnumeration = require('./interpreter/getEnumeration.cjs');
6
+ const require_dictionaryManipulator_qualifiedDictionary = require('./dictionaryManipulator/qualifiedDictionary.cjs');
5
7
  const require_interpreter_getDictionary = require('./interpreter/getDictionary.cjs');
6
8
  const require_interpreter_getIntlayer = require('./interpreter/getIntlayer.cjs');
7
9
  const require_interpreter_getNesting = require('./interpreter/getNesting.cjs');
@@ -53,6 +55,7 @@ const require_dictionaryManipulator_getNodeChildren = require('./dictionaryManip
53
55
  const require_utils_isValidReactElement = require('./utils/isValidReactElement.cjs');
54
56
  const require_dictionaryManipulator_getNodeType = require('./dictionaryManipulator/getNodeType.cjs');
55
57
  const require_dictionaryManipulator_mergeDictionaries = require('./dictionaryManipulator/mergeDictionaries.cjs');
58
+ const require_dictionaryManipulator_mergeQualifiedDictionaries = require('./dictionaryManipulator/mergeQualifiedDictionaries.cjs');
56
59
  const require_dictionaryManipulator_orderDictionaries = require('./dictionaryManipulator/orderDictionaries.cjs');
57
60
  const require_dictionaryManipulator_normalizeDictionary = require('./dictionaryManipulator/normalizeDictionary.cjs');
58
61
  const require_dictionaryManipulator_removeContentNodeByKeyPath = require('./dictionaryManipulator/removeContentNodeByKeyPath.cjs');
@@ -86,6 +89,7 @@ const require_messageFormat_ICU = require('./messageFormat/ICU.cjs');
86
89
  const require_messageFormat_i18next = require('./messageFormat/i18next.cjs');
87
90
  const require_messageFormat_po = require('./messageFormat/po.cjs');
88
91
  const require_messageFormat_vue_i18n = require('./messageFormat/vue-i18n.cjs');
92
+ const require_messageFormat_resolveMessage = require('./messageFormat/resolveMessage.cjs');
89
93
  const require_utils_isSameKeyPath = require('./utils/isSameKeyPath.cjs');
90
94
  const require_utils_stringifyYaml = require('./utils/stringifyYaml.cjs');
91
95
 
@@ -102,6 +106,7 @@ exports.CAPTURE_LETTER_AFTER_HYPHEN = require_markdown_constants.CAPTURE_LETTER_
102
106
  exports.CODE_BLOCK_FENCED_R = require_markdown_constants.CODE_BLOCK_FENCED_R;
103
107
  exports.CODE_BLOCK_R = require_markdown_constants.CODE_BLOCK_R;
104
108
  exports.CODE_INLINE_R = require_markdown_constants.CODE_INLINE_R;
109
+ exports.COMPOSITE_ID_SEPARATOR = require_dictionaryManipulator_qualifiedDictionary.COMPOSITE_ID_SEPARATOR;
105
110
  exports.CONSECUTIVE_NEWLINE_R = require_markdown_constants.CONSECUTIVE_NEWLINE_R;
106
111
  exports.CR_NEWLINE_R = require_markdown_constants.CR_NEWLINE_R;
107
112
  exports.CUSTOM_COMPONENT_R = require_markdown_constants.CUSTOM_COMPONENT_R;
@@ -143,6 +148,8 @@ exports.ORDERED_LIST_ITEM_R = require_markdown_constants.ORDERED_LIST_ITEM_R;
143
148
  exports.ORDERED_LIST_R = require_markdown_constants.ORDERED_LIST_R;
144
149
  exports.PARAGRAPH_R = require_markdown_constants.PARAGRAPH_R;
145
150
  exports.Priority = require_markdown_constants.Priority;
151
+ exports.QUALIFIER_DYNAMIC_TYPES_KEY = require_dictionaryManipulator_qualifiedDictionary.QUALIFIER_DYNAMIC_TYPES_KEY;
152
+ exports.QUALIFIER_ORDER = require_dictionaryManipulator_qualifiedDictionary.QUALIFIER_ORDER;
146
153
  exports.REFERENCE_IMAGE_OR_LINK = require_markdown_constants.REFERENCE_IMAGE_OR_LINK;
147
154
  exports.REFERENCE_IMAGE_R = require_markdown_constants.REFERENCE_IMAGE_R;
148
155
  exports.REFERENCE_LINK_R = require_markdown_constants.REFERENCE_LINK_R;
@@ -216,6 +223,13 @@ exports.getContentNodeByKeyPath = require_dictionaryManipulator_getContentNodeBy
216
223
  exports.getCookie = require_utils_getCookie.getCookie;
217
224
  exports.getDefaultNode = require_dictionaryManipulator_getDefaultNode.getDefaultNode;
218
225
  exports.getDictionary = require_interpreter_getDictionary.getDictionary;
226
+ exports.getDictionaryCompositeId = require_dictionaryManipulator_qualifiedDictionary.getDictionaryCompositeId;
227
+ exports.getDictionaryQualifierId = require_dictionaryManipulator_qualifiedDictionary.getDictionaryQualifierId;
228
+ exports.getDictionaryQualifierSegments = require_dictionaryManipulator_qualifiedDictionary.getDictionaryQualifierSegments;
229
+ exports.getDictionaryQualifierTypes = require_dictionaryManipulator_qualifiedDictionary.getDictionaryQualifierTypes;
230
+ exports.getDictionarySelectorCacheKey = require_dictionaryManipulator_qualifiedDictionary.getDictionarySelectorCacheKey;
231
+ exports.getEditedContent = require_deepTransformPlugins_getEditedContent.getEditedContent;
232
+ exports.getEditedDictionary = require_deepTransformPlugins_getEditedContent.getEditedDictionary;
219
233
  exports.getEmptyNode = require_dictionaryManipulator_getEmptyNode.getEmptyNode;
220
234
  exports.getEnumeration = require_interpreter_getEnumeration.getEnumeration;
221
235
  exports.getFilterMissingTranslationsContent = require_deepTransformPlugins_getFilterMissingTranslationsContent.getFilterMissingTranslationsContent;
@@ -265,10 +279,13 @@ exports.inlineRegex = require_markdown_utils.inlineRegex;
265
279
  exports.insert = require_transpiler_insertion_insertion.insert;
266
280
  exports.insertContentInDictionary = require_deepTransformPlugins_insertContentInDictionary.insertContentInDictionary;
267
281
  exports.insertionPlugin = require_interpreter_getContent_plugins.insertionPlugin;
282
+ exports.interpolateMessage = require_messageFormat_resolveMessage.interpolateMessage;
268
283
  exports.intlayerToI18nextFormatter = require_messageFormat_i18next.intlayerToI18nextFormatter;
269
284
  exports.intlayerToICUFormatter = require_messageFormat_ICU.intlayerToICUFormatter;
270
285
  exports.intlayerToPortableObjectFormatter = require_messageFormat_po.intlayerToPortableObjectFormatter;
271
286
  exports.intlayerToVueI18nFormatter = require_messageFormat_vue_i18n.intlayerToVueI18nFormatter;
287
+ exports.isQualifiedDictionaryGroup = require_dictionaryManipulator_qualifiedDictionary.isQualifiedDictionaryGroup;
288
+ exports.isQualifiedDynamicLoaderMap = require_dictionaryManipulator_qualifiedDictionary.isQualifiedDynamicLoaderMap;
272
289
  exports.isSameKeyPath = require_utils_isSameKeyPath.isSameKeyPath;
273
290
  exports.isValidElement = require_utils_isValidReactElement.isValidElement;
274
291
  exports.list = require_formatters_list.list;
@@ -280,6 +297,7 @@ exports.localeResolver = require_localization_localeResolver.localeResolver;
280
297
  exports.localeStorageOptions = require_utils_localeStorage.localeStorageOptions;
281
298
  exports.md = require_transpiler_markdown_markdown.md;
282
299
  exports.mergeDictionaries = require_dictionaryManipulator_mergeDictionaries.mergeDictionaries;
300
+ exports.mergeQualifiedDictionaries = require_dictionaryManipulator_mergeQualifiedDictionaries.mergeQualifiedDictionaries;
283
301
  exports.nest = require_transpiler_nesting_nesting.nest;
284
302
  exports.nestedPlugin = require_interpreter_getContent_plugins.nestedPlugin;
285
303
  exports.normalizeAttributeKey = require_markdown_utils.normalizeAttributeKey;
@@ -290,6 +308,7 @@ exports.number = require_formatters_number.number;
290
308
  exports.orderDictionaries = require_dictionaryManipulator_orderDictionaries.orderDictionaries;
291
309
  exports.parseBlock = require_markdown_utils.parseBlock;
292
310
  exports.parseCaptureInline = require_markdown_utils.parseCaptureInline;
311
+ exports.parseDictionarySelector = require_dictionaryManipulator_qualifiedDictionary.parseDictionarySelector;
293
312
  exports.parseInline = require_markdown_utils.parseInline;
294
313
  exports.parseMarkdown = require_markdown_compiler.parseMarkdown;
295
314
  exports.parseSimpleInline = require_markdown_utils.parseSimpleInline;
@@ -298,6 +317,7 @@ exports.parseTableAlign = require_markdown_utils.parseTableAlign;
298
317
  exports.parseTableAlignCapture = require_markdown_utils.parseTableAlignCapture;
299
318
  exports.parseTableCells = require_markdown_utils.parseTableCells;
300
319
  exports.parseTableRow = require_markdown_utils.parseTableRow;
320
+ exports.parseTaggedMessage = require_messageFormat_resolveMessage.parseTaggedMessage;
301
321
  exports.parseYaml = require_utils_parseYaml.parseYaml;
302
322
  exports.parserFor = require_markdown_parser.parserFor;
303
323
  exports.percentage = require_formatters_percentage.percentage;
@@ -306,12 +326,18 @@ exports.pluralPlugin = require_interpreter_getContent_plugins.pluralPlugin;
306
326
  exports.portableObjectToIntlayerFormatter = require_messageFormat_po.portableObjectToIntlayerFormatter;
307
327
  exports.presets = require_formatters_date.presets;
308
328
  exports.qualifies = require_markdown_utils.qualifies;
329
+ exports.reconstructQualifiedEntry = require_dictionaryManipulator_qualifiedDictionary.reconstructQualifiedEntry;
309
330
  exports.relativeTime = require_formatters_relativeTime.relativeTime;
310
331
  exports.removeContentNodeByKeyPath = require_dictionaryManipulator_removeContentNodeByKeyPath.removeContentNodeByKeyPath;
311
332
  exports.renameContentNodeByKeyPath = require_dictionaryManipulator_renameContentNodeByKeyPath.renameContentNodeByKeyPath;
312
333
  exports.renderFor = require_markdown_renderer.renderFor;
313
334
  exports.renderMarkdownAst = require_markdown_compiler.renderMarkdownAst;
314
335
  exports.renderNothing = require_markdown_utils.renderNothing;
336
+ exports.resolveMessage = require_messageFormat_resolveMessage.resolveMessage;
337
+ exports.resolveMessageNode = require_messageFormat_resolveMessage.resolveMessageNode;
338
+ exports.resolveQualifiedDictionary = require_dictionaryManipulator_qualifiedDictionary.resolveQualifiedDictionary;
339
+ exports.resolveQualifiedDynamicContent = require_dictionaryManipulator_qualifiedDictionary.resolveQualifiedDynamicContent;
340
+ exports.resolveQualifiedDynamicContentAsync = require_dictionaryManipulator_qualifiedDictionary.resolveQualifiedDynamicContentAsync;
315
341
  exports.sanitizer = require_markdown_utils.sanitizer;
316
342
  exports.setLocaleInStorage = require_utils_localeStorage.setLocaleInStorage;
317
343
  exports.setLocaleInStorageClient = require_utils_localeStorage.setLocaleInStorageClient;
@@ -0,0 +1,25 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ //#region src/interpreter/getCollection.ts
4
+ /**
5
+ * Picks a single item from a resolved collection array, or returns the full
6
+ * array when no index is requested.
7
+ *
8
+ * @param items - The already-resolved collection items.
9
+ * @param itemIndex - Optional 0-based index of the item to retrieve.
10
+ * @returns The item at `itemIndex`, or the full array when no index is given.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const all = getCollection(['a', 'b', 'c']); // ['a', 'b', 'c']
15
+ * const one = getCollection(['a', 'b', 'c'], 1); // 'b'
16
+ * ```
17
+ */
18
+ const getCollection = (items, itemIndex) => {
19
+ if (itemIndex === void 0 || itemIndex === null) return items;
20
+ return items[itemIndex];
21
+ };
22
+
23
+ //#endregion
24
+ exports.getCollection = getCollection;
25
+ //# sourceMappingURL=getCollection.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getCollection.cjs","names":[],"sources":["../../../src/interpreter/getCollection.ts"],"sourcesContent":["/**\n * Picks a single item from a resolved collection array, or returns the full\n * array when no index is requested.\n *\n * @param items - The already-resolved collection items.\n * @param itemIndex - Optional 0-based index of the item to retrieve.\n * @returns The item at `itemIndex`, or the full array when no index is given.\n *\n * @example\n * ```ts\n * const all = getCollection(['a', 'b', 'c']); // ['a', 'b', 'c']\n * const one = getCollection(['a', 'b', 'c'], 1); // 'b'\n * ```\n */\nexport const getCollection = <T>(items: T[], itemIndex?: number): T | T[] => {\n if (itemIndex === undefined || itemIndex === null) {\n return items;\n }\n\n return items[itemIndex] as T;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAcA,MAAa,iBAAoB,OAAY,cAAgC;AAC3E,KAAI,cAAc,UAAa,cAAc,KAC3C,QAAO;AAGT,QAAO,MAAM"}
@@ -1,23 +1,38 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_dictionaryManipulator_qualifiedDictionary = require('../dictionaryManipulator/qualifiedDictionary.cjs');
2
3
  const require_interpreter_getContent_getContent = require('./getContent/getContent.cjs');
3
4
 
4
5
  //#region src/interpreter/getDictionary.ts
5
6
  /**
6
7
  * Transforms a dictionary in a single pass, applying each plugin as needed.
7
8
  *
8
- * @param dictionary The dictionary to transform.
9
- * @param locale The locale to use if your transformers need it (e.g. for translations).
10
- * @param additionalPlugins An array of NodeTransformer that define how to transform recognized nodes.
11
- * If omitted, we’ll use a default set of plugins.
9
+ * Also accepts a `QualifiedDictionaryGroup` (collections, variants, meta
10
+ * records) together with a selector as second argument the group is resolved
11
+ * to a single entry (or an ordered array of entries for collections without an
12
+ * `item` selector) before transformation.
13
+ *
14
+ * @param dictionary The dictionary (or qualified dictionary group) to transform.
15
+ * @param localeOrSelector The locale, or a selector object (`{ item }`,
16
+ * `{ variant }`, `{ id, ...meta }`, optionally with `locale`).
17
+ * @param plugins An array of NodeTransformer that define how to transform recognized nodes.
18
+ * If omitted, we’ll use a default set of plugins.
12
19
  */
13
- const getDictionary = (dictionary, locale, plugins = require_interpreter_getContent_getContent.getBasePlugins(locale)) => {
14
- const props = {
15
- dictionaryKey: dictionary.key,
16
- dictionaryPath: dictionary.filePath,
17
- keyPath: [],
18
- plugins
20
+ const getDictionary = (dictionary, localeOrSelector, plugins) => {
21
+ const { locale, selector } = require_dictionaryManipulator_qualifiedDictionary.parseDictionarySelector(localeOrSelector);
22
+ const appliedPlugins = plugins ?? require_interpreter_getContent_getContent.getBasePlugins(locale);
23
+ const resolved = require_dictionaryManipulator_qualifiedDictionary.resolveQualifiedDictionary(dictionary, selector);
24
+ const transformDictionary = (resolvedDictionary) => {
25
+ const props = {
26
+ dictionaryKey: resolvedDictionary.key,
27
+ dictionaryPath: resolvedDictionary.filePath,
28
+ keyPath: [],
29
+ plugins: appliedPlugins
30
+ };
31
+ return require_interpreter_getContent_getContent.getContent(resolvedDictionary.content, props, appliedPlugins);
19
32
  };
20
- return require_interpreter_getContent_getContent.getContent(dictionary.content, props, plugins);
33
+ if (resolved === null) return null;
34
+ if (Array.isArray(resolved)) return resolved.map(transformDictionary);
35
+ return transformDictionary(resolved);
21
36
  };
22
37
 
23
38
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"getDictionary.cjs","names":["getBasePlugins","getContent"],"sources":["../../../src/interpreter/getDictionary.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n NodeProps,\n Plugins,\n} from './getContent';\nimport { getBasePlugins, getContent } from './getContent/getContent';\n\n/**\n * Transforms a dictionary in a single pass, applying each plugin as needed.\n *\n * @param dictionary The dictionary to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n * @param additionalPlugins An array of NodeTransformer that define how to transform recognized nodes.\n * If omitted, we’ll use a default set of plugins.\n */\nexport const getDictionary = <\n const T extends Dictionary,\n const L extends LocalesValues = DeclaredLocales,\n>(\n dictionary: T,\n locale?: L,\n plugins: Plugins[] = getBasePlugins(locale)\n): DeepTransformContent<T['content'], IInterpreterPluginState, L> => {\n const props: NodeProps = {\n dictionaryKey: dictionary.key,\n dictionaryPath: dictionary.filePath,\n keyPath: [],\n plugins,\n };\n\n return getContent(dictionary.content, props, plugins);\n};\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAa,iBAIX,YACA,QACA,UAAqBA,yDAAe,OAAO,KACwB;CACnE,MAAM,QAAmB;EACvB,eAAe,WAAW;EAC1B,gBAAgB,WAAW;EAC3B,SAAS,EAAE;EACX;EACD;AAED,QAAOC,qDAAW,WAAW,SAAS,OAAO,QAAQ"}
1
+ {"version":3,"file":"getDictionary.cjs","names":["parseDictionarySelector","getBasePlugins","resolveQualifiedDictionary","getContent"],"sources":["../../../src/interpreter/getDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionarySelector,\n QualifiedDictionaryGroup,\n ResolveQualifiedDictionaryContent,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n parseDictionarySelector,\n resolveQualifiedDictionary,\n} from '../dictionaryManipulator/qualifiedDictionary';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n NodeProps,\n Plugins,\n} from './getContent';\nimport { getBasePlugins, getContent } from './getContent/getContent';\n\n/**\n * Transforms a dictionary in a single pass, applying each plugin as needed.\n *\n * Also accepts a `QualifiedDictionaryGroup` (collections, variants, meta\n * records) together with a selector as second argument — the group is resolved\n * to a single entry (or an ordered array of entries for collections without an\n * `item` selector) before transformation.\n *\n * @param dictionary The dictionary (or qualified dictionary group) to transform.\n * @param localeOrSelector The locale, or a selector object (`{ item }`,\n * `{ variant }`, `{ id, ...meta }`, optionally with `locale`).\n * @param plugins An array of NodeTransformer that define how to transform recognized nodes.\n * If omitted, we’ll use a default set of plugins.\n */\nexport const getDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A,\n plugins?: Plugins[]\n): DeepTransformContent<\n ResolveQualifiedDictionaryContent<T, A>,\n IInterpreterPluginState,\n ExtractSelectorLocale<A>\n> => {\n const { locale, selector } = parseDictionarySelector(localeOrSelector);\n const appliedPlugins = plugins ?? getBasePlugins(locale);\n\n const resolved = resolveQualifiedDictionary(dictionary, selector);\n\n const transformDictionary = (resolvedDictionary: Dictionary) => {\n const props: NodeProps = {\n dictionaryKey: resolvedDictionary.key,\n dictionaryPath: resolvedDictionary.filePath,\n keyPath: [],\n plugins: appliedPlugins,\n };\n\n return getContent(resolvedDictionary.content, props, appliedPlugins);\n };\n\n if (resolved === null) return null as any;\n\n if (Array.isArray(resolved)) {\n return resolved.map(transformDictionary) as any;\n }\n\n return transformDictionary(resolved) as any;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqCA,MAAa,iBAIX,YACA,kBACA,YAKG;CACH,MAAM,EAAE,QAAQ,aAAaA,0EAAwB,iBAAiB;CACtE,MAAM,iBAAiB,WAAWC,yDAAe,OAAO;CAExD,MAAM,WAAWC,6EAA2B,YAAY,SAAS;CAEjE,MAAM,uBAAuB,uBAAmC;EAC9D,MAAM,QAAmB;GACvB,eAAe,mBAAmB;GAClC,gBAAgB,mBAAmB;GACnC,SAAS,EAAE;GACX,SAAS;GACV;AAED,SAAOC,qDAAW,mBAAmB,SAAS,OAAO,eAAe;;AAGtE,KAAI,aAAa,KAAM,QAAO;AAE9B,KAAI,MAAM,QAAQ,SAAS,CACzB,QAAO,SAAS,IAAI,oBAAoB;AAG1C,QAAO,oBAAoB,SAAS"}
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ const require_dictionaryManipulator_qualifiedDictionary = require('../dictionaryManipulator/qualifiedDictionary.cjs');
3
4
  const require_interpreter_getDictionary = require('./getDictionary.cjs');
4
5
  let _intlayer_config_built = require("@intlayer/config/built");
5
6
  let _intlayer_config_logger = require("@intlayer/config/logger");
@@ -22,7 +23,17 @@ const createSafeFallback = (path = "") => {
22
23
  };
23
24
  const dictionaryCache = /* @__PURE__ */ new Map();
24
25
  const warnedMissingDictionaries = /* @__PURE__ */ new Set();
25
- const getIntlayer = (key, locale, plugins) => {
26
+ /**
27
+ * Picks one dictionary by its key and returns its content for the given
28
+ * locale or selector.
29
+ *
30
+ * The second argument is either a locale (`'fr'`) or a selector object:
31
+ * - `{ item: 2 }` — collection item (omit `item` to get every item as array)
32
+ * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)
33
+ * - `{ id: 'prod_abc', ...metaFields }` — meta record
34
+ * - `locale` can be combined with any selector: `{ item: 2, locale: 'fr' }`
35
+ */
36
+ const getIntlayer = (key, localeOrSelector, plugins) => {
26
37
  const dictionary = (0, _intlayer_dictionaries_entry.getDictionaries)()[key];
27
38
  if (!dictionary && process.env.NODE_ENV === "development") {
28
39
  if (!warnedMissingDictionaries.has(key)) {
@@ -31,9 +42,11 @@ const getIntlayer = (key, locale, plugins) => {
31
42
  }
32
43
  return createSafeFallback(key);
33
44
  }
34
- const cacheKey = `${key}_${locale ?? "default"}_${plugins ? "custom_plugins" : "default_plugins"}`;
45
+ const { locale, selector } = require_dictionaryManipulator_qualifiedDictionary.parseDictionarySelector(localeOrSelector);
46
+ const selectorCacheKey = require_dictionaryManipulator_qualifiedDictionary.getDictionarySelectorCacheKey(selector);
47
+ const cacheKey = `${key}_${locale ?? "default"}_${selectorCacheKey}_${plugins ? "custom_plugins" : "default_plugins"}`;
35
48
  if (dictionaryCache.has(cacheKey)) return dictionaryCache.get(cacheKey);
36
- const result = require_interpreter_getDictionary.getDictionary(dictionary, locale, plugins);
49
+ const result = require_interpreter_getDictionary.getDictionary(dictionary, localeOrSelector, plugins);
37
50
  dictionaryCache.set(cacheKey, result);
38
51
  return result;
39
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"getIntlayer.cjs","names":["getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryContent,\n DictionaryRegistryElement,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy({} as Record<string | symbol, unknown>, {\n get: (_target, prop) => {\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString' ||\n prop === 'valueOf'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n if (prop === Symbol.iterator) {\n return function* () {\n yield path;\n };\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n });\n};\n\nconst dictionaryCache = new Map<string, any>();\nconst warnedMissingDictionaries = new Set<string>();\n\nexport const getIntlayer = <\n const T extends DictionaryKeys,\n const L extends LocalesValues = DeclaredLocales,\n>(\n key: T,\n locale?: L,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryContent<T>,\n IInterpreterPluginState,\n L\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T] as DictionaryRegistryElement<T>;\n\n if (!dictionary && process.env.NODE_ENV === 'development') {\n if (!warnedMissingDictionaries.has(key as string)) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n typeof window === 'undefined'\n ? `Dictionary ${colorizeKey(key)} was not found. Using fallback proxy.`\n : `Dictionary ${key} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n }\n );\n warnedMissingDictionaries.add(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n const cacheKey = `${key}_${locale ?? 'default'}_${plugins ? 'custom_plugins' : 'default_plugins'}`;\n\n if (dictionaryCache.has(cacheKey)) {\n return dictionaryCache.get(cacheKey);\n }\n\n const result = getDictionary<DictionaryRegistryElement<T>, L>(\n dictionary,\n locale,\n plugins\n );\n\n dictionaryCache.set(cacheKey, result);\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAM,sBAAsB,OAAO,OAAY;AAC7C,QAAO,IAAI,MAAM,EAAE,EAAsC,EACvD,MAAM,SAAS,SAAS;AACtB,MACE,SAAS,YACT,SAAS,OAAO,eAChB,SAAS,cACT,SAAS,UAET,cAAa;AAEf,MAAI,SAAS,OACX;AAEF,MAAI,SAAS,OAAO,SAClB,QAAO,aAAa;AAClB,SAAM;;AAMV,SAAO,mBADU,OAAO,GAAG,KAAK,GAAG,OAAO,KAAK,KAAK,OAAO,KAAK,CAC7B;IAEtC,CAAC;;AAGJ,MAAM,kCAAkB,IAAI,KAAkB;AAC9C,MAAM,4CAA4B,IAAI,KAAa;AAEnD,MAAa,eAIX,KACA,QACA,YAKG;CAEH,MAAM,gEAAyB,CAAC;AAEhC,KAAI,CAAC,cAAc,QAAQ,IAAI,aAAa,eAAe;AACzD,MAAI,CAAC,0BAA0B,IAAI,IAAc,EAAE;AAGjD,6CAD4B,EAAE,iCAAK,CAC7B,CACJ,OAAO,WAAW,cACd,uDAA0B,IAAI,CAAC,yCAC/B,cAAc,IAAI,wCACtB,EACE,OAAO,QACR,CACF;AACD,6BAA0B,IAAI,IAAc;;AAG9C,SAAO,mBAAmB,IAAc;;CAG1C,MAAM,WAAW,GAAG,IAAI,GAAG,UAAU,UAAU,GAAG,UAAU,mBAAmB;AAE/E,KAAI,gBAAgB,IAAI,SAAS,CAC/B,QAAO,gBAAgB,IAAI,SAAS;CAGtC,MAAM,SAASA,gDACb,YACA,QACA,QACD;AAED,iBAAgB,IAAI,UAAU,OAAO;AAErC,QAAO"}
1
+ {"version":3,"file":"getIntlayer.cjs","names":["parseDictionarySelector","getDictionarySelectorCacheKey","getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n getDictionarySelectorCacheKey,\n parseDictionarySelector,\n} from '../dictionaryManipulator/qualifiedDictionary';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy({} as Record<string | symbol, unknown>, {\n get: (_target, prop) => {\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString' ||\n prop === 'valueOf'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n if (prop === Symbol.iterator) {\n return function* () {\n yield path;\n };\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n });\n};\n\nconst dictionaryCache = new Map<string, any>();\nconst warnedMissingDictionaries = new Set<string>();\n\n/**\n * Picks one dictionary by its key and returns its content for the given\n * locale or selector.\n *\n * The second argument is either a locale (`'fr'`) or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ id: 'prod_abc', ...metaFields }` — meta record\n * - `locale` can be combined with any selector: `{ item: 2, locale: 'fr' }`\n */\nexport const getIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryResult<T, A>,\n IInterpreterPluginState,\n ExtractSelectorLocale<A>\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T];\n\n if (!dictionary && process.env.NODE_ENV === 'development') {\n if (!warnedMissingDictionaries.has(key as string)) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n typeof window === 'undefined'\n ? `Dictionary ${colorizeKey(key)} was not found. Using fallback proxy.`\n : `Dictionary ${key} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n }\n );\n warnedMissingDictionaries.add(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n const { locale, selector } = parseDictionarySelector(localeOrSelector);\n const selectorCacheKey = getDictionarySelectorCacheKey(selector);\n\n const cacheKey = `${key}_${locale ?? 'default'}_${selectorCacheKey}_${plugins ? 'custom_plugins' : 'default_plugins'}`;\n\n if (dictionaryCache.has(cacheKey)) {\n return dictionaryCache.get(cacheKey);\n }\n\n const result = getDictionary(dictionary, localeOrSelector, plugins);\n\n dictionaryCache.set(cacheKey, result);\n\n return result as any;\n};\n"],"mappings":";;;;;;;;;;;;;AA0BA,MAAM,sBAAsB,OAAO,OAAY;AAC7C,QAAO,IAAI,MAAM,EAAE,EAAsC,EACvD,MAAM,SAAS,SAAS;AACtB,MACE,SAAS,YACT,SAAS,OAAO,eAChB,SAAS,cACT,SAAS,UAET,cAAa;AAEf,MAAI,SAAS,OACX;AAEF,MAAI,SAAS,OAAO,SAClB,QAAO,aAAa;AAClB,SAAM;;AAMV,SAAO,mBADU,OAAO,GAAG,KAAK,GAAG,OAAO,KAAK,KAAK,OAAO,KAAK,CAC7B;IAEtC,CAAC;;AAGJ,MAAM,kCAAkB,IAAI,KAAkB;AAC9C,MAAM,4CAA4B,IAAI,KAAa;;;;;;;;;;;AAYnD,MAAa,eAIX,KACA,kBACA,YAKG;CAEH,MAAM,gEAAyB,CAAC;AAEhC,KAAI,CAAC,cAAc,QAAQ,IAAI,aAAa,eAAe;AACzD,MAAI,CAAC,0BAA0B,IAAI,IAAc,EAAE;AAGjD,6CAD4B,EAAE,iCAAK,CAC7B,CACJ,OAAO,WAAW,cACd,uDAA0B,IAAI,CAAC,yCAC/B,cAAc,IAAI,wCACtB,EACE,OAAO,QACR,CACF;AACD,6BAA0B,IAAI,IAAc;;AAG9C,SAAO,mBAAmB,IAAc;;CAG1C,MAAM,EAAE,QAAQ,aAAaA,0EAAwB,iBAAiB;CACtE,MAAM,mBAAmBC,gFAA8B,SAAS;CAEhE,MAAM,WAAW,GAAG,IAAI,GAAG,UAAU,UAAU,GAAG,iBAAiB,GAAG,UAAU,mBAAmB;AAEnG,KAAI,gBAAgB,IAAI,SAAS,CAC/B,QAAO,gBAAgB,IAAI,SAAS;CAGtC,MAAM,SAASC,gDAAc,YAAY,kBAAkB,QAAQ;AAEnE,iBAAgB,IAAI,UAAU,OAAO;AAErC,QAAO"}
@@ -0,0 +1,30 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ //#region src/interpreter/getVariant.ts
4
+ /**
5
+ * Resolves a variant node to its selected alternative.
6
+ *
7
+ * Falls back to `control` when the requested `variantKey` does not exist in
8
+ * the node or when no key is specified.
9
+ *
10
+ * @param variantContent - The map of variant alternatives.
11
+ * @param variantKey - Optional name of the alternative to select.
12
+ * @returns The resolved content for the requested variant.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const node = { control: 'Welcome', black_friday: 'Up to 50% off' };
17
+ *
18
+ * getVariant(node); // 'Welcome'
19
+ * getVariant(node, 'black_friday'); // 'Up to 50% off'
20
+ * getVariant(node, 'nonexistent'); // 'Welcome' (fallback to control)
21
+ * ```
22
+ */
23
+ const getVariant = (variantContent, variantKey) => {
24
+ if (variantKey && variantKey in variantContent) return variantContent[variantKey];
25
+ return variantContent.control;
26
+ };
27
+
28
+ //#endregion
29
+ exports.getVariant = getVariant;
30
+ //# sourceMappingURL=getVariant.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getVariant.cjs","names":[],"sources":["../../../src/interpreter/getVariant.ts"],"sourcesContent":["import type { VariantContentState } from '../transpiler/variant/variant';\n\n/**\n * Resolves a variant node to its selected alternative.\n *\n * Falls back to `control` when the requested `variantKey` does not exist in\n * the node or when no key is specified.\n *\n * @param variantContent - The map of variant alternatives.\n * @param variantKey - Optional name of the alternative to select.\n * @returns The resolved content for the requested variant.\n *\n * @example\n * ```ts\n * const node = { control: 'Welcome', black_friday: 'Up to 50% off' };\n *\n * getVariant(node); // 'Welcome'\n * getVariant(node, 'black_friday'); // 'Up to 50% off'\n * getVariant(node, 'nonexistent'); // 'Welcome' (fallback to control)\n * ```\n */\nexport const getVariant = <T>(\n variantContent: VariantContentState<T>,\n variantKey?: string\n): T => {\n if (variantKey && variantKey in variantContent) {\n return variantContent[variantKey] as T;\n }\n\n return variantContent.control as T;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,cACX,gBACA,eACM;AACN,KAAI,cAAc,cAAc,eAC9B,QAAO,eAAe;AAGxB,QAAO,eAAe"}
@@ -41,7 +41,7 @@ const detectLanguage = (order, options) => {
41
41
  const cookies = document.cookie.split(";");
42
42
  const cookieName = `${name}=`;
43
43
  const cookie = cookies.find((cookie) => cookie.trim().startsWith(cookieName));
44
- if (cookie) return cookie.split("=")[1].trim();
44
+ if (cookie) return cookie.split("=")[1]?.trim();
45
45
  } catch {}
46
46
  },
47
47
  getSessionStorage: (name) => {
@@ -1 +1 @@
1
- {"version":3,"file":"getBrowserLocale.cjs","names":["getLocaleFromStorageClient","localeDetector","internationalization","DEFAULT_LOCALE"],"sources":["../../../src/localization/getBrowserLocale.tsx"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { getLocaleFromStorageClient } from '../utils/localeStorage';\nimport { localeDetector } from './localeDetector';\n\nexport enum LanguageDetector {\n Querystring = 'querystring',\n Storage = 'storage',\n Navigator = 'navigator',\n HtmlTag = 'htmlTag',\n}\n\n// Default settings for the language detector\ntype LanguageDetectorOptions = {\n order?: LanguageDetector[];\n lookupQuerystring?: string;\n htmlTag?: HTMLElement | null;\n};\n\nconst getDefaultsOptions = (): LanguageDetectorOptions => {\n return {\n order: [\n LanguageDetector.Querystring,\n LanguageDetector.Storage,\n LanguageDetector.Navigator,\n LanguageDetector.HtmlTag,\n ],\n lookupQuerystring: 'locale',\n htmlTag: typeof document !== 'undefined' ? document.documentElement : null,\n };\n};\n\nconst detectLanguage = (\n order: string[],\n options: LanguageDetectorOptions\n): Record<LanguageDetector, Locale | undefined> => {\n const detected: Record<LanguageDetector, Locale | undefined> = {} as Record<\n LanguageDetector,\n Locale | undefined\n >;\n\n const queryStringDetector = () => {\n if (typeof window === 'undefined') return;\n const search = window.location.search || '';\n const params = new URLSearchParams(search);\n const value = params.get(options.lookupQuerystring ?? '');\n if (value) {\n detected[LanguageDetector.Querystring] = value as Locale;\n }\n };\n\n const storageDetector = () => {\n if (typeof window === 'undefined') return;\n\n const locale = getLocaleFromStorageClient({\n getCookie: (name: string) => {\n try {\n const cookies = document.cookie.split(';');\n const cookieName = `${name}=`;\n\n const cookie = cookies.find((cookie) =>\n cookie.trim().startsWith(cookieName)\n );\n\n if (cookie) {\n return cookie.split('=')[1].trim();\n }\n } catch {}\n return undefined;\n },\n getSessionStorage: (name: string) => {\n try {\n return window.sessionStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n getLocaleStorage: (name: string) => {\n try {\n return window.localStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n });\n\n if (locale) {\n detected[LanguageDetector.Storage] = locale;\n }\n };\n\n const navigatorDetector = () => {\n if (typeof navigator === 'undefined') return;\n\n const languages = navigator.languages ?? [navigator.language];\n\n // Use localeDetector to find the best matching locale\n const locale = localeDetector(\n { 'accept-language': languages.join(',') },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n if (locale) {\n detected[LanguageDetector.Navigator] = locale;\n }\n };\n\n const htmlTagDetector = () => {\n const htmlTag = options.htmlTag;\n if (htmlTag && typeof htmlTag.getAttribute === 'function') {\n const lang = htmlTag.getAttribute('lang');\n if (lang) {\n // Validate and resolve the locale\n\n const locale = localeDetector(\n { 'accept-language': lang },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n detected[LanguageDetector.HtmlTag] = locale;\n }\n }\n };\n\n // Map detector names to their corresponding functions\n const detectors: Record<string, () => void> = {\n [LanguageDetector.Querystring]: queryStringDetector,\n [LanguageDetector.Storage]: storageDetector,\n [LanguageDetector.Navigator]: navigatorDetector,\n [LanguageDetector.HtmlTag]: htmlTagDetector,\n };\n\n // Use the provided order to run each detector\n order.forEach((detectorName) => {\n detectors[detectorName]?.();\n });\n\n return detected;\n};\n\nconst getFirstAvailableLocale = (\n locales: Record<LanguageDetector, Locale | undefined>,\n order: LanguageDetector[]\n): Locale => {\n for (const detector of order) {\n const locale = locales[detector];\n\n if (locale && internationalization.locales.includes(locale)) {\n return locale;\n }\n }\n\n return internationalization?.defaultLocale ?? DEFAULT_LOCALE;\n};\n\n/**\n * Core language detector function for browser environments.\n *\n * Detects the user's preferred locale by checking multiple sources in order:\n * 1. Query string parameter\n * 2. Storage (cookies, localStorage, sessionStorage) - uses getLocaleFromStorage\n * 3. Navigator languages - uses localeDetector\n * 4. HTML lang attribute - uses localeDetector\n *\n * @param userOptions - Optional configuration for detection order and lookup keys\n * @returns The detected locale or the default locale\n *\n * @example\n * const locale = getBrowserLocale({ order: [LanguageDetector.Storage, LanguageDetector.Navigator] });\n */\nexport const getBrowserLocale = (\n userOptions: LanguageDetectorOptions | undefined = {}\n): Locale => {\n const options = { ...getDefaultsOptions(), ...userOptions };\n\n const locales = detectLanguage(options.order ?? [], options);\n\n return getFirstAvailableLocale(locales, options.order ?? []);\n};\n"],"mappings":";;;;;;;;AAMA,IAAY,mBAAL;AACL;AACA;AACA;AACA;;KACD;AASD,MAAM,2BAAoD;AACxD,QAAO;EACL,OAAO;;;;;GAKN;EACD,mBAAmB;EACnB,SAAS,OAAO,aAAa,cAAc,SAAS,kBAAkB;EACvE;;AAGH,MAAM,kBACJ,OACA,YACiD;CACjD,MAAM,WAAyD,EAAE;CAKjE,MAAM,4BAA4B;AAChC,MAAI,OAAO,WAAW,YAAa;EACnC,MAAM,SAAS,OAAO,SAAS,UAAU;EAEzC,MAAM,QAAQ,IADK,gBAAgB,OACf,CAAC,IAAI,QAAQ,qBAAqB,GAAG;AACzD,MAAI,MACF,2BAAyC;;CAI7C,MAAM,wBAAwB;AAC5B,MAAI,OAAO,WAAW,YAAa;EAEnC,MAAM,SAASA,uDAA2B;GACxC,YAAY,SAAiB;AAC3B,QAAI;KACF,MAAM,UAAU,SAAS,OAAO,MAAM,IAAI;KAC1C,MAAM,aAAa,GAAG,KAAK;KAE3B,MAAM,SAAS,QAAQ,MAAM,WAC3B,OAAO,MAAM,CAAC,WAAW,WAAW,CACrC;AAED,SAAI,OACF,QAAO,OAAO,MAAM,IAAI,CAAC,GAAG,MAAM;YAE9B;;GAGV,oBAAoB,SAAiB;AACnC,QAAI;AACF,YAAO,OAAO,eAAe,QAAQ,KAAK,IAAI;YACxC;;GAGV,mBAAmB,SAAiB;AAClC,QAAI;AACF,YAAO,OAAO,aAAa,QAAQ,KAAK,IAAI;YACtC;;GAGX,CAAC;AAEF,MAAI,OACF,uBAAqC;;CAIzC,MAAM,0BAA0B;AAC9B,MAAI,OAAO,cAAc,YAAa;EAKtC,MAAM,SAASC,mDACb,EAAE,oBAJc,UAAU,aAAa,CAAC,UAAU,SAAS,EAI5B,KAAK,IAAI,EAAE,EAC1CC,4CAAqB,SACrBA,4CAAqB,cACtB;AAED,MAAI,OACF,yBAAuC;;CAI3C,MAAM,wBAAwB;EAC5B,MAAM,UAAU,QAAQ;AACxB,MAAI,WAAW,OAAO,QAAQ,iBAAiB,YAAY;GACzD,MAAM,OAAO,QAAQ,aAAa,OAAO;AACzC,OAAI,KASF,uBANeD,mDACb,EAAE,mBAAmB,MAAM,EAC3BC,4CAAqB,SACrBA,4CAAqB,cAGoB;;;CAMjD,MAAM,YAAwC;mBACZ;eACJ;iBACE;eACF;EAC7B;AAGD,OAAM,SAAS,iBAAiB;AAC9B,YAAU,iBAAiB;GAC3B;AAEF,QAAO;;AAGT,MAAM,2BACJ,SACA,UACW;AACX,MAAK,MAAM,YAAY,OAAO;EAC5B,MAAM,SAAS,QAAQ;AAEvB,MAAI,UAAUA,4CAAqB,QAAQ,SAAS,OAAO,CACzD,QAAO;;AAIX,QAAOA,6CAAsB,iBAAiBC;;;;;;;;;;;;;;;;;AAkBhD,MAAa,oBACX,cAAmD,EAAE,KAC1C;CACX,MAAM,UAAU;EAAE,GAAG,oBAAoB;EAAE,GAAG;EAAa;AAI3D,QAAO,wBAFS,eAAe,QAAQ,SAAS,EAAE,EAAE,QAEd,EAAE,QAAQ,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"getBrowserLocale.cjs","names":["getLocaleFromStorageClient","localeDetector","internationalization","DEFAULT_LOCALE"],"sources":["../../../src/localization/getBrowserLocale.tsx"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { getLocaleFromStorageClient } from '../utils/localeStorage';\nimport { localeDetector } from './localeDetector';\n\nexport enum LanguageDetector {\n Querystring = 'querystring',\n Storage = 'storage',\n Navigator = 'navigator',\n HtmlTag = 'htmlTag',\n}\n\n// Default settings for the language detector\ntype LanguageDetectorOptions = {\n order?: LanguageDetector[];\n lookupQuerystring?: string;\n htmlTag?: HTMLElement | null;\n};\n\nconst getDefaultsOptions = (): LanguageDetectorOptions => {\n return {\n order: [\n LanguageDetector.Querystring,\n LanguageDetector.Storage,\n LanguageDetector.Navigator,\n LanguageDetector.HtmlTag,\n ],\n lookupQuerystring: 'locale',\n htmlTag: typeof document !== 'undefined' ? document.documentElement : null,\n };\n};\n\nconst detectLanguage = (\n order: string[],\n options: LanguageDetectorOptions\n): Record<LanguageDetector, Locale | undefined> => {\n const detected: Record<LanguageDetector, Locale | undefined> = {} as Record<\n LanguageDetector,\n Locale | undefined\n >;\n\n const queryStringDetector = () => {\n if (typeof window === 'undefined') return;\n const search = window.location.search || '';\n const params = new URLSearchParams(search);\n const value = params.get(options.lookupQuerystring ?? '');\n if (value) {\n detected[LanguageDetector.Querystring] = value as Locale;\n }\n };\n\n const storageDetector = () => {\n if (typeof window === 'undefined') return;\n\n const locale = getLocaleFromStorageClient({\n getCookie: (name: string) => {\n try {\n const cookies = document.cookie.split(';');\n const cookieName = `${name}=`;\n\n const cookie = cookies.find((cookie) =>\n cookie.trim().startsWith(cookieName)\n );\n\n if (cookie) {\n return cookie.split('=')[1]?.trim();\n }\n } catch {}\n return undefined;\n },\n getSessionStorage: (name: string) => {\n try {\n return window.sessionStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n getLocaleStorage: (name: string) => {\n try {\n return window.localStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n });\n\n if (locale) {\n detected[LanguageDetector.Storage] = locale;\n }\n };\n\n const navigatorDetector = () => {\n if (typeof navigator === 'undefined') return;\n\n const languages = navigator.languages ?? [navigator.language];\n\n // Use localeDetector to find the best matching locale\n const locale = localeDetector(\n { 'accept-language': languages.join(',') },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n if (locale) {\n detected[LanguageDetector.Navigator] = locale;\n }\n };\n\n const htmlTagDetector = () => {\n const htmlTag = options.htmlTag;\n if (htmlTag && typeof htmlTag.getAttribute === 'function') {\n const lang = htmlTag.getAttribute('lang');\n if (lang) {\n // Validate and resolve the locale\n\n const locale = localeDetector(\n { 'accept-language': lang },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n detected[LanguageDetector.HtmlTag] = locale;\n }\n }\n };\n\n // Map detector names to their corresponding functions\n const detectors: Record<string, () => void> = {\n [LanguageDetector.Querystring]: queryStringDetector,\n [LanguageDetector.Storage]: storageDetector,\n [LanguageDetector.Navigator]: navigatorDetector,\n [LanguageDetector.HtmlTag]: htmlTagDetector,\n };\n\n // Use the provided order to run each detector\n order.forEach((detectorName) => {\n detectors[detectorName]?.();\n });\n\n return detected;\n};\n\nconst getFirstAvailableLocale = (\n locales: Record<LanguageDetector, Locale | undefined>,\n order: LanguageDetector[]\n): Locale => {\n for (const detector of order) {\n const locale = locales[detector];\n\n if (locale && internationalization.locales.includes(locale)) {\n return locale;\n }\n }\n\n return internationalization?.defaultLocale ?? DEFAULT_LOCALE;\n};\n\n/**\n * Core language detector function for browser environments.\n *\n * Detects the user's preferred locale by checking multiple sources in order:\n * 1. Query string parameter\n * 2. Storage (cookies, localStorage, sessionStorage) - uses getLocaleFromStorage\n * 3. Navigator languages - uses localeDetector\n * 4. HTML lang attribute - uses localeDetector\n *\n * @param userOptions - Optional configuration for detection order and lookup keys\n * @returns The detected locale or the default locale\n *\n * @example\n * const locale = getBrowserLocale({ order: [LanguageDetector.Storage, LanguageDetector.Navigator] });\n */\nexport const getBrowserLocale = (\n userOptions: LanguageDetectorOptions | undefined = {}\n): Locale => {\n const options = { ...getDefaultsOptions(), ...userOptions };\n\n const locales = detectLanguage(options.order ?? [], options);\n\n return getFirstAvailableLocale(locales, options.order ?? []);\n};\n"],"mappings":";;;;;;;;AAMA,IAAY,mBAAL;AACL;AACA;AACA;AACA;;KACD;AASD,MAAM,2BAAoD;AACxD,QAAO;EACL,OAAO;;;;;GAKN;EACD,mBAAmB;EACnB,SAAS,OAAO,aAAa,cAAc,SAAS,kBAAkB;EACvE;;AAGH,MAAM,kBACJ,OACA,YACiD;CACjD,MAAM,WAAyD,EAAE;CAKjE,MAAM,4BAA4B;AAChC,MAAI,OAAO,WAAW,YAAa;EACnC,MAAM,SAAS,OAAO,SAAS,UAAU;EAEzC,MAAM,QAAQ,IADK,gBAAgB,OACf,CAAC,IAAI,QAAQ,qBAAqB,GAAG;AACzD,MAAI,MACF,2BAAyC;;CAI7C,MAAM,wBAAwB;AAC5B,MAAI,OAAO,WAAW,YAAa;EAEnC,MAAM,SAASA,uDAA2B;GACxC,YAAY,SAAiB;AAC3B,QAAI;KACF,MAAM,UAAU,SAAS,OAAO,MAAM,IAAI;KAC1C,MAAM,aAAa,GAAG,KAAK;KAE3B,MAAM,SAAS,QAAQ,MAAM,WAC3B,OAAO,MAAM,CAAC,WAAW,WAAW,CACrC;AAED,SAAI,OACF,QAAO,OAAO,MAAM,IAAI,CAAC,IAAI,MAAM;YAE/B;;GAGV,oBAAoB,SAAiB;AACnC,QAAI;AACF,YAAO,OAAO,eAAe,QAAQ,KAAK,IAAI;YACxC;;GAGV,mBAAmB,SAAiB;AAClC,QAAI;AACF,YAAO,OAAO,aAAa,QAAQ,KAAK,IAAI;YACtC;;GAGX,CAAC;AAEF,MAAI,OACF,uBAAqC;;CAIzC,MAAM,0BAA0B;AAC9B,MAAI,OAAO,cAAc,YAAa;EAKtC,MAAM,SAASC,mDACb,EAAE,oBAJc,UAAU,aAAa,CAAC,UAAU,SAAS,EAI5B,KAAK,IAAI,EAAE,EAC1CC,4CAAqB,SACrBA,4CAAqB,cACtB;AAED,MAAI,OACF,yBAAuC;;CAI3C,MAAM,wBAAwB;EAC5B,MAAM,UAAU,QAAQ;AACxB,MAAI,WAAW,OAAO,QAAQ,iBAAiB,YAAY;GACzD,MAAM,OAAO,QAAQ,aAAa,OAAO;AACzC,OAAI,KASF,uBANeD,mDACb,EAAE,mBAAmB,MAAM,EAC3BC,4CAAqB,SACrBA,4CAAqB,cAGoB;;;CAMjD,MAAM,YAAwC;mBACZ;eACJ;iBACE;eACF;EAC7B;AAGD,OAAM,SAAS,iBAAiB;AAC9B,YAAU,iBAAiB;GAC3B;AAEF,QAAO;;AAGT,MAAM,2BACJ,SACA,UACW;AACX,MAAK,MAAM,YAAY,OAAO;EAC5B,MAAM,SAAS,QAAQ;AAEvB,MAAI,UAAUA,4CAAqB,QAAQ,SAAS,OAAO,CACzD,QAAO;;AAIX,QAAOA,6CAAsB,iBAAiBC;;;;;;;;;;;;;;;;;AAkBhD,MAAa,oBACX,cAAmD,EAAE,KAC1C;CACX,MAAM,UAAU;EAAE,GAAG,oBAAoB;EAAE,GAAG;EAAa;AAI3D,QAAO,wBAFS,eAAe,QAAQ,SAAS,EAAE,EAAE,QAEd,EAAE,QAAQ,SAAS,EAAE,CAAC"}
@@ -80,7 +80,7 @@ const parseICU = (text) => {
80
80
  }
81
81
  if (text[index] === ",") {
82
82
  index++;
83
- if (type === "plural" || type === "select") {
83
+ if (type === "plural" || type === "select" || type === "selectordinal") {
84
84
  const options = {};
85
85
  while (index < text.length && text[index] !== "}") {
86
86
  while (index < text.length && /\s/.test(text[index])) index++;
@@ -109,6 +109,11 @@ const parseICU = (text) => {
109
109
  name,
110
110
  options
111
111
  };
112
+ else if (type === "selectordinal") return {
113
+ type: "selectordinal",
114
+ name,
115
+ options
116
+ };
112
117
  } else {
113
118
  let style = "";
114
119
  while (index < text.length && text[index] !== "}") {
@@ -206,6 +211,19 @@ const icuNodesToIntlayer = (nodes) => {
206
211
  options.__intlayer_icu_var = node.name;
207
212
  return require_transpiler_enumeration_enumeration.enu(options);
208
213
  }
214
+ if (node.type === "selectordinal") {
215
+ const options = {};
216
+ for (const [key, val] of Object.entries(node.options)) {
217
+ const newKey = key.startsWith("=") ? key.substring(1) : key === "other" ? "fallback" : key;
218
+ options[newKey] = icuNodesToIntlayer(val.map((value) => {
219
+ if (typeof value === "string") return value.replace(/#/g, `{{${node.name}}}`);
220
+ return value;
221
+ }));
222
+ }
223
+ options.__intlayer_icu_var = node.name;
224
+ options.__intlayer_icu_ordinal = true;
225
+ return require_transpiler_enumeration_enumeration.enu(options);
226
+ }
209
227
  }
210
228
  return nodes.map((node) => icuNodesToIntlayer([node]));
211
229
  };
@@ -264,7 +282,7 @@ const intlayerToIcuPlugin = {
264
282
  const options = node[_intlayer_types_nodeType.ENUMERATION];
265
283
  const transformedOptions = {};
266
284
  for (const [key, val] of Object.entries(options)) {
267
- if (key === "__intlayer_icu_var") continue;
285
+ if (key === "__intlayer_icu_var" || key === "__intlayer_icu_ordinal") continue;
268
286
  const childVal = next(val, props);
269
287
  transformedOptions[key] = typeof childVal === "string" ? childVal : JSON.stringify(childVal);
270
288
  }
@@ -273,6 +291,18 @@ const intlayerToIcuPlugin = {
273
291
  const match = (transformedOptions.fallback || transformedOptions.other || Object.values(transformedOptions)[0]).match(/\{([a-zA-Z0-9_]+)\}(?!,)/);
274
292
  if (match) varName = match[1];
275
293
  }
294
+ if (options.__intlayer_icu_ordinal === true) {
295
+ const ordinalParts = [];
296
+ for (const [key, val] of Object.entries(transformedOptions)) {
297
+ let icuKey = key;
298
+ if (key === "fallback") icuKey = "other";
299
+ else if (/^\d+$/.test(key)) icuKey = `=${key}`;
300
+ let strVal = val;
301
+ strVal = strVal.replace(new RegExp(`\\{${varName}\\}`, "g"), "#");
302
+ ordinalParts.push(`${icuKey} {${strVal}}`);
303
+ }
304
+ return `{${varName}, selectordinal, ${ordinalParts.join(" ")}}`;
305
+ }
276
306
  const keys = Object.keys(transformedOptions);
277
307
  const pluralKeys = [
278
308
  "1",