@intlayer/core 8.9.2 → 8.9.3
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.
- package/dist/cjs/deepTransformPlugins/getFilterMissingTranslationsContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getFilterTranslationsOnlyContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getFilteredLocalesContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getLocalizedContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getMissingLocalesContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getMultilingualDictionary.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getReplacedValuesContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/getSplittedContent.cjs.map +1 -1
- package/dist/cjs/deepTransformPlugins/insertContentInDictionary.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/editDictionaryByKeyPath.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/getContentNodeByKeyPath.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/getDefaultNode.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/getEmptyNode.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/getNodeChildren.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/getNodeType.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/normalizeDictionary.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/orderDictionaries.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/removeContentNodeByKeyPath.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/renameContentNodeByKeyPath.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/updateNodeChildren.cjs.map +1 -1
- package/dist/cjs/formatters/date.cjs.map +1 -1
- package/dist/cjs/formatters/percentage.cjs.map +1 -1
- package/dist/cjs/formatters/relativeTime.cjs.map +1 -1
- package/dist/cjs/interpreter/getCondition.cjs.map +1 -1
- package/dist/cjs/interpreter/getContent/deepTransform.cjs.map +1 -1
- package/dist/cjs/interpreter/getContent/plugins.cjs.map +1 -1
- package/dist/cjs/interpreter/getDictionary.cjs.map +1 -1
- package/dist/cjs/interpreter/getEnumeration.cjs.map +1 -1
- package/dist/cjs/interpreter/getGender.cjs.map +1 -1
- package/dist/cjs/interpreter/getHTML.cjs.map +1 -1
- package/dist/cjs/interpreter/getInsertion.cjs.map +1 -1
- package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
- package/dist/cjs/interpreter/getNesting.cjs.map +1 -1
- package/dist/cjs/interpreter/getPlural.cjs.map +1 -1
- package/dist/cjs/interpreter/getTranslation.cjs.map +1 -1
- package/dist/cjs/interpreter/splitAndJoinInsertion.cjs.map +1 -1
- package/dist/cjs/localization/generateSitemap.cjs.map +1 -1
- package/dist/cjs/localization/getBrowserLocale.cjs.map +1 -1
- package/dist/cjs/localization/getHTMLTextDir.cjs.map +1 -1
- package/dist/cjs/localization/getLocale.cjs.map +1 -1
- package/dist/cjs/localization/getLocaleFromPath.cjs.map +1 -1
- package/dist/cjs/localization/getLocaleName.cjs.map +1 -1
- package/dist/cjs/localization/getLocalizedUrl.cjs.map +1 -1
- package/dist/cjs/localization/getMultilingualUrls.cjs.map +1 -1
- package/dist/cjs/localization/getPathWithoutLocale.cjs.map +1 -1
- package/dist/cjs/localization/getPrefix.cjs.map +1 -1
- package/dist/cjs/localization/localeDetector.cjs.map +1 -1
- package/dist/cjs/localization/localeMapper.cjs.map +1 -1
- package/dist/cjs/localization/localeResolver.cjs.map +1 -1
- package/dist/cjs/localization/rewriteUtils.cjs.map +1 -1
- package/dist/cjs/localization/validatePrefix.cjs.map +1 -1
- package/dist/cjs/markdown/compiler.cjs.map +1 -1
- package/dist/cjs/markdown/constants.cjs.map +1 -1
- package/dist/cjs/markdown/parser.cjs.map +1 -1
- package/dist/cjs/markdown/renderer.cjs.map +1 -1
- package/dist/cjs/markdown/utils.cjs.map +1 -1
- package/dist/cjs/messageFormat/ICU.cjs.map +1 -1
- package/dist/cjs/messageFormat/i18next.cjs.map +1 -1
- package/dist/cjs/messageFormat/vue-i18n.cjs.map +1 -1
- package/dist/cjs/transpiler/file/file.cjs.map +1 -1
- package/dist/cjs/transpiler/file/fileBrowser.cjs.map +1 -1
- package/dist/cjs/transpiler/html/getHTMLCustomComponents.cjs.map +1 -1
- package/dist/cjs/transpiler/html/html.cjs.map +1 -1
- package/dist/cjs/transpiler/html/validateHTML.cjs.map +1 -1
- package/dist/cjs/transpiler/insertion/getInsertionValues.cjs.map +1 -1
- package/dist/cjs/transpiler/insertion/insertion.cjs.map +1 -1
- package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs.map +1 -1
- package/dist/cjs/transpiler/markdown/markdown.cjs.map +1 -1
- package/dist/cjs/transpiler/markdown/validateMarkdown.cjs.map +1 -1
- package/dist/cjs/utils/getCookie.cjs.map +1 -1
- package/dist/cjs/utils/intl.cjs.map +1 -1
- package/dist/cjs/utils/localeStorage.cjs.map +1 -1
- package/dist/cjs/utils/parseYaml.cjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getFilterMissingTranslationsContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getFilterTranslationsOnlyContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getFilteredLocalesContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getLocalizedContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getMissingLocalesContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getMultilingualDictionary.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getReplacedValuesContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/getSplittedContent.mjs.map +1 -1
- package/dist/esm/deepTransformPlugins/insertContentInDictionary.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/editDictionaryByKeyPath.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/getContentNodeByKeyPath.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/getDefaultNode.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/getEmptyNode.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/getNodeChildren.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/getNodeType.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/normalizeDictionary.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/orderDictionaries.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/removeContentNodeByKeyPath.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/renameContentNodeByKeyPath.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/updateNodeChildren.mjs.map +1 -1
- package/dist/esm/formatters/date.mjs.map +1 -1
- package/dist/esm/formatters/percentage.mjs.map +1 -1
- package/dist/esm/formatters/relativeTime.mjs.map +1 -1
- package/dist/esm/interpreter/getCondition.mjs.map +1 -1
- package/dist/esm/interpreter/getContent/deepTransform.mjs.map +1 -1
- package/dist/esm/interpreter/getContent/plugins.mjs.map +1 -1
- package/dist/esm/interpreter/getDictionary.mjs.map +1 -1
- package/dist/esm/interpreter/getEnumeration.mjs.map +1 -1
- package/dist/esm/interpreter/getGender.mjs.map +1 -1
- package/dist/esm/interpreter/getHTML.mjs.map +1 -1
- package/dist/esm/interpreter/getInsertion.mjs.map +1 -1
- package/dist/esm/interpreter/getIntlayer.mjs.map +1 -1
- package/dist/esm/interpreter/getNesting.mjs.map +1 -1
- package/dist/esm/interpreter/getPlural.mjs.map +1 -1
- package/dist/esm/interpreter/getTranslation.mjs.map +1 -1
- package/dist/esm/interpreter/splitAndJoinInsertion.mjs.map +1 -1
- package/dist/esm/localization/generateSitemap.mjs.map +1 -1
- package/dist/esm/localization/getBrowserLocale.mjs.map +1 -1
- package/dist/esm/localization/getHTMLTextDir.mjs.map +1 -1
- package/dist/esm/localization/getLocale.mjs.map +1 -1
- package/dist/esm/localization/getLocaleFromPath.mjs.map +1 -1
- package/dist/esm/localization/getLocaleName.mjs.map +1 -1
- package/dist/esm/localization/getLocalizedUrl.mjs.map +1 -1
- package/dist/esm/localization/getMultilingualUrls.mjs.map +1 -1
- package/dist/esm/localization/getPathWithoutLocale.mjs.map +1 -1
- package/dist/esm/localization/getPrefix.mjs.map +1 -1
- package/dist/esm/localization/localeDetector.mjs.map +1 -1
- package/dist/esm/localization/localeMapper.mjs.map +1 -1
- package/dist/esm/localization/localeResolver.mjs.map +1 -1
- package/dist/esm/localization/rewriteUtils.mjs.map +1 -1
- package/dist/esm/localization/validatePrefix.mjs.map +1 -1
- package/dist/esm/markdown/compiler.mjs.map +1 -1
- package/dist/esm/markdown/constants.mjs.map +1 -1
- package/dist/esm/markdown/parser.mjs.map +1 -1
- package/dist/esm/markdown/renderer.mjs.map +1 -1
- package/dist/esm/markdown/utils.mjs.map +1 -1
- package/dist/esm/messageFormat/ICU.mjs.map +1 -1
- package/dist/esm/messageFormat/i18next.mjs.map +1 -1
- package/dist/esm/messageFormat/vue-i18n.mjs.map +1 -1
- package/dist/esm/transpiler/file/file.mjs.map +1 -1
- package/dist/esm/transpiler/file/fileBrowser.mjs.map +1 -1
- package/dist/esm/transpiler/html/getHTMLCustomComponents.mjs.map +1 -1
- package/dist/esm/transpiler/html/html.mjs.map +1 -1
- package/dist/esm/transpiler/html/validateHTML.mjs.map +1 -1
- package/dist/esm/transpiler/insertion/getInsertionValues.mjs.map +1 -1
- package/dist/esm/transpiler/insertion/insertion.mjs.map +1 -1
- package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs.map +1 -1
- package/dist/esm/transpiler/markdown/markdown.mjs.map +1 -1
- package/dist/esm/transpiler/markdown/validateMarkdown.mjs.map +1 -1
- package/dist/esm/utils/getCookie.mjs.map +1 -1
- package/dist/esm/utils/intl.mjs.map +1 -1
- package/dist/esm/utils/localeStorage.mjs.map +1 -1
- package/dist/esm/utils/parseYaml.mjs.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderDictionaries.cjs","names":["editor"],"sources":["../../../src/dictionaryManipulator/orderDictionaries.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\n/**\n * Orders dictionaries based on the dictionary priority strategy.\n *\n * @param dictionaries - Array of dictionaries to order\n * @param priorityStrategy - The priority strategy ('local_first' or 'distant_first')\n * @returns Ordered array of dictionaries\n */\nexport const orderDictionaries = (dictionaries: Dictionary[]): Dictionary[] => {\n const { dictionaryPriorityStrategy } = editor;\n\n if (dictionaries.length <= 1) {\n return dictionaries;\n }\n\n // Stabilize original indices to preserve relative order for complete ties\n const withIndex = dictionaries.map((dictionary, index) => ({\n dictionary,\n index,\n }));\n\n const getPriority = (dictionary: Dictionary): number => {\n const p = dictionary.priority ?? 0;\n\n return Number.isFinite(p) ? p : 0;\n };\n\n const getLocationWeight = (d: Dictionary): number => {\n const location = d.location;\n\n // undefined location should always be last\n if (location === undefined) {\n return 2;\n }\n\n if (dictionaryPriorityStrategy === 'distant_first') {\n // distant should come first\n return location === 'remote' ? 0 : 1;\n }\n // default: local_first\n return location === 'local' ? 0 : 1;\n };\n\n withIndex.sort((a, b) => {\n // 1) Non-autoFilled before autoFilled (autoFilled have lower precedence)\n const aAuto = a.dictionary.filled ? 1 : 0;\n const bAuto = b.dictionary.filled ? 1 : 0;\n if (aAuto !== bAuto) return aAuto - bAuto; // 0 before 1\n\n // 2) Higher priority first (larger number wins)\n const aP = getPriority(a.dictionary);\n const bP = getPriority(b.dictionary);\n if (aP !== bP) return bP - aP; // descending\n\n // 3) Location according to strategy\n const aLocation = getLocationWeight(a.dictionary);\n const bLocation = getLocationWeight(b.dictionary);\n if (aLocation !== bLocation) return aLocation - bLocation;\n\n // 4) Stable fallback by original index\n return a.index - b.index;\n });\n\n return withIndex.map(({ dictionary }) => dictionary);\n};\n"],"mappings":";;;;;;;;;;;;AAUA,MAAa,qBAAqB,iBAA6C;CAC7E,MAAM,EAAE,+BAA+BA;
|
|
1
|
+
{"version":3,"file":"orderDictionaries.cjs","names":["editor"],"sources":["../../../src/dictionaryManipulator/orderDictionaries.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\n/**\n * Orders dictionaries based on the dictionary priority strategy.\n *\n * @param dictionaries - Array of dictionaries to order\n * @param priorityStrategy - The priority strategy ('local_first' or 'distant_first')\n * @returns Ordered array of dictionaries\n */\nexport const orderDictionaries = (dictionaries: Dictionary[]): Dictionary[] => {\n const { dictionaryPriorityStrategy } = editor;\n\n if (dictionaries.length <= 1) {\n return dictionaries;\n }\n\n // Stabilize original indices to preserve relative order for complete ties\n const withIndex = dictionaries.map((dictionary, index) => ({\n dictionary,\n index,\n }));\n\n const getPriority = (dictionary: Dictionary): number => {\n const p = dictionary.priority ?? 0;\n\n return Number.isFinite(p) ? p : 0;\n };\n\n const getLocationWeight = (d: Dictionary): number => {\n const location = d.location;\n\n // undefined location should always be last\n if (location === undefined) {\n return 2;\n }\n\n if (dictionaryPriorityStrategy === 'distant_first') {\n // distant should come first\n return location === 'remote' ? 0 : 1;\n }\n // default: local_first\n return location === 'local' ? 0 : 1;\n };\n\n withIndex.sort((a, b) => {\n // 1) Non-autoFilled before autoFilled (autoFilled have lower precedence)\n const aAuto = a.dictionary.filled ? 1 : 0;\n const bAuto = b.dictionary.filled ? 1 : 0;\n if (aAuto !== bAuto) return aAuto - bAuto; // 0 before 1\n\n // 2) Higher priority first (larger number wins)\n const aP = getPriority(a.dictionary);\n const bP = getPriority(b.dictionary);\n if (aP !== bP) return bP - aP; // descending\n\n // 3) Location according to strategy\n const aLocation = getLocationWeight(a.dictionary);\n const bLocation = getLocationWeight(b.dictionary);\n if (aLocation !== bLocation) return aLocation - bLocation;\n\n // 4) Stable fallback by original index\n return a.index - b.index;\n });\n\n return withIndex.map(({ dictionary }) => dictionary);\n};\n"],"mappings":";;;;;;;;;;;;AAUA,MAAa,qBAAqB,iBAA6C;CAC7E,MAAM,EAAE,+BAA+BA;CAEvC,IAAI,aAAa,UAAU,GACzB,OAAO;CAIT,MAAM,YAAY,aAAa,KAAK,YAAY,WAAW;EACzD;EACA;EACD,EAAE;CAEH,MAAM,eAAe,eAAmC;EACtD,MAAM,IAAI,WAAW,YAAY;EAEjC,OAAO,OAAO,SAAS,EAAE,GAAG,IAAI;;CAGlC,MAAM,qBAAqB,MAA0B;EACnD,MAAM,WAAW,EAAE;EAGnB,IAAI,aAAa,QACf,OAAO;EAGT,IAAI,+BAA+B,iBAEjC,OAAO,aAAa,WAAW,IAAI;EAGrC,OAAO,aAAa,UAAU,IAAI;;CAGpC,UAAU,MAAM,GAAG,MAAM;EAEvB,MAAM,QAAQ,EAAE,WAAW,SAAS,IAAI;EACxC,MAAM,QAAQ,EAAE,WAAW,SAAS,IAAI;EACxC,IAAI,UAAU,OAAO,OAAO,QAAQ;EAGpC,MAAM,KAAK,YAAY,EAAE,WAAW;EACpC,MAAM,KAAK,YAAY,EAAE,WAAW;EACpC,IAAI,OAAO,IAAI,OAAO,KAAK;EAG3B,MAAM,YAAY,kBAAkB,EAAE,WAAW;EACjD,MAAM,YAAY,kBAAkB,EAAE,WAAW;EACjD,IAAI,cAAc,WAAW,OAAO,YAAY;EAGhD,OAAO,EAAE,QAAQ,EAAE;GACnB;CAEF,OAAO,UAAU,KAAK,EAAE,iBAAiB,WAAW"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removeContentNodeByKeyPath.cjs","names":["NodeTypes"],"sources":["../../../src/dictionaryManipulator/removeContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const removeContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKey: string | number | null = null;\n\n for (const keyObj of keyPath) {\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKey = keyObj.key;\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.REACT_NODE ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type];\n }\n }\n\n if (parentValue && lastKey !== null) {\n if (Array.isArray(parentValue)) {\n parentValue.splice(lastKey as unknown as number, 1);\n } else {\n delete parentValue[lastKey];\n }\n }\n\n return dictionaryContent;\n};\n"],"mappings":";;;;;;AAKA,MAAa,8BACX,mBACA,YACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,UAAkC;
|
|
1
|
+
{"version":3,"file":"removeContentNodeByKeyPath.cjs","names":["NodeTypes"],"sources":["../../../src/dictionaryManipulator/removeContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const removeContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKey: string | number | null = null;\n\n for (const keyObj of keyPath) {\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKey = keyObj.key;\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.REACT_NODE ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type];\n }\n }\n\n if (parentValue && lastKey !== null) {\n if (Array.isArray(parentValue)) {\n parentValue.splice(lastKey as unknown as number, 1);\n } else {\n delete parentValue[lastKey];\n }\n }\n\n return dictionaryContent;\n};\n"],"mappings":";;;;;;AAKA,MAAa,8BACX,mBACA,YACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,UAAkC;CAEtC,KAAK,MAAM,UAAU,SAAS;EAC5B,cAAc;EAEd,IAAI,OAAO,SAASA,yBAAU,UAAU,OAAO,SAASA,yBAAU,OAAO;GACvE,UAAU,OAAO;GACjB,eAAe,aAAa,OAAO;;EAGrC,IACE,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,UAC1B,OAAO,SAASA,yBAAU,WAC1B;GACA,UAAU,OAAO;GACjB,eAAe,aAAa,OAAO,MAAM,OAAO;;EAGlD,IACE,OAAO,SAASA,yBAAU,YAC1B,OAAO,SAASA,yBAAU,cAC1B,OAAO,SAASA,yBAAU,QAC1B,OAAO,SAASA,yBAAU,aAC1B,OAAO,SAASA,yBAAU,MAC1B;GACA,UAAU,OAAO;GACjB,eAAe,aAAa,OAAO;;;CAIvC,IAAI,eAAe,YAAY,MAC7B,IAAI,MAAM,QAAQ,YAAY,EAC5B,YAAY,OAAO,SAA8B,EAAE;MAEnD,OAAO,YAAY;CAIvB,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renameContentNodeByKeyPath.cjs","names":["NodeTypes"],"sources":["../../../src/dictionaryManipulator/renameContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const renameContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n newKey: KeyPath['key'],\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKey: string | number | null = null;\n\n for (const keyObj of keyPath) {\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKey = keyObj.key;\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.REACT_NODE ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type];\n }\n }\n\n // Assign the new value to the last key of the parent while preserving the order\n if (parentValue && lastKey !== null) {\n if (Array.isArray(parentValue)) {\n parentValue[lastKey as number] = currentValue;\n } else {\n const newParentValue: any = {};\n for (const key of Object.keys(parentValue)) {\n if (key === lastKey && typeof newKey !== 'undefined') {\n newParentValue[newKey] = currentValue;\n } else {\n newParentValue[key] = parentValue[key];\n }\n }\n // Replace the contents of parentValue with newParentValue\n Object.keys(parentValue).forEach((key) => {\n delete parentValue[key];\n });\n Object.assign(parentValue, newParentValue);\n }\n }\n\n return dictionaryContent;\n};\n"],"mappings":";;;;;;AAKA,MAAa,8BACX,mBACA,QACA,YACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,UAAkC;
|
|
1
|
+
{"version":3,"file":"renameContentNodeByKeyPath.cjs","names":["NodeTypes"],"sources":["../../../src/dictionaryManipulator/renameContentNodeByKeyPath.ts"],"sourcesContent":["import type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const renameContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n newKey: KeyPath['key'],\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = dictionaryContent;\n let parentValue: any = null;\n let lastKey: string | number | null = null;\n\n for (const keyObj of keyPath) {\n parentValue = currentValue;\n\n if (keyObj.type === NodeTypes.OBJECT || keyObj.type === NodeTypes.ARRAY) {\n lastKey = keyObj.key;\n currentValue = currentValue[keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.TRANSLATION ||\n keyObj.type === NodeTypes.ENUMERATION ||\n keyObj.type === NodeTypes.PLURAL ||\n keyObj.type === NodeTypes.CONDITION\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type][keyObj.key];\n }\n\n if (\n keyObj.type === NodeTypes.MARKDOWN ||\n keyObj.type === NodeTypes.REACT_NODE ||\n keyObj.type === NodeTypes.HTML ||\n keyObj.type === NodeTypes.INSERTION ||\n keyObj.type === NodeTypes.FILE\n ) {\n lastKey = keyObj.type;\n currentValue = currentValue[keyObj.type];\n }\n }\n\n // Assign the new value to the last key of the parent while preserving the order\n if (parentValue && lastKey !== null) {\n if (Array.isArray(parentValue)) {\n parentValue[lastKey as number] = currentValue;\n } else {\n const newParentValue: any = {};\n for (const key of Object.keys(parentValue)) {\n if (key === lastKey && typeof newKey !== 'undefined') {\n newParentValue[newKey] = currentValue;\n } else {\n newParentValue[key] = parentValue[key];\n }\n }\n // Replace the contents of parentValue with newParentValue\n Object.keys(parentValue).forEach((key) => {\n delete parentValue[key];\n });\n Object.assign(parentValue, newParentValue);\n }\n }\n\n return dictionaryContent;\n};\n"],"mappings":";;;;;;AAKA,MAAa,8BACX,mBACA,QACA,YACgB;CAChB,IAAI,eAAoB;CACxB,IAAI,cAAmB;CACvB,IAAI,UAAkC;CAEtC,KAAK,MAAM,UAAU,SAAS;EAC5B,cAAc;EAEd,IAAI,OAAO,SAASA,yBAAU,UAAU,OAAO,SAASA,yBAAU,OAAO;GACvE,UAAU,OAAO;GACjB,eAAe,aAAa,OAAO;;EAGrC,IACE,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,eAC1B,OAAO,SAASA,yBAAU,UAC1B,OAAO,SAASA,yBAAU,WAC1B;GACA,UAAU,OAAO;GACjB,eAAe,aAAa,OAAO,MAAM,OAAO;;EAGlD,IACE,OAAO,SAASA,yBAAU,YAC1B,OAAO,SAASA,yBAAU,cAC1B,OAAO,SAASA,yBAAU,QAC1B,OAAO,SAASA,yBAAU,aAC1B,OAAO,SAASA,yBAAU,MAC1B;GACA,UAAU,OAAO;GACjB,eAAe,aAAa,OAAO;;;CAKvC,IAAI,eAAe,YAAY,MAC7B,IAAI,MAAM,QAAQ,YAAY,EAC5B,YAAY,WAAqB;MAC5B;EACL,MAAM,iBAAsB,EAAE;EAC9B,KAAK,MAAM,OAAO,OAAO,KAAK,YAAY,EACxC,IAAI,QAAQ,WAAW,OAAO,WAAW,aACvC,eAAe,UAAU;OAEzB,eAAe,OAAO,YAAY;EAItC,OAAO,KAAK,YAAY,CAAC,SAAS,QAAQ;GACxC,OAAO,YAAY;IACnB;EACF,OAAO,OAAO,aAAa,eAAe;;CAI9C,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateNodeChildren.cjs","names":["NodeTypes"],"sources":["../../../src/dictionaryManipulator/updateNodeChildren.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const updateNodeChildren = <\n T extends ContentNode,\n U extends ContentNode,\n>(\n section: T,\n newChildren: U\n): ContentNode => {\n if (typeof section === 'string') {\n return newChildren;\n }\n if (typeof section === 'number') {\n return newChildren;\n }\n if (typeof section === 'boolean') {\n return newChildren;\n }\n if (typeof (section as TypedNode)?.nodeType === 'string') {\n const typedNode = section as TypedNode;\n const content =\n typedNode[typedNode.nodeType as unknown as keyof typeof typedNode];\n\n if (\n typedNode.nodeType === NodeTypes.TRANSLATION ||\n typedNode.nodeType === NodeTypes.ENUMERATION ||\n typedNode.nodeType === NodeTypes.PLURAL ||\n typedNode.nodeType === NodeTypes.CONDITION\n ) {\n const newContent = Object.entries(content).reduce(\n (acc, [key]) => {\n acc[key] = newChildren;\n return acc;\n },\n {} as Record<string, ContentNode>\n );\n\n return {\n ...typedNode,\n [typedNode.nodeType]: newContent,\n };\n }\n\n if (typedNode.nodeType === NodeTypes.NESTED) {\n return typedNode;\n }\n\n return {\n ...typedNode,\n [typedNode.nodeType]: newChildren,\n };\n }\n\n if (!section || typeof section !== 'object') {\n return newChildren;\n }\n\n if (Array.isArray(section)) {\n return section.map(() => newChildren) as unknown as ContentNode;\n }\n\n return Object.entries(\n section as unknown as Record<string, ContentNode>\n ).reduce(\n (acc, [key]) => ({\n ...acc,\n [key]: newChildren,\n }),\n {} as Record<string, ContentNode>\n ) as unknown as ContentNode;\n};\n"],"mappings":";;;;;;AAIA,MAAa,sBAIX,SACA,gBACgB;
|
|
1
|
+
{"version":3,"file":"updateNodeChildren.cjs","names":["NodeTypes"],"sources":["../../../src/dictionaryManipulator/updateNodeChildren.ts"],"sourcesContent":["import type { ContentNode, TypedNode } from '@intlayer/types/dictionary';\n\nimport * as NodeTypes from '@intlayer/types/nodeType';\n\nexport const updateNodeChildren = <\n T extends ContentNode,\n U extends ContentNode,\n>(\n section: T,\n newChildren: U\n): ContentNode => {\n if (typeof section === 'string') {\n return newChildren;\n }\n if (typeof section === 'number') {\n return newChildren;\n }\n if (typeof section === 'boolean') {\n return newChildren;\n }\n if (typeof (section as TypedNode)?.nodeType === 'string') {\n const typedNode = section as TypedNode;\n const content =\n typedNode[typedNode.nodeType as unknown as keyof typeof typedNode];\n\n if (\n typedNode.nodeType === NodeTypes.TRANSLATION ||\n typedNode.nodeType === NodeTypes.ENUMERATION ||\n typedNode.nodeType === NodeTypes.PLURAL ||\n typedNode.nodeType === NodeTypes.CONDITION\n ) {\n const newContent = Object.entries(content).reduce(\n (acc, [key]) => {\n acc[key] = newChildren;\n return acc;\n },\n {} as Record<string, ContentNode>\n );\n\n return {\n ...typedNode,\n [typedNode.nodeType]: newContent,\n };\n }\n\n if (typedNode.nodeType === NodeTypes.NESTED) {\n return typedNode;\n }\n\n return {\n ...typedNode,\n [typedNode.nodeType]: newChildren,\n };\n }\n\n if (!section || typeof section !== 'object') {\n return newChildren;\n }\n\n if (Array.isArray(section)) {\n return section.map(() => newChildren) as unknown as ContentNode;\n }\n\n return Object.entries(\n section as unknown as Record<string, ContentNode>\n ).reduce(\n (acc, [key]) => ({\n ...acc,\n [key]: newChildren,\n }),\n {} as Record<string, ContentNode>\n ) as unknown as ContentNode;\n};\n"],"mappings":";;;;;;AAIA,MAAa,sBAIX,SACA,gBACgB;CAChB,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,UACrB,OAAO;CAET,IAAI,OAAO,YAAY,WACrB,OAAO;CAET,IAAI,OAAQ,SAAuB,aAAa,UAAU;EACxD,MAAM,YAAY;EAClB,MAAM,UACJ,UAAU,UAAU;EAEtB,IACE,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,eACjC,UAAU,aAAaA,yBAAU,UACjC,UAAU,aAAaA,yBAAU,WACjC;GACA,MAAM,aAAa,OAAO,QAAQ,QAAQ,CAAC,QACxC,KAAK,CAAC,SAAS;IACd,IAAI,OAAO;IACX,OAAO;MAET,EAAE,CACH;GAED,OAAO;IACL,GAAG;KACF,UAAU,WAAW;IACvB;;EAGH,IAAI,UAAU,aAAaA,yBAAU,QACnC,OAAO;EAGT,OAAO;GACL,GAAG;IACF,UAAU,WAAW;GACvB;;CAGH,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,IAAI,MAAM,QAAQ,QAAQ,EACxB,OAAO,QAAQ,UAAU,YAAY;CAGvC,OAAO,OAAO,QACZ,QACD,CAAC,QACC,KAAK,CAAC,UAAU;EACf,GAAG;GACF,MAAM;EACR,GACD,EAAE,CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date.cjs","names":["internationalization","getCachedIntl"],"sources":["../../../src/formatters/date.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\nexport type DateTimePreset =\n | 'short'\n | 'long'\n | 'dateOnly'\n | 'timeOnly'\n | 'full';\n\nexport const presets: Record<DateTimePreset, Intl.DateTimeFormatOptions> = {\n short: {\n year: '2-digit',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n },\n long: {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n },\n full: {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n hour12: false,\n },\n dateOnly: {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n },\n timeOnly: {\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n },\n};\n\n/**\n * Formats a date/time value into a localized string using Intl.DateTimeFormat.\n *\n * @example\n * date(new Date('2025-08-02T14:30:00Z'), { year: '2-digit', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });\n * // \"08/02/25, 14:30\"\n *\n * @example\n * date(\"2025-08-02T14:30:00Z\", { locale: Locales.FRENCH, month: \"long\", day: \"numeric\" });\n * // \"2 août\"\n */\nexport const date = (\n date: Date | string | number,\n options?:\n | (Intl.DateTimeFormatOptions & { locale?: LocalesValues })\n | DateTimePreset\n): string => {\n const dateTime = new Date(date);\n\n const resolvedOptions =\n typeof options === 'string' ? (presets[options] ?? {}) : options;\n\n const locale =\n (typeof options === 'object' ? options?.locale : undefined) ??\n internationalization?.defaultLocale;\n\n const formatter = getCachedIntl(Intl.DateTimeFormat, locale, resolvedOptions);\n\n return formatter.format(dateTime);\n};\n"],"mappings":";;;;;;AAWA,MAAa,UAA8D;CACzE,OAAO;EACL,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT;CACD,MAAM;EACJ,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT;CACD,MAAM;EACJ,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACR,QAAQ;EACT;CACD,UAAU;EACR,MAAM;EACN,OAAO;EACP,KAAK;EACN;CACD,UAAU;EACR,MAAM;EACN,QAAQ;EACR,QAAQ;EACT;CACF;;;;;;;;;;;;AAaD,MAAa,QACX,MACA,YAGW;CACX,MAAM,WAAW,IAAI,KAAK,KAAK;CAE/B,MAAM,kBACJ,OAAO,YAAY,WAAY,QAAQ,YAAY,EAAE,GAAI;CAE3D,MAAM,UACH,OAAO,YAAY,WAAW,SAAS,SAAS,WACjDA,6CAAsB;
|
|
1
|
+
{"version":3,"file":"date.cjs","names":["internationalization","getCachedIntl"],"sources":["../../../src/formatters/date.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\nexport type DateTimePreset =\n | 'short'\n | 'long'\n | 'dateOnly'\n | 'timeOnly'\n | 'full';\n\nexport const presets: Record<DateTimePreset, Intl.DateTimeFormatOptions> = {\n short: {\n year: '2-digit',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n },\n long: {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n },\n full: {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n hour12: false,\n },\n dateOnly: {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n },\n timeOnly: {\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n },\n};\n\n/**\n * Formats a date/time value into a localized string using Intl.DateTimeFormat.\n *\n * @example\n * date(new Date('2025-08-02T14:30:00Z'), { year: '2-digit', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });\n * // \"08/02/25, 14:30\"\n *\n * @example\n * date(\"2025-08-02T14:30:00Z\", { locale: Locales.FRENCH, month: \"long\", day: \"numeric\" });\n * // \"2 août\"\n */\nexport const date = (\n date: Date | string | number,\n options?:\n | (Intl.DateTimeFormatOptions & { locale?: LocalesValues })\n | DateTimePreset\n): string => {\n const dateTime = new Date(date);\n\n const resolvedOptions =\n typeof options === 'string' ? (presets[options] ?? {}) : options;\n\n const locale =\n (typeof options === 'object' ? options?.locale : undefined) ??\n internationalization?.defaultLocale;\n\n const formatter = getCachedIntl(Intl.DateTimeFormat, locale, resolvedOptions);\n\n return formatter.format(dateTime);\n};\n"],"mappings":";;;;;;AAWA,MAAa,UAA8D;CACzE,OAAO;EACL,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT;CACD,MAAM;EACJ,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT;CACD,MAAM;EACJ,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACR,QAAQ;EACT;CACD,UAAU;EACR,MAAM;EACN,OAAO;EACP,KAAK;EACN;CACD,UAAU;EACR,MAAM;EACN,QAAQ;EACR,QAAQ;EACT;CACF;;;;;;;;;;;;AAaD,MAAa,QACX,MACA,YAGW;CACX,MAAM,WAAW,IAAI,KAAK,KAAK;CAE/B,MAAM,kBACJ,OAAO,YAAY,WAAY,QAAQ,YAAY,EAAE,GAAI;CAE3D,MAAM,UACH,OAAO,YAAY,WAAW,SAAS,SAAS,WACjDA,6CAAsB;CAIxB,OAFkBC,iCAAc,KAAK,gBAAgB,QAAQ,gBAE7C,CAAC,OAAO,SAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"percentage.cjs","names":["getCachedIntl","internationalization"],"sources":["../../../src/formatters/percentage.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\n/**\n * Formats a number as a percentage string (e.g., 0.25 → \"25%\").\n *\n * @example\n * percentage(0.25); // \"25%\"\n *\n * @example\n * percentage(0.25, { minimumFractionDigits: 2 }); // \"25.00%\"\n */\nexport const percentage = (\n value: string | number,\n {\n locale,\n ...options\n }: Intl.NumberFormatOptions & { locale?: LocalesValues } = {}\n): string => {\n let numericValue = Number(value);\n\n // Normalize: if user passes 10, treat it as 10% instead of 1000%\n if (numericValue > 1) {\n numericValue /= 100;\n }\n\n const formatter = getCachedIntl(\n Intl.NumberFormat,\n locale ?? internationalization?.defaultLocale,\n\n {\n style: 'percent',\n ...options,\n }\n );\n\n return formatter.format(Number(numericValue));\n};\n"],"mappings":";;;;;;;;;;;;;;;AAaA,MAAa,cACX,OACA,EACE,QACA,GAAG,YACsD,EAAE,KAClD;CACX,IAAI,eAAe,OAAO,MAAM;
|
|
1
|
+
{"version":3,"file":"percentage.cjs","names":["getCachedIntl","internationalization"],"sources":["../../../src/formatters/percentage.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\n/**\n * Formats a number as a percentage string (e.g., 0.25 → \"25%\").\n *\n * @example\n * percentage(0.25); // \"25%\"\n *\n * @example\n * percentage(0.25, { minimumFractionDigits: 2 }); // \"25.00%\"\n */\nexport const percentage = (\n value: string | number,\n {\n locale,\n ...options\n }: Intl.NumberFormatOptions & { locale?: LocalesValues } = {}\n): string => {\n let numericValue = Number(value);\n\n // Normalize: if user passes 10, treat it as 10% instead of 1000%\n if (numericValue > 1) {\n numericValue /= 100;\n }\n\n const formatter = getCachedIntl(\n Intl.NumberFormat,\n locale ?? internationalization?.defaultLocale,\n\n {\n style: 'percent',\n ...options,\n }\n );\n\n return formatter.format(Number(numericValue));\n};\n"],"mappings":";;;;;;;;;;;;;;;AAaA,MAAa,cACX,OACA,EACE,QACA,GAAG,YACsD,EAAE,KAClD;CACX,IAAI,eAAe,OAAO,MAAM;CAGhC,IAAI,eAAe,GACjB,gBAAgB;CAalB,OAVkBA,iCAChB,KAAK,cACL,UAAUC,6CAAsB,eAEhC;EACE,OAAO;EACP,GAAG;EACJ,CAGa,CAAC,OAAO,OAAO,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relativeTime.cjs","names":["getCachedIntl","internationalization"],"sources":["../../../src/formatters/relativeTime.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\ntype RelativeTimeUnit = Intl.RelativeTimeFormatUnit;\n\n/**\n * Calculate the difference between 2 dates in the given unit.\n */\nconst diffInUnit = (from: Date, to: Date, unit: RelativeTimeUnit): number => {\n const msDiff = to.getTime() - from.getTime();\n const sec = msDiff / 1000;\n\n switch (unit) {\n case 'second':\n return sec;\n case 'minute':\n return sec / 60;\n case 'hour':\n return sec / 3600;\n case 'day':\n return sec / 86400;\n case 'month':\n return sec / (30 * 86400); // approx\n case 'quarter':\n return sec / (3 * 30 * 86400); // 3 months approx\n case 'year':\n return sec / (365 * 86400); // approx\n default:\n return sec;\n }\n};\n\n/**\n * Formats the difference between two dates as a localized relative time string.\n *\n * @example\n * relativeTime(new Date(Date.now() - 30000)); // \"30 seconds ago\"\n *\n * @example\n * relativeTime(\"2025-01-01\", new Date(), { locale: Locales.FRENCH, unit: \"day\" });\n * // \"il y a 443 jours\"\n */\nexport const relativeTime = (\n from: Date | string | number,\n to: Date | string | number = new Date(),\n options?: Intl.RelativeTimeFormatOptions & {\n locale?: LocalesValues;\n unit?: RelativeTimeUnit;\n }\n): string => {\n const fromDate = new Date(from);\n const toDate = new Date(to);\n const unit = options?.unit ?? 'second';\n\n const value = diffInUnit(fromDate, toDate, unit);\n\n return getCachedIntl(\n Intl.RelativeTimeFormat,\n options?.locale ?? internationalization?.defaultLocale,\n\n options\n ).format(Math.round(value), unit);\n};\n"],"mappings":";;;;;;;;;AASA,MAAM,cAAc,MAAY,IAAU,SAAmC;CAE3E,MAAM,OADS,GAAG,SAAS,GAAG,KAAK,SAAS,IACvB;
|
|
1
|
+
{"version":3,"file":"relativeTime.cjs","names":["getCachedIntl","internationalization"],"sources":["../../../src/formatters/relativeTime.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedIntl } from '../utils/intl';\n\ntype RelativeTimeUnit = Intl.RelativeTimeFormatUnit;\n\n/**\n * Calculate the difference between 2 dates in the given unit.\n */\nconst diffInUnit = (from: Date, to: Date, unit: RelativeTimeUnit): number => {\n const msDiff = to.getTime() - from.getTime();\n const sec = msDiff / 1000;\n\n switch (unit) {\n case 'second':\n return sec;\n case 'minute':\n return sec / 60;\n case 'hour':\n return sec / 3600;\n case 'day':\n return sec / 86400;\n case 'month':\n return sec / (30 * 86400); // approx\n case 'quarter':\n return sec / (3 * 30 * 86400); // 3 months approx\n case 'year':\n return sec / (365 * 86400); // approx\n default:\n return sec;\n }\n};\n\n/**\n * Formats the difference between two dates as a localized relative time string.\n *\n * @example\n * relativeTime(new Date(Date.now() - 30000)); // \"30 seconds ago\"\n *\n * @example\n * relativeTime(\"2025-01-01\", new Date(), { locale: Locales.FRENCH, unit: \"day\" });\n * // \"il y a 443 jours\"\n */\nexport const relativeTime = (\n from: Date | string | number,\n to: Date | string | number = new Date(),\n options?: Intl.RelativeTimeFormatOptions & {\n locale?: LocalesValues;\n unit?: RelativeTimeUnit;\n }\n): string => {\n const fromDate = new Date(from);\n const toDate = new Date(to);\n const unit = options?.unit ?? 'second';\n\n const value = diffInUnit(fromDate, toDate, unit);\n\n return getCachedIntl(\n Intl.RelativeTimeFormat,\n options?.locale ?? internationalization?.defaultLocale,\n\n options\n ).format(Math.round(value), unit);\n};\n"],"mappings":";;;;;;;;;AASA,MAAM,cAAc,MAAY,IAAU,SAAmC;CAE3E,MAAM,OADS,GAAG,SAAS,GAAG,KAAK,SAAS,IACvB;CAErB,QAAQ,MAAR;EACE,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO,MAAM;EACf,KAAK,QACH,OAAO,MAAM;EACf,KAAK,OACH,OAAO,MAAM;EACf,KAAK,SACH,OAAO,OAAO,KAAK;EACrB,KAAK,WACH,OAAO,OAAO,KAAS;EACzB,KAAK,QACH,OAAO,OAAO,MAAM;EACtB,SACE,OAAO;;;;;;;;;;;;;AAcb,MAAa,gBACX,MACA,qBAA6B,IAAI,MAAM,EACvC,YAIW;CACX,MAAM,WAAW,IAAI,KAAK,KAAK;CAC/B,MAAM,SAAS,IAAI,KAAK,GAAG;CAC3B,MAAM,OAAO,SAAS,QAAQ;CAE9B,MAAM,QAAQ,WAAW,UAAU,QAAQ,KAAK;CAEhD,OAAOA,iCACL,KAAK,oBACL,SAAS,UAAUC,6CAAsB,eAEzC,QACD,CAAC,OAAO,KAAK,MAAM,MAAM,EAAE,KAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getCondition.cjs","names":[],"sources":["../../../src/interpreter/getCondition.ts"],"sourcesContent":["import type { ConditionContentStates } from '../transpiler';\n\n/**\n * Picks content based on a boolean condition.\n *\n * @param conditionContent - A map with 'true', 'false', and optionally 'fallback' keys.\n * @param state - The boolean state to match.\n * @returns The matching content.\n *\n * @example\n * ```ts\n * const content = getCondition({\n * 'true': 'The condition is validated',\n * 'false': 'The condition is not validated',\n * }, true);\n * // 'The condition is validated'\n * ```\n */\nexport const getCondition = <Content>(\n conditionContent: ConditionContentStates<Content>,\n state?: boolean\n): Content => {\n const stateList = Object.keys(conditionContent);\n const fallbackState = stateList[\n stateList.length - 1\n ] as keyof typeof conditionContent;\n\n // Default or error handling if no keys match\n return (\n conditionContent[`${state}` as keyof typeof conditionContent] ??\n conditionContent.fallback ??\n (conditionContent[fallbackState] as Content)\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,MAAa,gBACX,kBACA,UACY;CACZ,MAAM,YAAY,OAAO,KAAK,iBAAiB;CAC/C,MAAM,gBAAgB,UACpB,UAAU,SAAS;
|
|
1
|
+
{"version":3,"file":"getCondition.cjs","names":[],"sources":["../../../src/interpreter/getCondition.ts"],"sourcesContent":["import type { ConditionContentStates } from '../transpiler';\n\n/**\n * Picks content based on a boolean condition.\n *\n * @param conditionContent - A map with 'true', 'false', and optionally 'fallback' keys.\n * @param state - The boolean state to match.\n * @returns The matching content.\n *\n * @example\n * ```ts\n * const content = getCondition({\n * 'true': 'The condition is validated',\n * 'false': 'The condition is not validated',\n * }, true);\n * // 'The condition is validated'\n * ```\n */\nexport const getCondition = <Content>(\n conditionContent: ConditionContentStates<Content>,\n state?: boolean\n): Content => {\n const stateList = Object.keys(conditionContent);\n const fallbackState = stateList[\n stateList.length - 1\n ] as keyof typeof conditionContent;\n\n // Default or error handling if no keys match\n return (\n conditionContent[`${state}` as keyof typeof conditionContent] ??\n conditionContent.fallback ??\n (conditionContent[fallbackState] as Content)\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,MAAa,gBACX,kBACA,UACY;CACZ,MAAM,YAAY,OAAO,KAAK,iBAAiB;CAC/C,MAAM,gBAAgB,UACpB,UAAU,SAAS;CAIrB,OACE,iBAAiB,GAAG,YACpB,iBAAiB,YAChB,iBAAiB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deepTransform.cjs","names":["NodeTypes"],"sources":["../../../../src/interpreter/getContent/deepTransform.ts"],"sourcesContent":["import type { KeyPath } from '@intlayer/types/keyPath';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport type { NodeProps } from './plugins';\n\n/**\n * Recursively traverses a node (object/array/primitive).\n * Applies the *first* plugin that can transform a node, then stops descending further.\n * If no plugin transforms it, it recurses into its children.\n */\nexport const deepTransformNode = (node: any, props: NodeProps): any => {\n // Otherwise, if it's an object, check if any plugin can handle it:\n for (const plugin of props.plugins ?? []) {\n if (plugin.canHandle(node)) {\n // Return the transformed node => do NOT recurse further\n return plugin.transform(node, props, (node: any, props: any) =>\n deepTransformNode(node, props)\n );\n }\n }\n\n // If it's null/undefined or not an object, just return it directly:\n if (node === null || typeof node !== 'object') {\n return node;\n }\n\n // If it's a framework-specific virtual node or already a transformed Proxy,\n // return it directly to avoid re-transforming its internal properties.\n if (\n (node as any).$$typeof !== undefined ||\n (node as any).__v_isVNode !== undefined ||\n (node as any)._isVNode !== undefined ||\n (node as any).isJSX !== undefined ||\n typeof node === 'function' // Proxies for html/markdown are functions\n ) {\n return node;\n }\n\n // If it's an array, transform each element:\n if (Array.isArray(node)) {\n return node.map((child, index) => {\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ARRAY, key: index } as KeyPath,\n ],\n };\n return deepTransformNode(child, childProps);\n });\n }\n\n // If no plugin transforms it, we keep traversing its properties.\n const result: Record<string, any> = {};\n for (const key in node) {\n const childProps = {\n ...props,\n children: node[key],\n keyPath: [...props.keyPath, { type: NodeTypes.OBJECT, key } as KeyPath],\n };\n\n if (props.eager) {\n // Eager mode: recurse immediately so plugins fire on every node, even\n // when the caller discards the returned tree (e.g. side-effect-only\n // plugins like missing-locale detection).\n result[key] = deepTransformNode(node[key], childProps);\n continue;\n }\n\n Object.defineProperty(result, key, {\n enumerable: true,\n configurable: true,\n get: function () {\n const transformed = deepTransformNode(node[key], childProps);\n\n // Memoize the result onto the property to avoid re-calculating on next read\n Object.defineProperty(this, key, {\n value: transformed,\n enumerable: true,\n configurable: true,\n });\n return transformed;\n },\n });\n }\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;AASA,MAAa,qBAAqB,MAAW,UAA0B;
|
|
1
|
+
{"version":3,"file":"deepTransform.cjs","names":["NodeTypes"],"sources":["../../../../src/interpreter/getContent/deepTransform.ts"],"sourcesContent":["import type { KeyPath } from '@intlayer/types/keyPath';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport type { NodeProps } from './plugins';\n\n/**\n * Recursively traverses a node (object/array/primitive).\n * Applies the *first* plugin that can transform a node, then stops descending further.\n * If no plugin transforms it, it recurses into its children.\n */\nexport const deepTransformNode = (node: any, props: NodeProps): any => {\n // Otherwise, if it's an object, check if any plugin can handle it:\n for (const plugin of props.plugins ?? []) {\n if (plugin.canHandle(node)) {\n // Return the transformed node => do NOT recurse further\n return plugin.transform(node, props, (node: any, props: any) =>\n deepTransformNode(node, props)\n );\n }\n }\n\n // If it's null/undefined or not an object, just return it directly:\n if (node === null || typeof node !== 'object') {\n return node;\n }\n\n // If it's a framework-specific virtual node or already a transformed Proxy,\n // return it directly to avoid re-transforming its internal properties.\n if (\n (node as any).$$typeof !== undefined ||\n (node as any).__v_isVNode !== undefined ||\n (node as any)._isVNode !== undefined ||\n (node as any).isJSX !== undefined ||\n typeof node === 'function' // Proxies for html/markdown are functions\n ) {\n return node;\n }\n\n // If it's an array, transform each element:\n if (Array.isArray(node)) {\n return node.map((child, index) => {\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ARRAY, key: index } as KeyPath,\n ],\n };\n return deepTransformNode(child, childProps);\n });\n }\n\n // If no plugin transforms it, we keep traversing its properties.\n const result: Record<string, any> = {};\n for (const key in node) {\n const childProps = {\n ...props,\n children: node[key],\n keyPath: [...props.keyPath, { type: NodeTypes.OBJECT, key } as KeyPath],\n };\n\n if (props.eager) {\n // Eager mode: recurse immediately so plugins fire on every node, even\n // when the caller discards the returned tree (e.g. side-effect-only\n // plugins like missing-locale detection).\n result[key] = deepTransformNode(node[key], childProps);\n continue;\n }\n\n Object.defineProperty(result, key, {\n enumerable: true,\n configurable: true,\n get: function () {\n const transformed = deepTransformNode(node[key], childProps);\n\n // Memoize the result onto the property to avoid re-calculating on next read\n Object.defineProperty(this, key, {\n value: transformed,\n enumerable: true,\n configurable: true,\n });\n return transformed;\n },\n });\n }\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;AASA,MAAa,qBAAqB,MAAW,UAA0B;CAErE,KAAK,MAAM,UAAU,MAAM,WAAW,EAAE,EACtC,IAAI,OAAO,UAAU,KAAK,EAExB,OAAO,OAAO,UAAU,MAAM,QAAQ,MAAW,UAC/C,kBAAkB,MAAM,MAAM,CAC/B;CAKL,IAAI,SAAS,QAAQ,OAAO,SAAS,UACnC,OAAO;CAKT,IACG,KAAa,aAAa,UAC1B,KAAa,gBAAgB,UAC7B,KAAa,aAAa,UAC1B,KAAa,UAAU,UACxB,OAAO,SAAS,YAEhB,OAAO;CAIT,IAAI,MAAM,QAAQ,KAAK,EACrB,OAAO,KAAK,KAAK,OAAO,UAAU;EAShC,OAAO,kBAAkB,OAAO;GAP9B,GAAG;GACH,UAAU;GACV,SAAS,CACP,GAAG,MAAM,SACT;IAAE,MAAMA,yBAAU;IAAO,KAAK;IAAO,CACtC;GAEuC,CAAC;GAC3C;CAIJ,MAAM,SAA8B,EAAE;CACtC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,aAAa;GACjB,GAAG;GACH,UAAU,KAAK;GACf,SAAS,CAAC,GAAG,MAAM,SAAS;IAAE,MAAMA,yBAAU;IAAQ;IAAK,CAAY;GACxE;EAED,IAAI,MAAM,OAAO;GAIf,OAAO,OAAO,kBAAkB,KAAK,MAAM,WAAW;GACtD;;EAGF,OAAO,eAAe,QAAQ,KAAK;GACjC,YAAY;GACZ,cAAc;GACd,KAAK,WAAY;IACf,MAAM,cAAc,kBAAkB,KAAK,MAAM,WAAW;IAG5D,OAAO,eAAe,MAAM,KAAK;KAC/B,OAAO;KACP,YAAY;KACZ,cAAc;KACf,CAAC;IACF,OAAO;;GAEV,CAAC;;CAGJ,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.cjs","names":["NodeTypes","getTranslation","getEnumeration","getInsertion","getPlural","getCondition","getGender","getNesting"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport type {\n ConditionContent,\n EnumerationContent,\n FileContent,\n Gender,\n GenderContent,\n InsertionContent,\n NestedContent,\n PluralContent,\n TranslationContent,\n} from '../../transpiler';\nimport { getCondition } from '../getCondition';\nimport { getEnumeration } from '../getEnumeration';\nimport { getGender } from '../getGender';\nimport { getInsertion } from '../getInsertion';\nimport { type GetNestingResult, getNesting } from '../getNesting';\nimport { getPlural } from '../getPlural';\nimport { getTranslation } from '../getTranslation';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\n/** ---------------------------------------------\n * PLUGIN DEFINITION\n * --------------------------------------------- */\n\n/**\n * A plugin/transformer that can optionally transform a node during a single DFS pass.\n * - `canHandle` decides if the node is transformable by this plugin.\n * - `transform` returns the transformed node (and does not recurse further).\n *\n * > `transformFn` is a function that can be used to deeply transform inside the plugin.\n */\nexport type Plugins = {\n id: string;\n canHandle: (node: any) => boolean;\n transform: (\n node: any,\n props: NodeProps,\n transformFn: (node: any, props: NodeProps) => any\n ) => any;\n};\n\n/** ---------------------------------------------\n * FALLBACK PLUGIN\n *\n * Used to fallback a tree-shaken plugin\n * --------------------------------------------- */\n\nexport const fallbackPlugin: Plugins = {\n id: 'fallback-plugin',\n canHandle: () => false,\n transform: (node) => node,\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type UnionKeys<T> = T extends unknown ? keyof T : never;\nexport type ValueAtKey<T, K> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.TRANSLATION]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? U[keyof U] extends Record<PropertyKey, unknown>\n ? {\n [K in UnionKeys<U[keyof U]>]: L extends keyof U\n ? K extends keyof U[L]\n ? U[L][K]\n : ValueAtKey<U[keyof U], K>\n : ValueAtKey<U[keyof U], K>;\n } extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : (L extends keyof U ? U[L] : U[keyof U]) extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins =>\n process.env['INTLAYER_NODE_TYPE_TRANSLATION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.TRANSLATION,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.TRANSLATION] ?? {};\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const childProps = {\n ...props,\n children: original[key as keyof typeof original],\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.TRANSLATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(\n original[key as keyof typeof original],\n childProps\n );\n }\n\n return getTranslation(result, locale, fallback);\n },\n };\n\n/** ---------------------------------------------\n * ENUMERATION PLUGIN\n * --------------------------------------------- */\n\nexport type EnumerationCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.ENUMERATION]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[typeof NodeTypes.ENUMERATION][keyof T[typeof NodeTypes.ENUMERATION]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_ENUMERATION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.ENUMERATION,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.ENUMERATION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as unknown as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ENUMERATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: number | { count: number }) => {\n const quantity = typeof arg === 'number' ? arg : arg.count;\n const subResult = getEnumeration(result, quantity);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * PLURAL PLUGIN\n * --------------------------------------------- */\n\nexport type PluralCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.PLURAL]: object;\n}\n ? (\n arg: number | { count: number; [key: string]: unknown }\n ) => DeepTransformContent<\n T[typeof NodeTypes.PLURAL][keyof T[typeof NodeTypes.PLURAL]],\n S\n >\n : never;\n\n/**\n * Plural plugin. Replaces node with a function that takes a count (or\n * `{ count, ...values }`) => string, picking the matching CLDR plural form\n * for the active locale and interpolating `{{count}}` (and other values).\n */\nexport const pluralPlugin = (locale?: LocalesValues): Plugins =>\n process.env['INTLAYER_NODE_TYPE_PLURAL'] === 'false'\n ? fallbackPlugin\n : {\n id: 'plural-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.PLURAL,\n transform: (node: PluralContent, props, deepTransformNode) => {\n const original = node[NodeTypes.PLURAL];\n const result: Record<string, any> = {};\n\n /** String plugin for plural. Replaces string node with a component that renders the insertion. */\n const pluralStringPlugin: Plugins = {\n id: 'plural-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (values: { [k: string]: string | number }) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.PLURAL, key } as KeyPath,\n ],\n plugins: [pluralStringPlugin, ...(props.plugins ?? [])],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n const effectiveLocale = String(locale ?? props.locale ?? 'en');\n\n return (arg: number | { count: number; [key: string]: unknown }) => {\n const count = typeof arg === 'number' ? arg : arg.count;\n const values =\n typeof arg === 'object'\n ? arg\n : ({ count } as Record<string, unknown>);\n\n const subResult = getPlural(\n result as PluralContent['plural'],\n count,\n effectiveLocale\n );\n\n if (typeof subResult === 'function') {\n return subResult(values);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.CONDITION]: object;\n}\n ? (\n value: boolean | { value: boolean }\n ) => DeepTransformContent<\n T[typeof NodeTypes.CONDITION][keyof T[typeof NodeTypes.CONDITION]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_CONDITION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.CONDITION,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const original = node[NodeTypes.CONDITION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.CONDITION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: boolean | { value: boolean }) => {\n const value = typeof arg === 'boolean' ? arg : arg.value;\n const subResult = getCondition(result as any, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? (\n values: {\n [K in T['fields'][number]]: string | number;\n }\n ) => I extends string\n ? DeepTransformContent<string, S>\n : DeepTransformContent<I, S>\n : never;\n\n/** Insertion plugin. Replaces node with a function that takes quantity => string. */\nexport const insertionPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_INSERTION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.INSERTION];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n };\n\n/** ---------------------------------------------\n * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.GENDER]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<\n T[typeof NodeTypes.GENDER][keyof T[typeof NodeTypes.GENDER]],\n S\n >\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_GENDER'] === 'false'\n ? fallbackPlugin\n : {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.GENDER,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const original = node[NodeTypes.GENDER];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.GENDER, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (value: Gender) => getGender(result as any, value);\n },\n };\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.NESTED]: infer U;\n}\n ? U extends {\n dictionaryKey: infer K extends DictionaryKeys;\n path?: infer P;\n }\n ? GetNestingResult<K, P, S>\n : never\n : never;\n\n/** Nested plugin. Replaces node with the result of `getNesting`. */\nexport const nestedPlugin = (locale?: LocalesValues): Plugins =>\n process.env['INTLAYER_NODE_TYPE_NESTED'] === 'false'\n ? fallbackPlugin\n : {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n (node?.nodeType === NodeTypes.NESTED || node?.nodeType === 'n'),\n transform: (node: NestedContent, props) =>\n getNesting(\n node[NodeTypes.NESTED].dictionaryKey,\n node[NodeTypes.NESTED].path,\n {\n ...props,\n locale: (locale ?? props.locale) as Locale,\n }\n ),\n };\n\n/** ---------------------------------------------\n * FILE PLUGIN\n * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.FILE]: string;\n content?: string;\n}\n ? string\n : never;\n\n/** File plugin. Replaces node with the result of `getNesting`. */\nexport const filePlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_FILE'] === 'false'\n ? fallbackPlugin\n : {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.FILE,\n transform: (node: FileContent, props, deepTransform) =>\n deepTransform(node.content, {\n ...props,\n children: node.content,\n }),\n };\n\n/**\n * PLUGIN RESULT\n */\n\n/**\n * Interface that defines the properties of a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface NodeProps {\n dictionaryKey: string;\n keyPath: KeyPath[];\n plugins?: Plugins[];\n locale?: Locale;\n dictionaryPath?: string;\n children?: any;\n /**\n * Forces eager traversal of plain objects in `deepTransformNode`. By default\n * traversal is lazy (property getters), so callers that discard the returned\n * value never trigger plugins on nested nodes. Set this when running plugins\n * for their side effects only (e.g. missing-locale detection).\n */\n eager?: boolean;\n}\n\n/**\n * Interface that defines the plugins that can be used to transform a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface IInterpreterPlugin<T, S, L extends LocalesValues> {\n translation: TranslationCond<T, S, L>;\n enumeration: EnumerationCond<T, S, L>;\n plural: PluralCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n gender: GenderCond<T, S, L>;\n nested: NestedCond<T, S, L>;\n file: FileCond<T>;\n}\n\n/**\n * Allow to avoid overwriting import from `intlayer` package when `IInterpreterPlugin<T>` interface is augmented in another package, such as `react-intlayer`.\n */\nexport type IInterpreterPluginState = {\n translation: true;\n enumeration: true;\n plural: true;\n condition: true;\n insertion: true;\n gender: true;\n nested: true;\n file: true;\n};\n\n/**\n * Utility type to check if a plugin can be applied to a node.\n */\ntype CheckApplyPlugin<\n T,\n K extends keyof IInterpreterPlugin<T, S, L>,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = K extends keyof S // Test if the key is a key of S.\n ? // Test if the key of S is true. Then the plugin can be applied.\n S[K] extends true\n ? // Test if the key of S exist\n IInterpreterPlugin<T, S, L>[K] extends never\n ? never\n : // Test if the plugin condition is true (if it's not, the plugin is skipped for this node)\n IInterpreterPlugin<T, S, L>[K]\n : never\n : never;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\ntype Traverse<T, S, L extends LocalesValues = DeclaredLocales> =\n T extends ReadonlyArray<infer U> // Turn any read-only array into a plain mutable array\n ? Array<DeepTransformContent<U, S, L>>\n : T extends object\n ? { [K in keyof T]: DeepTransformContent<T[K], S, L> }\n : T;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\nexport type DeepTransformContent<\n T,\n S = IInterpreterPluginState,\n L extends LocalesValues = DeclaredLocales,\n> =\n IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L> extends never // Check if there is a plugin for T:\n ? // No plugin was found, so try to transform T recursively:\n Traverse<T, S, L>\n : // A plugin was found – use the plugin's transformation.\n CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L>;\n"],"mappings":";;;;;;;;;;;;;;;;;;AA2DA,MAAa,iBAA0B;CACrC,IAAI;CACJ,iBAAiB;CACjB,YAAY,SAAS;CACtB;;AAmCD,MAAa,qBACX,QACA,aAEA,QAAQ,IAAI,sCAAsC,UAC9C,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaA,yBAAU;CAC3D,YAAY,MAA0B,OAAO,sBAAsB;EACjE,MAAM,WAAW,KAAKA,yBAAU,gBAAgB,EAAE;EAClD,MAAM,SAA8B,EAAE;AAEtC,OAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,aAAa;IACjB,GAAG;IACH,UAAU,SAAS;IACnB,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAa;KAAK,CACrC;IACF;AACD,UAAO,OAAO,kBACZ,SAAS,MACT,WACD;;AAGH,SAAOC,kDAAe,QAAQ,QAAQ,SAAS;;CAElD;;AAmBP,MAAa,oBACX,QAAQ,IAAI,sCAAsC,UAC9C,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaD,yBAAU;CAC3D,YAAY,MAA0B,OAAO,sBAAsB;EACjE,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,EAAE;AAEtC,OAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;AASvB,UAAO,OAAO,kBAAkB,OAAO;IAPrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAa;KAAK,CACrC;IAE8C,CAAC;;AAGpD,UAAQ,QAAoC;GAE1C,MAAM,YAAYE,kDAAe,QADhB,OAAO,QAAQ,WAAW,MAAM,IAAI,MACH;AAElD,OAAI,OAAO,cAAc,cAAc,OAAO,QAAQ,SACpD,QAAO,UAAU,IAAI;AAGvB,UAAO;;;CAGZ;;;;;;AAuBP,MAAa,gBAAgB,WAC3B,QAAQ,IAAI,iCAAiC,UACzC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaF,yBAAU;CAC3D,YAAY,MAAqB,OAAO,sBAAsB;EAC5D,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,EAAE;;EAGtC,MAAM,qBAA8B;GAClC,IAAI;GACJ,YAAY,SAAS,OAAO,SAAS;GACrC,YAAY,MAAc,UAAU,sBAAsB;IACxD,MAAM,oBAAoB,kBAAkB,MAAM;KAChD,GAAG;KACH,UAAU;KACV,SAAS,CACP,IAAI,MAAM,WAAY,EAAE,EAAgB,QACrC,WAAW,OAAO,OAAO,uBAC3B,CACF;KACF,CAAC;AAEF,YAAQ,WAA6C;KACnD,MAAM,WAAWG,8CAAa,mBAAmB,OAAO;AAExD,YAAO,kBAAkB,UAAU;MACjC,GAAG;MACH,SAAS,MAAM;MACf;MACD,CAAC;;;GAGP;AAED,OAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;AAUvB,UAAO,OAAO,kBAAkB,OAAO;IARrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMH,yBAAU;KAAQ;KAAK,CAChC;IACD,SAAS,CAAC,oBAAoB,GAAI,MAAM,WAAW,EAAE,CAAE;IAER,CAAC;;EAGpD,MAAM,kBAAkB,OAAO,UAAU,MAAM,UAAU,KAAK;AAE9D,UAAQ,QAA4D;GAClE,MAAM,QAAQ,OAAO,QAAQ,WAAW,MAAM,IAAI;GAClD,MAAM,SACJ,OAAO,QAAQ,WACX,MACC,EAAE,OAAO;GAEhB,MAAM,YAAYI,wCAChB,QACA,OACA,gBACD;AAED,OAAI,OAAO,cAAc,WACvB,QAAO,UAAU,OAAO;AAG1B,UAAO;;;CAGZ;;AAmBP,MAAa,kBACX,QAAQ,IAAI,oCAAoC,UAC5C,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaJ,yBAAU;CAC3D,YAAY,MAAwB,OAAO,sBAAsB;EAC/D,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,EAAE;AAEtC,OAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;AASvB,UAAO,OAAO,kBAAkB,OAAO;IAPrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAW;KAAK,CACnC;IAE8C,CAAC;;AAGpD,UAAQ,QAAsC;GAE5C,MAAM,YAAYK,8CAAa,QADjB,OAAO,QAAQ,YAAY,MAAM,IAAI,MACC;AAEpD,OAAI,OAAO,cAAc,cAAc,OAAO,QAAQ,SACpD,QAAO,UAAU,IAAI;AAGvB,UAAO;;;CAGZ;;AAqBP,MAAa,kBACX,QAAQ,IAAI,oCAAoC,UAC5C,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaL,yBAAU;CAC3D,YAAY,MAAwB,OAAO,sBAAsB;EAC/D,MAAM,aAAwB,CAC5B,GAAG,MAAM,SACT,EACE,MAAMA,yBAAU,WACjB,CACF;EAED,MAAM,WAAW,KAAKA,yBAAU;;EAGhC,MAAM,wBAAiC;GACrC,IAAI;GACJ,YAAY,SAAS,OAAO,SAAS;GACrC,YAAY,MAAc,UAAU,sBAAsB;IACxD,MAAM,oBAAoB,kBAAkB,MAAM;KAChD,GAAG;KACH,UAAU;KACV,SAAS,CACP,IAAI,MAAM,WAAY,EAAE,EAAgB,QACrC,WAAW,OAAO,OAAO,uBAC3B,CACF;KACF,CAAC;AAEF,YACE,WAGG;KACH,MAAM,WAAWG,8CAAa,mBAAmB,OAAO;AAExD,YAAO,kBAAkB,UAAU;MACjC,GAAG;MACH,SAAS,MAAM;MACf;MACD,CAAC;;;GAGP;AAED,SAAO,kBAAkB,UAAU;GACjC,GAAG;GACH;GACA,SAAS;GACT,SAAS,CAAC,uBAAuB,GAAI,MAAM,WAAW,EAAE,CAAE;GAC3D,CAAC;;CAEL;;AAmBP,MAAa,eACX,QAAQ,IAAI,iCAAiC,UACzC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaH,yBAAU;CAC3D,YAAY,MAAqB,OAAO,sBAAsB;EAC5D,MAAM,WAAW,KAAKA,yBAAU;EAChC,MAAM,SAA8B,EAAE;AAEtC,OAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,QAAQ,SAAS;AASvB,UAAO,OAAO,kBAAkB,OAAO;IAPrC,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAMA,yBAAU;KAAQ;KAAK,CAChC;IAE8C,CAAC;;AAGpD,UAAQ,UAAkBM,wCAAU,QAAe,MAAM;;CAE5D;;AAmBP,MAAa,gBAAgB,WAC3B,QAAQ,IAAI,iCAAiC,UACzC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,aACf,MAAM,aAAaN,yBAAU,UAAU,MAAM,aAAa;CAC7D,YAAY,MAAqB,UAC/BO,0CACE,KAAKP,yBAAU,QAAQ,eACvB,KAAKA,yBAAU,QAAQ,MACvB;EACE,GAAG;EACH,QAAS,UAAU,MAAM;EAC1B,CACF;CACJ;;AAeP,MAAa,aACX,QAAQ,IAAI,+BAA+B,UACvC,iBACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaA,yBAAU;CAC3D,YAAY,MAAmB,OAAO,kBACpC,cAAc,KAAK,SAAS;EAC1B,GAAG;EACH,UAAU,KAAK;EAChB,CAAC;CACL"}
|
|
1
|
+
{"version":3,"file":"plugins.cjs","names":["NodeTypes","getTranslation","getEnumeration","getInsertion","getPlural","getCondition","getGender","getNesting"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport type {\n ConditionContent,\n EnumerationContent,\n FileContent,\n Gender,\n GenderContent,\n InsertionContent,\n NestedContent,\n PluralContent,\n TranslationContent,\n} from '../../transpiler';\nimport { getCondition } from '../getCondition';\nimport { getEnumeration } from '../getEnumeration';\nimport { getGender } from '../getGender';\nimport { getInsertion } from '../getInsertion';\nimport { type GetNestingResult, getNesting } from '../getNesting';\nimport { getPlural } from '../getPlural';\nimport { getTranslation } from '../getTranslation';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\n/** ---------------------------------------------\n * PLUGIN DEFINITION\n * --------------------------------------------- */\n\n/**\n * A plugin/transformer that can optionally transform a node during a single DFS pass.\n * - `canHandle` decides if the node is transformable by this plugin.\n * - `transform` returns the transformed node (and does not recurse further).\n *\n * > `transformFn` is a function that can be used to deeply transform inside the plugin.\n */\nexport type Plugins = {\n id: string;\n canHandle: (node: any) => boolean;\n transform: (\n node: any,\n props: NodeProps,\n transformFn: (node: any, props: NodeProps) => any\n ) => any;\n};\n\n/** ---------------------------------------------\n * FALLBACK PLUGIN\n *\n * Used to fallback a tree-shaken plugin\n * --------------------------------------------- */\n\nexport const fallbackPlugin: Plugins = {\n id: 'fallback-plugin',\n canHandle: () => false,\n transform: (node) => node,\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type UnionKeys<T> = T extends unknown ? keyof T : never;\nexport type ValueAtKey<T, K> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.TRANSLATION]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? U[keyof U] extends Record<PropertyKey, unknown>\n ? {\n [K in UnionKeys<U[keyof U]>]: L extends keyof U\n ? K extends keyof U[L]\n ? U[L][K]\n : ValueAtKey<U[keyof U], K>\n : ValueAtKey<U[keyof U], K>;\n } extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : (L extends keyof U ? U[L] : U[keyof U]) extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins =>\n process.env['INTLAYER_NODE_TYPE_TRANSLATION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.TRANSLATION,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.TRANSLATION] ?? {};\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const childProps = {\n ...props,\n children: original[key as keyof typeof original],\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.TRANSLATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(\n original[key as keyof typeof original],\n childProps\n );\n }\n\n return getTranslation(result, locale, fallback);\n },\n };\n\n/** ---------------------------------------------\n * ENUMERATION PLUGIN\n * --------------------------------------------- */\n\nexport type EnumerationCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.ENUMERATION]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[typeof NodeTypes.ENUMERATION][keyof T[typeof NodeTypes.ENUMERATION]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_ENUMERATION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.ENUMERATION,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.ENUMERATION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as unknown as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ENUMERATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: number | { count: number }) => {\n const quantity = typeof arg === 'number' ? arg : arg.count;\n const subResult = getEnumeration(result, quantity);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * PLURAL PLUGIN\n * --------------------------------------------- */\n\nexport type PluralCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.PLURAL]: object;\n}\n ? (\n arg: number | { count: number; [key: string]: unknown }\n ) => DeepTransformContent<\n T[typeof NodeTypes.PLURAL][keyof T[typeof NodeTypes.PLURAL]],\n S\n >\n : never;\n\n/**\n * Plural plugin. Replaces node with a function that takes a count (or\n * `{ count, ...values }`) => string, picking the matching CLDR plural form\n * for the active locale and interpolating `{{count}}` (and other values).\n */\nexport const pluralPlugin = (locale?: LocalesValues): Plugins =>\n process.env['INTLAYER_NODE_TYPE_PLURAL'] === 'false'\n ? fallbackPlugin\n : {\n id: 'plural-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.PLURAL,\n transform: (node: PluralContent, props, deepTransformNode) => {\n const original = node[NodeTypes.PLURAL];\n const result: Record<string, any> = {};\n\n /** String plugin for plural. Replaces string node with a component that renders the insertion. */\n const pluralStringPlugin: Plugins = {\n id: 'plural-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (values: { [k: string]: string | number }) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.PLURAL, key } as KeyPath,\n ],\n plugins: [pluralStringPlugin, ...(props.plugins ?? [])],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n const effectiveLocale = String(locale ?? props.locale ?? 'en');\n\n return (arg: number | { count: number; [key: string]: unknown }) => {\n const count = typeof arg === 'number' ? arg : arg.count;\n const values =\n typeof arg === 'object'\n ? arg\n : ({ count } as Record<string, unknown>);\n\n const subResult = getPlural(\n result as PluralContent['plural'],\n count,\n effectiveLocale\n );\n\n if (typeof subResult === 'function') {\n return subResult(values);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.CONDITION]: object;\n}\n ? (\n value: boolean | { value: boolean }\n ) => DeepTransformContent<\n T[typeof NodeTypes.CONDITION][keyof T[typeof NodeTypes.CONDITION]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_CONDITION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.CONDITION,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const original = node[NodeTypes.CONDITION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.CONDITION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: boolean | { value: boolean }) => {\n const value = typeof arg === 'boolean' ? arg : arg.value;\n const subResult = getCondition(result as any, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? (\n values: {\n [K in T['fields'][number]]: string | number;\n }\n ) => I extends string\n ? DeepTransformContent<string, S>\n : DeepTransformContent<I, S>\n : never;\n\n/** Insertion plugin. Replaces node with a function that takes quantity => string. */\nexport const insertionPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_INSERTION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.INSERTION];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n };\n\n/** ---------------------------------------------\n * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.GENDER]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<\n T[typeof NodeTypes.GENDER][keyof T[typeof NodeTypes.GENDER]],\n S\n >\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_GENDER'] === 'false'\n ? fallbackPlugin\n : {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.GENDER,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const original = node[NodeTypes.GENDER];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.GENDER, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (value: Gender) => getGender(result as any, value);\n },\n };\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.NESTED]: infer U;\n}\n ? U extends {\n dictionaryKey: infer K extends DictionaryKeys;\n path?: infer P;\n }\n ? GetNestingResult<K, P, S>\n : never\n : never;\n\n/** Nested plugin. Replaces node with the result of `getNesting`. */\nexport const nestedPlugin = (locale?: LocalesValues): Plugins =>\n process.env['INTLAYER_NODE_TYPE_NESTED'] === 'false'\n ? fallbackPlugin\n : {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n (node?.nodeType === NodeTypes.NESTED || node?.nodeType === 'n'),\n transform: (node: NestedContent, props) =>\n getNesting(\n node[NodeTypes.NESTED].dictionaryKey,\n node[NodeTypes.NESTED].path,\n {\n ...props,\n locale: (locale ?? props.locale) as Locale,\n }\n ),\n };\n\n/** ---------------------------------------------\n * FILE PLUGIN\n * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.FILE]: string;\n content?: string;\n}\n ? string\n : never;\n\n/** File plugin. Replaces node with the result of `getNesting`. */\nexport const filePlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_FILE'] === 'false'\n ? fallbackPlugin\n : {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.FILE,\n transform: (node: FileContent, props, deepTransform) =>\n deepTransform(node.content, {\n ...props,\n children: node.content,\n }),\n };\n\n/**\n * PLUGIN RESULT\n */\n\n/**\n * Interface that defines the properties of a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface NodeProps {\n dictionaryKey: string;\n keyPath: KeyPath[];\n plugins?: Plugins[];\n locale?: Locale;\n dictionaryPath?: string;\n children?: any;\n /**\n * Forces eager traversal of plain objects in `deepTransformNode`. By default\n * traversal is lazy (property getters), so callers that discard the returned\n * value never trigger plugins on nested nodes. Set this when running plugins\n * for their side effects only (e.g. missing-locale detection).\n */\n eager?: boolean;\n}\n\n/**\n * Interface that defines the plugins that can be used to transform a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface IInterpreterPlugin<T, S, L extends LocalesValues> {\n translation: TranslationCond<T, S, L>;\n enumeration: EnumerationCond<T, S, L>;\n plural: PluralCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n gender: GenderCond<T, S, L>;\n nested: NestedCond<T, S, L>;\n file: FileCond<T>;\n}\n\n/**\n * Allow to avoid overwriting import from `intlayer` package when `IInterpreterPlugin<T>` interface is augmented in another package, such as `react-intlayer`.\n */\nexport type IInterpreterPluginState = {\n translation: true;\n enumeration: true;\n plural: true;\n condition: true;\n insertion: true;\n gender: true;\n nested: true;\n file: true;\n};\n\n/**\n * Utility type to check if a plugin can be applied to a node.\n */\ntype CheckApplyPlugin<\n T,\n K extends keyof IInterpreterPlugin<T, S, L>,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = K extends keyof S // Test if the key is a key of S.\n ? // Test if the key of S is true. Then the plugin can be applied.\n S[K] extends true\n ? // Test if the key of S exist\n IInterpreterPlugin<T, S, L>[K] extends never\n ? never\n : // Test if the plugin condition is true (if it's not, the plugin is skipped for this node)\n IInterpreterPlugin<T, S, L>[K]\n : never\n : never;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\ntype Traverse<T, S, L extends LocalesValues = DeclaredLocales> =\n T extends ReadonlyArray<infer U> // Turn any read-only array into a plain mutable array\n ? Array<DeepTransformContent<U, S, L>>\n : T extends object\n ? { [K in keyof T]: DeepTransformContent<T[K], S, L> }\n : T;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\nexport type DeepTransformContent<\n T,\n S = IInterpreterPluginState,\n L extends LocalesValues = DeclaredLocales,\n> =\n IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L> extends never // Check if there is a plugin for T:\n ? // No plugin was found, so try to transform T recursively:\n Traverse<T, S, L>\n : // A plugin was found – use the plugin's transformation.\n CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L>;\n"],"mappings":"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"}
|
|
@@ -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 T extends Dictionary,\n 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;
|
|
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 T extends Dictionary,\n 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;CAED,OAAOC,qDAAW,WAAW,SAAS,OAAO,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getEnumeration.cjs","names":[],"sources":["../../../src/interpreter/getEnumeration.ts"],"sourcesContent":["import type { EnterFormat, EnumerationContentState } from '../transpiler';\n\n/**\n * Find the matching condition for a quantity.\n *\n * Usage:\n *\n * ```ts\n * const key = findMatchingCondition({\n * '<=-2.3': 'You have less than -2.3',\n * '<1': 'You have less than one',\n * '2': 'You have two',\n * '>=3': 'You have three or more',\n * }, 2);\n * // '2'\n * ```\n *\n * The order of the keys will define the priority of the content.\n *\n * ```ts\n * const key = findMatchingCondition({\n * '<4': 'You have less than four',\n * '2': 'You have two',\n * }, 2);\n * // '<4'\n * ```\n *\n * If no keys match, the default key is '1'.\n */\nexport const findMatchingCondition = <Content>(\n enumerationContent: EnumerationContentState<Content>,\n quantity: number\n): EnterFormat | undefined => {\n const numericKeys = Object.keys(enumerationContent);\n\n for (const key of numericKeys) {\n const isEqual =\n (!key.startsWith('>') &&\n !key.startsWith('<') &&\n !key.startsWith('=') &&\n parseFloat(key) === quantity) ||\n (key.startsWith('=') && parseFloat(key.slice(1)) === quantity);\n const isSuperior =\n key.startsWith('>') && quantity > parseFloat(key.slice(1));\n const isSuperiorOrEqual =\n key.startsWith('>=') && quantity >= parseFloat(key.slice(2));\n const isInferior =\n key.startsWith('<') && quantity < parseFloat(key.slice(1));\n const isInferiorOrEqual =\n key.startsWith('<=') && quantity <= parseFloat(key.slice(2));\n\n if (\n isEqual ||\n isSuperior ||\n isSuperiorOrEqual ||\n isInferior ||\n isInferiorOrEqual\n ) {\n return key as EnterFormat;\n }\n }\n};\n\n/**\n * Picks content from an enumeration map based on a provided quantity.\n *\n * Supported keys in the enumeration map:\n * - Specific numbers: '0', '1', '2'\n * - Comparison operators: '<5', '>=10', '<=2'\n * - Fallback: 'fallback'\n *\n * The first matching key in the object's iteration order will be selected.\n *\n * @param enumerationContent - A map of conditions/quantities to content.\n * @param quantity - The number to match against the conditions.\n * @returns The matching content.\n *\n * @example\n * ```ts\n * const content = getEnumeration({\n * '0': 'No items',\n * '1': 'One item',\n * '>1': 'Many items',\n * }, 5);\n * // 'Many items'\n * ```\n */\nexport const getEnumeration = <Content>(\n enumerationContent: EnumerationContentState<Content>,\n quantity: number\n): Content => {\n const key =\n findMatchingCondition<Content>(enumerationContent, quantity) ?? 'fallback';\n\n // Default or error handling if no keys match\n return enumerationContent[key] as Content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAa,yBACX,oBACA,aAC4B;CAC5B,MAAM,cAAc,OAAO,KAAK,mBAAmB;
|
|
1
|
+
{"version":3,"file":"getEnumeration.cjs","names":[],"sources":["../../../src/interpreter/getEnumeration.ts"],"sourcesContent":["import type { EnterFormat, EnumerationContentState } from '../transpiler';\n\n/**\n * Find the matching condition for a quantity.\n *\n * Usage:\n *\n * ```ts\n * const key = findMatchingCondition({\n * '<=-2.3': 'You have less than -2.3',\n * '<1': 'You have less than one',\n * '2': 'You have two',\n * '>=3': 'You have three or more',\n * }, 2);\n * // '2'\n * ```\n *\n * The order of the keys will define the priority of the content.\n *\n * ```ts\n * const key = findMatchingCondition({\n * '<4': 'You have less than four',\n * '2': 'You have two',\n * }, 2);\n * // '<4'\n * ```\n *\n * If no keys match, the default key is '1'.\n */\nexport const findMatchingCondition = <Content>(\n enumerationContent: EnumerationContentState<Content>,\n quantity: number\n): EnterFormat | undefined => {\n const numericKeys = Object.keys(enumerationContent);\n\n for (const key of numericKeys) {\n const isEqual =\n (!key.startsWith('>') &&\n !key.startsWith('<') &&\n !key.startsWith('=') &&\n parseFloat(key) === quantity) ||\n (key.startsWith('=') && parseFloat(key.slice(1)) === quantity);\n const isSuperior =\n key.startsWith('>') && quantity > parseFloat(key.slice(1));\n const isSuperiorOrEqual =\n key.startsWith('>=') && quantity >= parseFloat(key.slice(2));\n const isInferior =\n key.startsWith('<') && quantity < parseFloat(key.slice(1));\n const isInferiorOrEqual =\n key.startsWith('<=') && quantity <= parseFloat(key.slice(2));\n\n if (\n isEqual ||\n isSuperior ||\n isSuperiorOrEqual ||\n isInferior ||\n isInferiorOrEqual\n ) {\n return key as EnterFormat;\n }\n }\n};\n\n/**\n * Picks content from an enumeration map based on a provided quantity.\n *\n * Supported keys in the enumeration map:\n * - Specific numbers: '0', '1', '2'\n * - Comparison operators: '<5', '>=10', '<=2'\n * - Fallback: 'fallback'\n *\n * The first matching key in the object's iteration order will be selected.\n *\n * @param enumerationContent - A map of conditions/quantities to content.\n * @param quantity - The number to match against the conditions.\n * @returns The matching content.\n *\n * @example\n * ```ts\n * const content = getEnumeration({\n * '0': 'No items',\n * '1': 'One item',\n * '>1': 'Many items',\n * }, 5);\n * // 'Many items'\n * ```\n */\nexport const getEnumeration = <Content>(\n enumerationContent: EnumerationContentState<Content>,\n quantity: number\n): Content => {\n const key =\n findMatchingCondition<Content>(enumerationContent, quantity) ?? 'fallback';\n\n // Default or error handling if no keys match\n return enumerationContent[key] as Content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAa,yBACX,oBACA,aAC4B;CAC5B,MAAM,cAAc,OAAO,KAAK,mBAAmB;CAEnD,KAAK,MAAM,OAAO,aAAa;EAC7B,MAAM,UACH,CAAC,IAAI,WAAW,IAAI,IACnB,CAAC,IAAI,WAAW,IAAI,IACpB,CAAC,IAAI,WAAW,IAAI,IACpB,WAAW,IAAI,KAAK,YACrB,IAAI,WAAW,IAAI,IAAI,WAAW,IAAI,MAAM,EAAE,CAAC,KAAK;EACvD,MAAM,aACJ,IAAI,WAAW,IAAI,IAAI,WAAW,WAAW,IAAI,MAAM,EAAE,CAAC;EAC5D,MAAM,oBACJ,IAAI,WAAW,KAAK,IAAI,YAAY,WAAW,IAAI,MAAM,EAAE,CAAC;EAC9D,MAAM,aACJ,IAAI,WAAW,IAAI,IAAI,WAAW,WAAW,IAAI,MAAM,EAAE,CAAC;EAC5D,MAAM,oBACJ,IAAI,WAAW,KAAK,IAAI,YAAY,WAAW,IAAI,MAAM,EAAE,CAAC;EAE9D,IACE,WACA,cACA,qBACA,cACA,mBAEA,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6Bb,MAAa,kBACX,oBACA,aACY;CAKZ,OAAO,mBAHL,sBAA+B,oBAAoB,SAAS,IAAI"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getGender.cjs","names":[],"sources":["../../../src/interpreter/getGender.ts"],"sourcesContent":["import type { Gender, GenderContentStates } from '../transpiler';\n\ntype GenderEntry = Gender | 'm' | 'f';\n\nconst getGenderEntry = (gender: GenderEntry): Gender => {\n if (gender === 'm' || gender === 'male') return 'male';\n if (gender === 'f' || gender === 'female') return 'female';\n return 'fallback';\n};\n\n/**\n * Allow to pick a content based on a gender.\n *\n * Usage:\n *\n * ```ts\n * const content = getGender({\n * 'true': 'The gender is validated',\n * 'false': 'The gender is not validated',\n * }, true);\n * // 'The gender is validated'\n * ```\n *\n * The last key provided will be used as the fallback value.\n *\n * ```ts\n * const content = getGender({\n * 'false': 'The gender is not validated',\n * 'true': 'The gender is validated',\n * }, undefined);\n * // 'The gender is validated'\n */\nexport const getGender = <Content>(\n genderContent: GenderContentStates<Content>,\n gender: GenderEntry\n): Content => {\n const stateList = Object.keys(genderContent);\n\n const fallbackState = stateList[\n stateList.length - 1\n ] as keyof typeof genderContent;\n\n const genderEntry = getGenderEntry(gender);\n\n // Default or error handling if no keys match\n return (\n genderContent[genderEntry as keyof typeof genderContent] ??\n genderContent.fallback ??\n (genderContent[fallbackState] as Content)\n );\n};\n"],"mappings":";;;AAIA,MAAM,kBAAkB,WAAgC;
|
|
1
|
+
{"version":3,"file":"getGender.cjs","names":[],"sources":["../../../src/interpreter/getGender.ts"],"sourcesContent":["import type { Gender, GenderContentStates } from '../transpiler';\n\ntype GenderEntry = Gender | 'm' | 'f';\n\nconst getGenderEntry = (gender: GenderEntry): Gender => {\n if (gender === 'm' || gender === 'male') return 'male';\n if (gender === 'f' || gender === 'female') return 'female';\n return 'fallback';\n};\n\n/**\n * Allow to pick a content based on a gender.\n *\n * Usage:\n *\n * ```ts\n * const content = getGender({\n * 'true': 'The gender is validated',\n * 'false': 'The gender is not validated',\n * }, true);\n * // 'The gender is validated'\n * ```\n *\n * The last key provided will be used as the fallback value.\n *\n * ```ts\n * const content = getGender({\n * 'false': 'The gender is not validated',\n * 'true': 'The gender is validated',\n * }, undefined);\n * // 'The gender is validated'\n */\nexport const getGender = <Content>(\n genderContent: GenderContentStates<Content>,\n gender: GenderEntry\n): Content => {\n const stateList = Object.keys(genderContent);\n\n const fallbackState = stateList[\n stateList.length - 1\n ] as keyof typeof genderContent;\n\n const genderEntry = getGenderEntry(gender);\n\n // Default or error handling if no keys match\n return (\n genderContent[genderEntry as keyof typeof genderContent] ??\n genderContent.fallback ??\n (genderContent[fallbackState] as Content)\n );\n};\n"],"mappings":";;;AAIA,MAAM,kBAAkB,WAAgC;CACtD,IAAI,WAAW,OAAO,WAAW,QAAQ,OAAO;CAChD,IAAI,WAAW,OAAO,WAAW,UAAU,OAAO;CAClD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;AAyBT,MAAa,aACX,eACA,WACY;CACZ,MAAM,YAAY,OAAO,KAAK,cAAc;CAE5C,MAAM,gBAAgB,UACpB,UAAU,SAAS;CAMrB,OACE,cAJkB,eAAe,OAIR,KACzB,cAAc,YACb,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getHTML.cjs","names":[],"sources":["../../../src/interpreter/getHTML.ts"],"sourcesContent":["/**\n * Component function that receives properly typed props\n * Props include:\n * - children?: any[] - Array of child elements (ReactNode[], VNode[], etc.)\n * - [key: string]: any - Any HTML attributes (className, style, href, etc.)\n */\ntype Component = (props: { children?: any[]; [key: string]: any }) => any;\n\n/**\n * Component object that delegates to another component\n */\ntype ComponentObject = {\n tag: string;\n props?: Record<string, any>;\n};\n\n/**\n * Components map:\n * - Function components receive typed props\n * - String components delegate to another tag\n * - Object components delegate with additional props\n */\ntype Components = Record<string, Component | string | ComponentObject>;\n\n/**\n * Helper to parse attributes from a tag string.\n */\nconst parseAttributes = (attributes: string): Record<string, string> => {\n const props: Record<string, string> = {};\n const attrRegex = /([a-zA-Z0-9-]+)=\"([^\"]*)\"/g;\n\n let match = attrRegex.exec(attributes);\n while (match !== null) {\n props[match[1]] = match[2];\n match = attrRegex.exec(attributes);\n }\n return props;\n};\n\ntype ASTNode =\n | string\n | {\n tagName: string;\n props: Record<string, string>;\n children: ASTNode[];\n };\n\nconst astCache = new Map<string, ASTNode[]>();\n\nconst parseHTML = (content: string): ASTNode[] => {\n if (astCache.has(content)) {\n return astCache.get(content)!;\n }\n\n if (typeof content !== 'string') {\n return [];\n }\n\n const tagRegex = /<(\\/)?([a-zA-Z0-9.-]+)([\\s\\S]*?)(\\/?)>/g;\n const elements: ASTNode[] = [];\n const stack: {\n tagName: string;\n children: ASTNode[];\n props: Record<string, string>;\n }[] = [];\n\n let lastIndex = 0;\n let match = tagRegex.exec(content);\n\n const appendChild = (child: ASTNode) => {\n const target =\n stack.length > 0 ? stack[stack.length - 1].children : elements;\n target.push(child);\n };\n\n while (match !== null) {\n const [fullMatch, isClosingRaw, tagName, attributesRaw, isSelfClosingRaw] =\n match;\n const matchIndex = match.index;\n\n if (matchIndex > lastIndex) {\n appendChild(content.slice(lastIndex, matchIndex));\n }\n\n const isClosing = isClosingRaw === '/';\n const isSelfClosing =\n isSelfClosingRaw === '/' ||\n attributesRaw.trim().endsWith('/') ||\n fullMatch.endsWith('/>');\n\n const cleanedAttributes = attributesRaw.trim().replace(/\\/$/, '').trim();\n\n if (isClosing) {\n const last = stack[stack.length - 1];\n\n // Only pop if the tag names match\n if (last && last.tagName === tagName) {\n const popped = stack.pop();\n if (popped) {\n appendChild({\n tagName: popped.tagName,\n props: popped.props,\n children: popped.children,\n });\n }\n }\n // If tags don't match or no open tag, silently ignore the closing tag\n } else if (isSelfClosing) {\n const tagProps = parseAttributes(cleanedAttributes);\n appendChild({\n tagName,\n props: tagProps,\n children: [],\n });\n } else {\n const tagProps = parseAttributes(cleanedAttributes);\n stack.push({ tagName, children: [], props: tagProps });\n }\n\n lastIndex = matchIndex + fullMatch.length;\n match = tagRegex.exec(content);\n }\n\n if (lastIndex < content.length) {\n appendChild(content.slice(lastIndex));\n }\n\n // Handle unclosed tags by appending them to the root or parent\n while (stack.length > 0) {\n const last = stack.pop();\n if (last) {\n appendChild({\n tagName: last.tagName,\n props: last.props,\n children: last.children,\n });\n }\n }\n\n astCache.set(content, elements);\n return elements;\n};\n\n/**\n * Interprets a string containing HTML-like tags and replaces them with provided components or strings.\n */\nexport const getHTML = (content: string, values: Components): any => {\n // Parse into AST (cached)\n const ast = parseHTML(content);\n\n // Render AST\n let keyCounter = 0;\n\n const renderASTNode = (node: ASTNode): any => {\n if (typeof node === 'string') {\n return node;\n }\n\n const { tagName, props, children } = node;\n const renderedChildren = children.flatMap(renderASTNode);\n const index = keyCounter++;\n\n let override = values[tagName];\n\n if (!override) {\n const lowerTagName = tagName.toLowerCase();\n const foundKey = Object.keys(values).find(\n (key) => key.toLowerCase() === lowerTagName\n );\n\n if (foundKey) override = values[foundKey];\n }\n\n const key = `html-tag-${tagName}-${index}`;\n\n if (typeof override === 'function') {\n return override({ ...props, children: renderedChildren, key });\n }\n\n if (typeof override === 'string') {\n const component = values[override];\n\n if (typeof component === 'function') {\n return component({ ...props, children: renderedChildren, key });\n }\n return renderedChildren;\n }\n\n if (\n typeof override === 'object' &&\n override !== null &&\n 'tag' in override\n ) {\n const { tag: targetTag, props: extraProps } = override as ComponentObject;\n const component = values[targetTag];\n\n if (typeof component === 'function') {\n return component({\n ...props,\n ...extraProps,\n children: renderedChildren,\n key,\n });\n }\n return renderedChildren;\n }\n\n // Default: Skip tag, render children\n return renderedChildren;\n };\n\n const result = ast.flatMap(renderASTNode);\n return result.length === 1 ? result[0] : result;\n};\n"],"mappings":";;;;;;AA2BA,MAAM,mBAAmB,eAA+C;CACtE,MAAM,QAAgC,EAAE;CACxC,MAAM,YAAY;CAElB,IAAI,QAAQ,UAAU,KAAK,WAAW;
|
|
1
|
+
{"version":3,"file":"getHTML.cjs","names":[],"sources":["../../../src/interpreter/getHTML.ts"],"sourcesContent":["/**\n * Component function that receives properly typed props\n * Props include:\n * - children?: any[] - Array of child elements (ReactNode[], VNode[], etc.)\n * - [key: string]: any - Any HTML attributes (className, style, href, etc.)\n */\ntype Component = (props: { children?: any[]; [key: string]: any }) => any;\n\n/**\n * Component object that delegates to another component\n */\ntype ComponentObject = {\n tag: string;\n props?: Record<string, any>;\n};\n\n/**\n * Components map:\n * - Function components receive typed props\n * - String components delegate to another tag\n * - Object components delegate with additional props\n */\ntype Components = Record<string, Component | string | ComponentObject>;\n\n/**\n * Helper to parse attributes from a tag string.\n */\nconst parseAttributes = (attributes: string): Record<string, string> => {\n const props: Record<string, string> = {};\n const attrRegex = /([a-zA-Z0-9-]+)=\"([^\"]*)\"/g;\n\n let match = attrRegex.exec(attributes);\n while (match !== null) {\n props[match[1]] = match[2];\n match = attrRegex.exec(attributes);\n }\n return props;\n};\n\ntype ASTNode =\n | string\n | {\n tagName: string;\n props: Record<string, string>;\n children: ASTNode[];\n };\n\nconst astCache = new Map<string, ASTNode[]>();\n\nconst parseHTML = (content: string): ASTNode[] => {\n if (astCache.has(content)) {\n return astCache.get(content)!;\n }\n\n if (typeof content !== 'string') {\n return [];\n }\n\n const tagRegex = /<(\\/)?([a-zA-Z0-9.-]+)([\\s\\S]*?)(\\/?)>/g;\n const elements: ASTNode[] = [];\n const stack: {\n tagName: string;\n children: ASTNode[];\n props: Record<string, string>;\n }[] = [];\n\n let lastIndex = 0;\n let match = tagRegex.exec(content);\n\n const appendChild = (child: ASTNode) => {\n const target =\n stack.length > 0 ? stack[stack.length - 1].children : elements;\n target.push(child);\n };\n\n while (match !== null) {\n const [fullMatch, isClosingRaw, tagName, attributesRaw, isSelfClosingRaw] =\n match;\n const matchIndex = match.index;\n\n if (matchIndex > lastIndex) {\n appendChild(content.slice(lastIndex, matchIndex));\n }\n\n const isClosing = isClosingRaw === '/';\n const isSelfClosing =\n isSelfClosingRaw === '/' ||\n attributesRaw.trim().endsWith('/') ||\n fullMatch.endsWith('/>');\n\n const cleanedAttributes = attributesRaw.trim().replace(/\\/$/, '').trim();\n\n if (isClosing) {\n const last = stack[stack.length - 1];\n\n // Only pop if the tag names match\n if (last && last.tagName === tagName) {\n const popped = stack.pop();\n if (popped) {\n appendChild({\n tagName: popped.tagName,\n props: popped.props,\n children: popped.children,\n });\n }\n }\n // If tags don't match or no open tag, silently ignore the closing tag\n } else if (isSelfClosing) {\n const tagProps = parseAttributes(cleanedAttributes);\n appendChild({\n tagName,\n props: tagProps,\n children: [],\n });\n } else {\n const tagProps = parseAttributes(cleanedAttributes);\n stack.push({ tagName, children: [], props: tagProps });\n }\n\n lastIndex = matchIndex + fullMatch.length;\n match = tagRegex.exec(content);\n }\n\n if (lastIndex < content.length) {\n appendChild(content.slice(lastIndex));\n }\n\n // Handle unclosed tags by appending them to the root or parent\n while (stack.length > 0) {\n const last = stack.pop();\n if (last) {\n appendChild({\n tagName: last.tagName,\n props: last.props,\n children: last.children,\n });\n }\n }\n\n astCache.set(content, elements);\n return elements;\n};\n\n/**\n * Interprets a string containing HTML-like tags and replaces them with provided components or strings.\n */\nexport const getHTML = (content: string, values: Components): any => {\n // Parse into AST (cached)\n const ast = parseHTML(content);\n\n // Render AST\n let keyCounter = 0;\n\n const renderASTNode = (node: ASTNode): any => {\n if (typeof node === 'string') {\n return node;\n }\n\n const { tagName, props, children } = node;\n const renderedChildren = children.flatMap(renderASTNode);\n const index = keyCounter++;\n\n let override = values[tagName];\n\n if (!override) {\n const lowerTagName = tagName.toLowerCase();\n const foundKey = Object.keys(values).find(\n (key) => key.toLowerCase() === lowerTagName\n );\n\n if (foundKey) override = values[foundKey];\n }\n\n const key = `html-tag-${tagName}-${index}`;\n\n if (typeof override === 'function') {\n return override({ ...props, children: renderedChildren, key });\n }\n\n if (typeof override === 'string') {\n const component = values[override];\n\n if (typeof component === 'function') {\n return component({ ...props, children: renderedChildren, key });\n }\n return renderedChildren;\n }\n\n if (\n typeof override === 'object' &&\n override !== null &&\n 'tag' in override\n ) {\n const { tag: targetTag, props: extraProps } = override as ComponentObject;\n const component = values[targetTag];\n\n if (typeof component === 'function') {\n return component({\n ...props,\n ...extraProps,\n children: renderedChildren,\n key,\n });\n }\n return renderedChildren;\n }\n\n // Default: Skip tag, render children\n return renderedChildren;\n };\n\n const result = ast.flatMap(renderASTNode);\n return result.length === 1 ? result[0] : result;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getInsertion.cjs","names":[],"sources":["../../../src/interpreter/getInsertion.ts"],"sourcesContent":["import type { InsertionContent } from '../transpiler';\n\n/**\n * Allow to insert values in a string.\n *\n * Usage:\n *\n * ```ts\n * const content = getInsertion('Hello {{name}}!', {\n * name: 'John',\n * });\n * // 'Hello John!'\n * ```\n *\n */\nexport const getInsertion = (\n content: string,\n values: { [K in InsertionContent['fields'][number]]: string | number }\n) =>\n content.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n });\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAa,gBACX,SACA,WAEA,QAAQ,QAAQ,yBAAyB,GAAG,QAAQ;
|
|
1
|
+
{"version":3,"file":"getInsertion.cjs","names":[],"sources":["../../../src/interpreter/getInsertion.ts"],"sourcesContent":["import type { InsertionContent } from '../transpiler';\n\n/**\n * Allow to insert values in a string.\n *\n * Usage:\n *\n * ```ts\n * const content = getInsertion('Hello {{name}}!', {\n * name: 'John',\n * });\n * // 'Hello John!'\n * ```\n *\n */\nexport const getInsertion = (\n content: string,\n values: { [K in InsertionContent['fields'][number]]: string | number }\n) =>\n content.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n });\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAa,gBACX,SACA,WAEA,QAAQ,QAAQ,yBAAyB,GAAG,QAAQ;CAElD,QAAQ,OADW,IAAI,MACE,KAAK,IAAI,UAAU;EAC5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIntlayer.cjs","names":["getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryContent,\n DictionaryRegistryElement,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy(\n // Target is a function so it can be called if the dictionary expects a function\n () => path,\n {\n get: (_target, prop) => {\n // Handle common object methods to prevent infinite recursion or weird behavior\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n if (prop === Symbol.iterator) {\n return function* () {\n yield path;\n };\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n // If the code tries to execute the missing key as a function: t.title()\n apply: () => {\n return path;\n },\n }\n );\n};\n\nconst dictionaryCache = new Map<string, any>();\nconst warnedMissingDictionaries = new Set<string>();\n\nexport const getIntlayer = <\n T extends DictionaryKeys,\n L extends LocalesValues = DeclaredLocales,\n>(\n key: T,\n locale?: L,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryContent<T>,\n IInterpreterPluginState,\n L\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T] as DictionaryRegistryElement<T>;\n\n if (!dictionary) {\n if (!warnedMissingDictionaries.has(key as string)) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n `Dictionary ${colorizeKey(key as string)} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n isVerbose: true,\n }\n );\n warnedMissingDictionaries.add(key as string);\n }\n\n if (process.env.NODE_ENV === 'development') {\n // Return the Safe Proxy\n // We initialize it with the dictionary key name so the UI shows \"my-dictionary.someKey\"\n return createSafeFallback(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n const cacheKey = `${key}_${locale ?? 'default'}_${plugins ? 'custom_plugins' : 'default_plugins'}`;\n\n if (dictionaryCache.has(cacheKey)) {\n return dictionaryCache.get(cacheKey);\n }\n\n const result = getDictionary<DictionaryRegistryElement<T>, L>(\n dictionary,\n locale,\n plugins\n );\n\n dictionaryCache.set(cacheKey, result);\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAM,sBAAsB,OAAO,OAAY;
|
|
1
|
+
{"version":3,"file":"getIntlayer.cjs","names":["getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryContent,\n DictionaryRegistryElement,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy(\n // Target is a function so it can be called if the dictionary expects a function\n () => path,\n {\n get: (_target, prop) => {\n // Handle common object methods to prevent infinite recursion or weird behavior\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n if (prop === Symbol.iterator) {\n return function* () {\n yield path;\n };\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n // If the code tries to execute the missing key as a function: t.title()\n apply: () => {\n return path;\n },\n }\n );\n};\n\nconst dictionaryCache = new Map<string, any>();\nconst warnedMissingDictionaries = new Set<string>();\n\nexport const getIntlayer = <\n T extends DictionaryKeys,\n L extends LocalesValues = DeclaredLocales,\n>(\n key: T,\n locale?: L,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryContent<T>,\n IInterpreterPluginState,\n L\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T] as DictionaryRegistryElement<T>;\n\n if (!dictionary) {\n if (!warnedMissingDictionaries.has(key as string)) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n `Dictionary ${colorizeKey(key as string)} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n isVerbose: true,\n }\n );\n warnedMissingDictionaries.add(key as string);\n }\n\n if (process.env.NODE_ENV === 'development') {\n // Return the Safe Proxy\n // We initialize it with the dictionary key name so the UI shows \"my-dictionary.someKey\"\n return createSafeFallback(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n const cacheKey = `${key}_${locale ?? 'default'}_${plugins ? 'custom_plugins' : 'default_plugins'}`;\n\n if (dictionaryCache.has(cacheKey)) {\n return dictionaryCache.get(cacheKey);\n }\n\n const result = getDictionary<DictionaryRegistryElement<T>, L>(\n dictionary,\n locale,\n plugins\n );\n\n dictionaryCache.set(cacheKey, result);\n\n return result;\n};\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAM,sBAAsB,OAAO,OAAY;CAC7C,OAAO,IAAI,YAEH,MACN;EACE,MAAM,SAAS,SAAS;GAEtB,IACE,SAAS,YACT,SAAS,OAAO,eAChB,SAAS,YAET,aAAa;GAEf,IAAI,SAAS,QACX;GAEF,IAAI,SAAS,OAAO,UAClB,OAAO,aAAa;IAClB,MAAM;;GAMV,OAAO,mBADU,OAAO,GAAG,KAAK,GAAG,OAAO,KAAK,KAAK,OAAO,KAAK,CAC7B;;EAGrC,aAAa;GACX,OAAO;;EAEV,CACF;;AAGH,MAAM,kCAAkB,IAAI,KAAkB;AAC9C,MAAM,4CAA4B,IAAI,KAAa;AAEnD,MAAa,eAIX,KACA,QACA,YAKG;CAEH,MAAM,gEAAyB,CAAC;CAEhC,IAAI,CAAC,YAAY;EACf,IAAI,CAAC,0BAA0B,IAAI,IAAc,EAAE;GAGjD,0CAD4B,EAAE,iCAAK,CAC7B,CACJ,uDAA0B,IAAc,CAAC,wCACzC;IACE,OAAO;IACP,WAAW;IACZ,CACF;GACD,0BAA0B,IAAI,IAAc;;EAG9C,IAAI,QAAQ,IAAI,aAAa,eAG3B,OAAO,mBAAmB,IAAc;EAG1C,OAAO,mBAAmB,IAAc;;CAG1C,MAAM,WAAW,GAAG,IAAI,GAAG,UAAU,UAAU,GAAG,UAAU,mBAAmB;CAE/E,IAAI,gBAAgB,IAAI,SAAS,EAC/B,OAAO,gBAAgB,IAAI,SAAS;CAGtC,MAAM,SAASA,gDACb,YACA,QACA,QACD;CAED,gBAAgB,IAAI,UAAU,OAAO;CAErC,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getNesting.cjs","names":["getIntlayer"],"sources":["../../../src/interpreter/getNesting.ts"],"sourcesContent":["import type { DictionaryKeys, DictionaryRegistryContent } from '@intlayer/types/module_augmentation';\nimport type { GetSubPath } from '@intlayer/types/dictionary';\nimport type { ValidDotPathsFor } from '../transpiler';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n NodeProps,\n} from './getContent';\nimport { getIntlayer } from './getIntlayer';\n\nexport type GetNestingResult<\n K extends DictionaryKeys,\n P = undefined,\n S = IInterpreterPluginState,\n> = GetSubPath<DeepTransformContent<DictionaryRegistryContent<K>, S>, P>;\n\n/**\n * Extracts content from another dictionary by its key and an optional path.\n *\n * This allows for reusing content across different dictionaries.\n *\n * @param dictionaryKey - The key of the dictionary to nest.\n * @param path - Optional dot-separated path to a specific field within the nested dictionary.\n * @param props - Optional properties like locale and plugins.\n * @returns The nested content.\n *\n * @example\n * ```ts\n * const content = getNesting(\"common\", \"buttons.save\");\n * // 'Save'\n * ```\n */\nexport const getNesting = <K extends DictionaryKeys, P>(\n dictionaryKey: K,\n path?: P extends ValidDotPathsFor<K> ? P : never,\n props?: NodeProps\n): GetNestingResult<K, P> => {\n const dictionary = getIntlayer(dictionaryKey, props?.locale, props?.plugins);\n\n if (typeof path === 'string') {\n const pathArray = (path as string).split('.');\n let current: any = dictionary;\n\n for (const key of pathArray) {\n // Safely traverse down the object using the path\n current = current?.[key];\n // If we cannot find the path, return the whole dictionary as a fallback\n if (current === undefined) {\n return dictionary as any;\n }\n }\n\n return current;\n }\n\n // Default or error handling if path is not a string or otherwise undefined\n return dictionary as any;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,cACX,eACA,MACA,UAC2B;CAC3B,MAAM,aAAaA,4CAAY,eAAe,OAAO,QAAQ,OAAO,QAAQ;
|
|
1
|
+
{"version":3,"file":"getNesting.cjs","names":["getIntlayer"],"sources":["../../../src/interpreter/getNesting.ts"],"sourcesContent":["import type { DictionaryKeys, DictionaryRegistryContent } from '@intlayer/types/module_augmentation';\nimport type { GetSubPath } from '@intlayer/types/dictionary';\nimport type { ValidDotPathsFor } from '../transpiler';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n NodeProps,\n} from './getContent';\nimport { getIntlayer } from './getIntlayer';\n\nexport type GetNestingResult<\n K extends DictionaryKeys,\n P = undefined,\n S = IInterpreterPluginState,\n> = GetSubPath<DeepTransformContent<DictionaryRegistryContent<K>, S>, P>;\n\n/**\n * Extracts content from another dictionary by its key and an optional path.\n *\n * This allows for reusing content across different dictionaries.\n *\n * @param dictionaryKey - The key of the dictionary to nest.\n * @param path - Optional dot-separated path to a specific field within the nested dictionary.\n * @param props - Optional properties like locale and plugins.\n * @returns The nested content.\n *\n * @example\n * ```ts\n * const content = getNesting(\"common\", \"buttons.save\");\n * // 'Save'\n * ```\n */\nexport const getNesting = <K extends DictionaryKeys, P>(\n dictionaryKey: K,\n path?: P extends ValidDotPathsFor<K> ? P : never,\n props?: NodeProps\n): GetNestingResult<K, P> => {\n const dictionary = getIntlayer(dictionaryKey, props?.locale, props?.plugins);\n\n if (typeof path === 'string') {\n const pathArray = (path as string).split('.');\n let current: any = dictionary;\n\n for (const key of pathArray) {\n // Safely traverse down the object using the path\n current = current?.[key];\n // If we cannot find the path, return the whole dictionary as a fallback\n if (current === undefined) {\n return dictionary as any;\n }\n }\n\n return current;\n }\n\n // Default or error handling if path is not a string or otherwise undefined\n return dictionary as any;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,cACX,eACA,MACA,UAC2B;CAC3B,MAAM,aAAaA,4CAAY,eAAe,OAAO,QAAQ,OAAO,QAAQ;CAE5E,IAAI,OAAO,SAAS,UAAU;EAC5B,MAAM,YAAa,KAAgB,MAAM,IAAI;EAC7C,IAAI,UAAe;EAEnB,KAAK,MAAM,OAAO,WAAW;GAE3B,UAAU,UAAU;GAEpB,IAAI,YAAY,QACd,OAAO;;EAIX,OAAO;;CAIT,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPlural.cjs","names":["getCachedIntl"],"sources":["../../../src/interpreter/getPlural.ts"],"sourcesContent":["import type { DeclaredLocales } from '@intlayer/types';\nimport type { LocalesValues } from 'intlayer';\nimport { getCachedIntl } from '../formatters';\nimport type {\n PluralCategory,\n PluralContentState,\n} from '../transpiler/plural/plural';\n\n/**\n * Picks content from a plural map based on a count and locale, using CLDR\n * pluralization rules (`Intl.PluralRules`).\n *\n * Falls back to the `other` category when no specific category matches.\n *\n * @example\n * ```ts\n * getPlural({\n * one: 'one item',\n * other: '{{count}} items',\n * }, 5, 'en');\n * // '{{count}} items'\n * ```\n */\nexport const getPlural = <L extends LocalesValues = DeclaredLocales>(\n pluralContent: PluralContentState<string>,\n count: number,\n locale: L\n): string => {\n const category = getCachedIntl(Intl.PluralRules, locale).select(\n count\n ) as PluralCategory;\n\n return pluralContent[category] ?? pluralContent.other;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAuBA,MAAa,aACX,eACA,OACA,WACW;
|
|
1
|
+
{"version":3,"file":"getPlural.cjs","names":["getCachedIntl"],"sources":["../../../src/interpreter/getPlural.ts"],"sourcesContent":["import type { DeclaredLocales } from '@intlayer/types';\nimport type { LocalesValues } from 'intlayer';\nimport { getCachedIntl } from '../formatters';\nimport type {\n PluralCategory,\n PluralContentState,\n} from '../transpiler/plural/plural';\n\n/**\n * Picks content from a plural map based on a count and locale, using CLDR\n * pluralization rules (`Intl.PluralRules`).\n *\n * Falls back to the `other` category when no specific category matches.\n *\n * @example\n * ```ts\n * getPlural({\n * one: 'one item',\n * other: '{{count}} items',\n * }, 5, 'en');\n * // '{{count}} items'\n * ```\n */\nexport const getPlural = <L extends LocalesValues = DeclaredLocales>(\n pluralContent: PluralContentState<string>,\n count: number,\n locale: L\n): string => {\n const category = getCachedIntl(Intl.PluralRules, locale).select(\n count\n ) as PluralCategory;\n\n return pluralContent[category] ?? pluralContent.other;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAuBA,MAAa,aACX,eACA,OACA,WACW;CAKX,OAAO,cAJUA,iCAAc,KAAK,aAAa,OAAO,CAAC,OACvD,MAG2B,KAAK,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTranslation.cjs","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type {\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Check if a value is a plain object that can be safely merged.\n * Returns false for Promises, React elements, class instances, etc.\n */\nconst isPlainObject = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object') return false;\n if (typeof (value as any).then === 'function') return false;\n if (\n (value as any).$$typeof !== undefined ||\n (value as any).__v_isVNode !== undefined ||\n (value as any)._isVNode !== undefined ||\n (value as any).isJSX !== undefined\n ) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null || Array.isArray(value);\n};\n\n/**\n * Recursively merges two objects, skipping undefined source values.\n * First argument takes precedence. Arrays replace rather than merge.\n */\nconst deepMerge = (target: any, source: any): any => {\n if (target === undefined) return source;\n if (source === undefined) return target;\n if (Array.isArray(target)) return target;\n if (isPlainObject(target) && isPlainObject(source)) {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n if (\n key === '__proto__' ||\n key === 'constructor' ||\n source[key] === undefined\n )\n continue;\n result[key] =\n target[key] !== undefined\n ? deepMerge(target[key], source[key])\n : source[key];\n }\n return result;\n }\n return target;\n};\n\n/**\n * Picks the appropriate content from a locale map based on the provided locale.\n *\n * It handles:\n * 1. Exact locale match (e.g., 'en-US').\n * 2. Generic locale fallback (e.g., 'en' if 'en-US' is not found).\n * 3. Explicit fallback locale.\n * 4. Deep merging of objects to ensure partial translations are complemented by fallbacks.\n *\n * @param languageContent - A map of locales to content.\n * @param locale - The target locale to retrieve.\n * @param fallback - Optional fallback locale if the target is not found.\n * @returns The translated content.\n *\n * @example\n * ```ts\n * const content = getTranslation({\n * en: 'Hello',\n * fr: 'Bonjour',\n * }, 'fr');\n * // 'Bonjour'\n * ```\n */\nexport const getTranslation = <Content = string>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues,\n fallback?: LocalesValues\n): Content => {\n const get = (loc: string): Content | undefined =>\n languageContent[loc as keyof typeof languageContent];\n\n // Build priority-ordered locale candidates (most specific first), deduped\n const seen = new Set<string>();\n const locales: string[] = [];\n const addLocale = (loc: string | undefined) => {\n if (loc && !seen.has(loc)) {\n seen.add(loc);\n locales.push(loc);\n }\n };\n\n addLocale(locale);\n if (locale.includes('-')) addLocale(locale.split('-')[0]);\n\n addLocale(fallback);\n if (fallback?.includes('-')) addLocale(fallback.split('-')[0]);\n\n // Collect results: strings exit early (if no higher-priority object was found),\n // objects are accumulated for deep merging.\n const results: Content[] = [];\n\n for (const loc of locales) {\n const val = get(loc);\n\n if (val === undefined) continue;\n if (typeof val === 'string') {\n if (results.length === 0) return val;\n continue; // an object at higher priority takes precedence\n }\n\n results.push(val);\n }\n\n if (results.length === 0) return undefined as Content;\n if (results.length === 1) return results[0];\n if (Array.isArray(results[0])) return results[0];\n\n // Merge objects: first result (most specific) takes precedence\n return (results as object[]).reduce((acc, curr) =>\n deepMerge(acc, curr)\n ) as Content;\n};\n"],"mappings":";;;;;;;AASA,MAAM,iBAAiB,UAA4B;
|
|
1
|
+
{"version":3,"file":"getTranslation.cjs","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type {\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Check if a value is a plain object that can be safely merged.\n * Returns false for Promises, React elements, class instances, etc.\n */\nconst isPlainObject = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object') return false;\n if (typeof (value as any).then === 'function') return false;\n if (\n (value as any).$$typeof !== undefined ||\n (value as any).__v_isVNode !== undefined ||\n (value as any)._isVNode !== undefined ||\n (value as any).isJSX !== undefined\n ) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null || Array.isArray(value);\n};\n\n/**\n * Recursively merges two objects, skipping undefined source values.\n * First argument takes precedence. Arrays replace rather than merge.\n */\nconst deepMerge = (target: any, source: any): any => {\n if (target === undefined) return source;\n if (source === undefined) return target;\n if (Array.isArray(target)) return target;\n if (isPlainObject(target) && isPlainObject(source)) {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n if (\n key === '__proto__' ||\n key === 'constructor' ||\n source[key] === undefined\n )\n continue;\n result[key] =\n target[key] !== undefined\n ? deepMerge(target[key], source[key])\n : source[key];\n }\n return result;\n }\n return target;\n};\n\n/**\n * Picks the appropriate content from a locale map based on the provided locale.\n *\n * It handles:\n * 1. Exact locale match (e.g., 'en-US').\n * 2. Generic locale fallback (e.g., 'en' if 'en-US' is not found).\n * 3. Explicit fallback locale.\n * 4. Deep merging of objects to ensure partial translations are complemented by fallbacks.\n *\n * @param languageContent - A map of locales to content.\n * @param locale - The target locale to retrieve.\n * @param fallback - Optional fallback locale if the target is not found.\n * @returns The translated content.\n *\n * @example\n * ```ts\n * const content = getTranslation({\n * en: 'Hello',\n * fr: 'Bonjour',\n * }, 'fr');\n * // 'Bonjour'\n * ```\n */\nexport const getTranslation = <Content = string>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues,\n fallback?: LocalesValues\n): Content => {\n const get = (loc: string): Content | undefined =>\n languageContent[loc as keyof typeof languageContent];\n\n // Build priority-ordered locale candidates (most specific first), deduped\n const seen = new Set<string>();\n const locales: string[] = [];\n const addLocale = (loc: string | undefined) => {\n if (loc && !seen.has(loc)) {\n seen.add(loc);\n locales.push(loc);\n }\n };\n\n addLocale(locale);\n if (locale.includes('-')) addLocale(locale.split('-')[0]);\n\n addLocale(fallback);\n if (fallback?.includes('-')) addLocale(fallback.split('-')[0]);\n\n // Collect results: strings exit early (if no higher-priority object was found),\n // objects are accumulated for deep merging.\n const results: Content[] = [];\n\n for (const loc of locales) {\n const val = get(loc);\n\n if (val === undefined) continue;\n if (typeof val === 'string') {\n if (results.length === 0) return val;\n continue; // an object at higher priority takes precedence\n }\n\n results.push(val);\n }\n\n if (results.length === 0) return undefined as Content;\n if (results.length === 1) return results[0];\n if (Array.isArray(results[0])) return results[0];\n\n // Merge objects: first result (most specific) takes precedence\n return (results as object[]).reduce((acc, curr) =>\n deepMerge(acc, curr)\n ) as Content;\n};\n"],"mappings":";;;;;;;AASA,MAAM,iBAAiB,UAA4B;CACjD,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO;CACxD,IAAI,OAAQ,MAAc,SAAS,YAAY,OAAO;CACtD,IACG,MAAc,aAAa,UAC3B,MAAc,gBAAgB,UAC9B,MAAc,aAAa,UAC3B,MAAc,UAAU,QAEzB,OAAO;CAET,MAAM,QAAQ,OAAO,eAAe,MAAM;CAC1C,OAAO,UAAU,OAAO,aAAa,UAAU,QAAQ,MAAM,QAAQ,MAAM;;;;;;AAO7E,MAAM,aAAa,QAAa,WAAqB;CACnD,IAAI,WAAW,QAAW,OAAO;CACjC,IAAI,WAAW,QAAW,OAAO;CACjC,IAAI,MAAM,QAAQ,OAAO,EAAE,OAAO;CAClC,IAAI,cAAc,OAAO,IAAI,cAAc,OAAO,EAAE;EAClD,MAAM,SAAS,EAAE,GAAG,QAAQ;EAE5B,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;GACrC,IACE,QAAQ,eACR,QAAQ,iBACR,OAAO,SAAS,QAEhB;GACF,OAAO,OACL,OAAO,SAAS,SACZ,UAAU,OAAO,MAAM,OAAO,KAAK,GACnC,OAAO;;EAEf,OAAO;;CAET,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;AA0BT,MAAa,kBACX,iBACA,QACA,aACY;CACZ,MAAM,OAAO,QACX,gBAAgB;CAGlB,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,UAAoB,EAAE;CAC5B,MAAM,aAAa,QAA4B;EAC7C,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,EAAE;GACzB,KAAK,IAAI,IAAI;GACb,QAAQ,KAAK,IAAI;;;CAIrB,UAAU,OAAO;CACjB,IAAI,OAAO,SAAS,IAAI,EAAE,UAAU,OAAO,MAAM,IAAI,CAAC,GAAG;CAEzD,UAAU,SAAS;CACnB,IAAI,UAAU,SAAS,IAAI,EAAE,UAAU,SAAS,MAAM,IAAI,CAAC,GAAG;CAI9D,MAAM,UAAqB,EAAE;CAE7B,KAAK,MAAM,OAAO,SAAS;EACzB,MAAM,MAAM,IAAI,IAAI;EAEpB,IAAI,QAAQ,QAAW;EACvB,IAAI,OAAO,QAAQ,UAAU;GAC3B,IAAI,QAAQ,WAAW,GAAG,OAAO;GACjC;;EAGF,QAAQ,KAAK,IAAI;;CAGnB,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,IAAI,QAAQ,WAAW,GAAG,OAAO,QAAQ;CACzC,IAAI,MAAM,QAAQ,QAAQ,GAAG,EAAE,OAAO,QAAQ;CAG9C,OAAQ,QAAqB,QAAQ,KAAK,SACxC,UAAU,KAAK,KAAK,CACrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"splitAndJoinInsertion.cjs","names":[],"sources":["../../../src/interpreter/splitAndJoinInsertion.ts"],"sourcesContent":["/**\n * Check if a value is a complex object (not a primitive)\n * Used to determine if values need to be wrapped in fragments\n */\nconst isComplexValue = (value: any): boolean =>\n value != null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean';\n\n// Hoisted: replace/split do not suffer from the stateful lastIndex mutation of .exec()\nconst insertionRegex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n\nexport const splitInsertionTemplate = <T = any>(\n template: string,\n values: Record<string, T> = {}\n): { isSimple: boolean; parts: string | T[] } => {\n if (!Object.values(values).some(isComplexValue)) {\n return {\n isSimple: true,\n parts: template.replace(insertionRegex, (_, key) =>\n (values[key.trim()] ?? '').toString()\n ),\n };\n }\n\n const chunks = template.split(insertionRegex);\n const parts: any[] = [];\n\n for (let i = 0; i < chunks.length; i++) {\n if (i % 2 === 0) {\n if (chunks[i]) parts.push(chunks[i]);\n } else {\n const val = values[chunks[i].trim()];\n if (val != null) parts.push(val);\n }\n }\n\n return { isSimple: false, parts };\n};\n"],"mappings":";;;;;;;AAIA,MAAM,kBAAkB,UACtB,SAAS,QACT,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU;AAGnB,MAAM,iBAAiB;AAEvB,MAAa,0BACX,UACA,SAA4B,EAAE,KACiB;
|
|
1
|
+
{"version":3,"file":"splitAndJoinInsertion.cjs","names":[],"sources":["../../../src/interpreter/splitAndJoinInsertion.ts"],"sourcesContent":["/**\n * Check if a value is a complex object (not a primitive)\n * Used to determine if values need to be wrapped in fragments\n */\nconst isComplexValue = (value: any): boolean =>\n value != null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean';\n\n// Hoisted: replace/split do not suffer from the stateful lastIndex mutation of .exec()\nconst insertionRegex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n\nexport const splitInsertionTemplate = <T = any>(\n template: string,\n values: Record<string, T> = {}\n): { isSimple: boolean; parts: string | T[] } => {\n if (!Object.values(values).some(isComplexValue)) {\n return {\n isSimple: true,\n parts: template.replace(insertionRegex, (_, key) =>\n (values[key.trim()] ?? '').toString()\n ),\n };\n }\n\n const chunks = template.split(insertionRegex);\n const parts: any[] = [];\n\n for (let i = 0; i < chunks.length; i++) {\n if (i % 2 === 0) {\n if (chunks[i]) parts.push(chunks[i]);\n } else {\n const val = values[chunks[i].trim()];\n if (val != null) parts.push(val);\n }\n }\n\n return { isSimple: false, parts };\n};\n"],"mappings":";;;;;;;AAIA,MAAM,kBAAkB,UACtB,SAAS,QACT,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU;AAGnB,MAAM,iBAAiB;AAEvB,MAAa,0BACX,UACA,SAA4B,EAAE,KACiB;CAC/C,IAAI,CAAC,OAAO,OAAO,OAAO,CAAC,KAAK,eAAe,EAC7C,OAAO;EACL,UAAU;EACV,OAAO,SAAS,QAAQ,iBAAiB,GAAG,SACzC,OAAO,IAAI,MAAM,KAAK,IAAI,UAAU,CACtC;EACF;CAGH,MAAM,SAAS,SAAS,MAAM,eAAe;CAC7C,MAAM,QAAe,EAAE;CAEvB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KACjC,IAAI,IAAI,MAAM,GACZ;MAAI,OAAO,IAAI,MAAM,KAAK,OAAO,GAAG;QAC/B;EACL,MAAM,MAAM,OAAO,OAAO,GAAG,MAAM;EACnC,IAAI,OAAO,MAAM,MAAM,KAAK,IAAI;;CAIpC,OAAO;EAAE,UAAU;EAAO;EAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateSitemap.cjs","names":["resolveRoutingConfig","getMultilingualUrls"],"sources":["../../../src/localization/generateSitemap.ts"],"sourcesContent":["import type { RoutingConfig } from '@intlayer/types/config';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getMultilingualUrls } from './getMultilingualUrls';\nimport { type RoutingOptions, resolveRoutingConfig } from './getPrefix';\n\nexport type SitemapUrlEntry = {\n /** The canonical path, e.g. '/dashboard' */\n path: string;\n changefreq?: string;\n priority?: number;\n /** ISO date string, e.g. '2024-01-15' */\n lastmod?: string;\n};\n\nexport type GenerateSitemapOptions = {\n /** Base site URL without trailing slash, e.g. 'https://example.com' */\n siteUrl: string;\n /**\n * Whether to include xhtml:link alternate tags for multilingual support.\n *\n * When enabled, alternate links are only generated for modes where URLs\n * differ per locale:\n * - 'prefix-no-default': included\n * - 'prefix-all': included\n * - 'search-params': included\n * - 'no-prefix': excluded (all locales share the same URL)\n *\n * @default true\n */\n xhtmlLinks?: boolean;\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n};\n\n/**\n * Returns whether xhtml:link alternate tags should be generated for the given routing mode.\n *\n * Alternates are meaningful only when locale URLs are distinct:\n * - 'no-prefix' produces identical URLs for all locales → no alternates\n * - all other modes produce distinct URLs → alternates are generated\n */\nconst shouldIncludeAlternates = (\n mode: RoutingConfig['mode'],\n xhtmlLinks: boolean\n): boolean => xhtmlLinks && mode !== 'no-prefix';\n\n/**\n * Generates a single `<url>` sitemap entry for the given path.\n *\n * Example:\n *\n * ```ts\n * generateSitemapUrl('/dashboard', {\n * siteUrl: 'https://example.com',\n * changefreq: 'weekly',\n * priority: 0.8,\n * xhtmlLinks: true,\n * locales: ['en', 'fr'],\n * defaultLocale: 'en',\n * mode: 'prefix-no-default',\n * });\n * // Returns:\n * // <url>\n * // <loc>https://example.com/dashboard</loc>\n * // <changefreq>weekly</changefreq>\n * // <priority>0.8</priority>\n * // <xhtml:link rel=\"alternate\" hrefLang=\"en\" href=\"https://example.com/dashboard\"/>\n * // <xhtml:link rel=\"alternate\" hrefLang=\"fr\" href=\"https://example.com/fr/dashboard\"/>\n * // <xhtml:link rel=\"alternate\" hrefLang=\"x-default\" href=\"https://example.com/dashboard\"/>\n * // </url>\n * ```\n *\n * @param path - The canonical path to generate the entry for.\n * @param options - Configuration options.\n * @returns A `<url>` XML string.\n */\nexport const generateSitemapUrl = (\n path: string,\n options: SitemapUrlEntry & GenerateSitemapOptions\n): string => {\n const {\n siteUrl,\n changefreq,\n priority,\n lastmod,\n xhtmlLinks = true,\n ...routingOptions\n } = options;\n\n const resolved = resolveRoutingConfig(routingOptions as RoutingOptions);\n const fullUrl = `${siteUrl}${path}`;\n\n const lines: (string | null)[] = [\n ' <url>',\n ` <loc>${fullUrl}</loc>`,\n lastmod ? ` <lastmod>${lastmod}</lastmod>` : null,\n changefreq ? ` <changefreq>${changefreq}</changefreq>` : null,\n priority !== undefined ? ` <priority>${priority}</priority>` : null,\n ];\n\n if (shouldIncludeAlternates(resolved.mode, xhtmlLinks)) {\n const alternates = getMultilingualUrls(\n path,\n routingOptions as RoutingOptions\n );\n\n for (const [lang, localePath] of Object.entries(alternates)) {\n lines.push(\n ` <xhtml:link rel=\"alternate\" hrefLang=\"${lang}\" href=\"${siteUrl}${localePath}\"/>`\n );\n }\n\n lines.push(\n ` <xhtml:link rel=\"alternate\" hrefLang=\"x-default\" href=\"${fullUrl}\"/>`\n );\n }\n\n lines.push(' </url>');\n\n return lines.filter(Boolean).join('\\n');\n};\n\n/**\n * Generates a full XML sitemap string from an array of URL entries.\n *\n * Automatically adds `xmlns:xhtml` to the `<urlset>` declaration when\n * xhtml:link alternate tags are included.\n *\n * Example:\n *\n * ```ts\n * generateSitemap(\n * [\n * { path: '/', changefreq: 'daily', priority: 1.0 },\n * { path: '/about', changefreq: 'monthly', priority: 0.5 },\n * ],\n * {\n * siteUrl: 'https://example.com',\n * xhtmlLinks: true,\n * locales: ['en', 'fr'],\n * defaultLocale: 'en',\n * mode: 'prefix-no-default',\n * }\n * );\n * ```\n *\n * @param entries - Array of URL entries to include in the sitemap.\n * @param options - Sitemap generation options.\n * @returns A full XML sitemap string.\n */\nexport const generateSitemap = (\n entries: SitemapUrlEntry[],\n options: GenerateSitemapOptions\n): string => {\n const { siteUrl, xhtmlLinks = true, ...routingOptions } = options;\n\n const resolved = resolveRoutingConfig(routingOptions as RoutingOptions);\n const includeAlternates = shouldIncludeAlternates(resolved.mode, xhtmlLinks);\n\n const xmlEntries = entries.map((entry) =>\n generateSitemapUrl(entry.path, {\n ...entry,\n siteUrl,\n xhtmlLinks,\n ...routingOptions,\n })\n );\n\n const xmlns = includeAlternates\n ? '\\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"'\n : '';\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset\n xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"${xmlns}\n>\n${xmlEntries.join('\\n')}\n</urlset>`;\n};\n"],"mappings":";;;;;;;;;;;;AA2CA,MAAM,2BACJ,MACA,eACY,cAAc,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCrC,MAAa,sBACX,MACA,YACW;CACX,MAAM,EACJ,SACA,YACA,UACA,SACA,aAAa,MACb,GAAG,mBACD;CAEJ,MAAM,WAAWA,oDAAqB,eAAiC;CACvE,MAAM,UAAU,GAAG,UAAU;CAE7B,MAAM,QAA2B;EAC/B;EACA,YAAY,QAAQ;EACpB,UAAU,gBAAgB,QAAQ,cAAc;EAChD,aAAa,mBAAmB,WAAW,iBAAiB;EAC5D,aAAa,SAAY,iBAAiB,SAAS,eAAe;EACnE;
|
|
1
|
+
{"version":3,"file":"generateSitemap.cjs","names":["resolveRoutingConfig","getMultilingualUrls"],"sources":["../../../src/localization/generateSitemap.ts"],"sourcesContent":["import type { RoutingConfig } from '@intlayer/types/config';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getMultilingualUrls } from './getMultilingualUrls';\nimport { type RoutingOptions, resolveRoutingConfig } from './getPrefix';\n\nexport type SitemapUrlEntry = {\n /** The canonical path, e.g. '/dashboard' */\n path: string;\n changefreq?: string;\n priority?: number;\n /** ISO date string, e.g. '2024-01-15' */\n lastmod?: string;\n};\n\nexport type GenerateSitemapOptions = {\n /** Base site URL without trailing slash, e.g. 'https://example.com' */\n siteUrl: string;\n /**\n * Whether to include xhtml:link alternate tags for multilingual support.\n *\n * When enabled, alternate links are only generated for modes where URLs\n * differ per locale:\n * - 'prefix-no-default': included\n * - 'prefix-all': included\n * - 'search-params': included\n * - 'no-prefix': excluded (all locales share the same URL)\n *\n * @default true\n */\n xhtmlLinks?: boolean;\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n};\n\n/**\n * Returns whether xhtml:link alternate tags should be generated for the given routing mode.\n *\n * Alternates are meaningful only when locale URLs are distinct:\n * - 'no-prefix' produces identical URLs for all locales → no alternates\n * - all other modes produce distinct URLs → alternates are generated\n */\nconst shouldIncludeAlternates = (\n mode: RoutingConfig['mode'],\n xhtmlLinks: boolean\n): boolean => xhtmlLinks && mode !== 'no-prefix';\n\n/**\n * Generates a single `<url>` sitemap entry for the given path.\n *\n * Example:\n *\n * ```ts\n * generateSitemapUrl('/dashboard', {\n * siteUrl: 'https://example.com',\n * changefreq: 'weekly',\n * priority: 0.8,\n * xhtmlLinks: true,\n * locales: ['en', 'fr'],\n * defaultLocale: 'en',\n * mode: 'prefix-no-default',\n * });\n * // Returns:\n * // <url>\n * // <loc>https://example.com/dashboard</loc>\n * // <changefreq>weekly</changefreq>\n * // <priority>0.8</priority>\n * // <xhtml:link rel=\"alternate\" hrefLang=\"en\" href=\"https://example.com/dashboard\"/>\n * // <xhtml:link rel=\"alternate\" hrefLang=\"fr\" href=\"https://example.com/fr/dashboard\"/>\n * // <xhtml:link rel=\"alternate\" hrefLang=\"x-default\" href=\"https://example.com/dashboard\"/>\n * // </url>\n * ```\n *\n * @param path - The canonical path to generate the entry for.\n * @param options - Configuration options.\n * @returns A `<url>` XML string.\n */\nexport const generateSitemapUrl = (\n path: string,\n options: SitemapUrlEntry & GenerateSitemapOptions\n): string => {\n const {\n siteUrl,\n changefreq,\n priority,\n lastmod,\n xhtmlLinks = true,\n ...routingOptions\n } = options;\n\n const resolved = resolveRoutingConfig(routingOptions as RoutingOptions);\n const fullUrl = `${siteUrl}${path}`;\n\n const lines: (string | null)[] = [\n ' <url>',\n ` <loc>${fullUrl}</loc>`,\n lastmod ? ` <lastmod>${lastmod}</lastmod>` : null,\n changefreq ? ` <changefreq>${changefreq}</changefreq>` : null,\n priority !== undefined ? ` <priority>${priority}</priority>` : null,\n ];\n\n if (shouldIncludeAlternates(resolved.mode, xhtmlLinks)) {\n const alternates = getMultilingualUrls(\n path,\n routingOptions as RoutingOptions\n );\n\n for (const [lang, localePath] of Object.entries(alternates)) {\n lines.push(\n ` <xhtml:link rel=\"alternate\" hrefLang=\"${lang}\" href=\"${siteUrl}${localePath}\"/>`\n );\n }\n\n lines.push(\n ` <xhtml:link rel=\"alternate\" hrefLang=\"x-default\" href=\"${fullUrl}\"/>`\n );\n }\n\n lines.push(' </url>');\n\n return lines.filter(Boolean).join('\\n');\n};\n\n/**\n * Generates a full XML sitemap string from an array of URL entries.\n *\n * Automatically adds `xmlns:xhtml` to the `<urlset>` declaration when\n * xhtml:link alternate tags are included.\n *\n * Example:\n *\n * ```ts\n * generateSitemap(\n * [\n * { path: '/', changefreq: 'daily', priority: 1.0 },\n * { path: '/about', changefreq: 'monthly', priority: 0.5 },\n * ],\n * {\n * siteUrl: 'https://example.com',\n * xhtmlLinks: true,\n * locales: ['en', 'fr'],\n * defaultLocale: 'en',\n * mode: 'prefix-no-default',\n * }\n * );\n * ```\n *\n * @param entries - Array of URL entries to include in the sitemap.\n * @param options - Sitemap generation options.\n * @returns A full XML sitemap string.\n */\nexport const generateSitemap = (\n entries: SitemapUrlEntry[],\n options: GenerateSitemapOptions\n): string => {\n const { siteUrl, xhtmlLinks = true, ...routingOptions } = options;\n\n const resolved = resolveRoutingConfig(routingOptions as RoutingOptions);\n const includeAlternates = shouldIncludeAlternates(resolved.mode, xhtmlLinks);\n\n const xmlEntries = entries.map((entry) =>\n generateSitemapUrl(entry.path, {\n ...entry,\n siteUrl,\n xhtmlLinks,\n ...routingOptions,\n })\n );\n\n const xmlns = includeAlternates\n ? '\\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"'\n : '';\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset\n xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"${xmlns}\n>\n${xmlEntries.join('\\n')}\n</urlset>`;\n};\n"],"mappings":";;;;;;;;;;;;AA2CA,MAAM,2BACJ,MACA,eACY,cAAc,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCrC,MAAa,sBACX,MACA,YACW;CACX,MAAM,EACJ,SACA,YACA,UACA,SACA,aAAa,MACb,GAAG,mBACD;CAEJ,MAAM,WAAWA,oDAAqB,eAAiC;CACvE,MAAM,UAAU,GAAG,UAAU;CAE7B,MAAM,QAA2B;EAC/B;EACA,YAAY,QAAQ;EACpB,UAAU,gBAAgB,QAAQ,cAAc;EAChD,aAAa,mBAAmB,WAAW,iBAAiB;EAC5D,aAAa,SAAY,iBAAiB,SAAS,eAAe;EACnE;CAED,IAAI,wBAAwB,SAAS,MAAM,WAAW,EAAE;EACtD,MAAM,aAAaC,6DACjB,MACA,eACD;EAED,KAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,WAAW,EACzD,MAAM,KACJ,6CAA6C,KAAK,UAAU,UAAU,WAAW,KAClF;EAGH,MAAM,KACJ,8DAA8D,QAAQ,KACvE;;CAGH,MAAM,KAAK,WAAW;CAEtB,OAAO,MAAM,OAAO,QAAQ,CAAC,KAAK,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BzC,MAAa,mBACX,SACA,YACW;CACX,MAAM,EAAE,SAAS,aAAa,MAAM,GAAG,mBAAmB;CAG1D,MAAM,oBAAoB,wBADTD,oDAAqB,eACoB,CAAC,MAAM,WAAW;CAE5E,MAAM,aAAa,QAAQ,KAAK,UAC9B,mBAAmB,MAAM,MAAM;EAC7B,GAAG;EACH;EACA;EACA,GAAG;EACJ,CAAC,CACH;CAMD,OAAO;;uDAJO,oBACV,qDACA,GAIuD;;EAE3D,WAAW,KAAK,KAAK,CAAC"}
|