@intlayer/core 7.0.1 → 7.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/cjs/deepTransformPlugins/getSplittedContent.cjs +123 -0
  2. package/dist/cjs/deepTransformPlugins/getSplittedContent.cjs.map +1 -0
  3. package/dist/cjs/deepTransformPlugins/index.cjs +3 -0
  4. package/dist/cjs/dictionaryManipulator/getContentNodeByKeyPath.cjs +7 -4
  5. package/dist/cjs/dictionaryManipulator/getContentNodeByKeyPath.cjs.map +1 -1
  6. package/dist/cjs/dictionaryManipulator/getUnmergedDictionaryByKeyPath.cjs +1 -1
  7. package/dist/cjs/dictionaryManipulator/getUnmergedDictionaryByKeyPath.cjs.map +1 -1
  8. package/dist/cjs/dictionaryManipulator/index.cjs +1 -3
  9. package/dist/cjs/index.cjs +4 -3
  10. package/dist/cjs/localization/getMultilingualUrls.cjs +3 -3
  11. package/dist/cjs/localization/getMultilingualUrls.cjs.map +1 -1
  12. package/dist/cjs/transpiler/file/file.cjs +2 -2
  13. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs +6 -39
  14. package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs.map +1 -1
  15. package/dist/cjs/utils/parseYaml.cjs +140 -6
  16. package/dist/cjs/utils/parseYaml.cjs.map +1 -1
  17. package/dist/esm/deepTransformPlugins/getSplittedContent.mjs +120 -0
  18. package/dist/esm/deepTransformPlugins/getSplittedContent.mjs.map +1 -0
  19. package/dist/esm/deepTransformPlugins/index.mjs +2 -1
  20. package/dist/esm/dictionaryManipulator/getContentNodeByKeyPath.mjs +7 -4
  21. package/dist/esm/dictionaryManipulator/getContentNodeByKeyPath.mjs.map +1 -1
  22. package/dist/esm/dictionaryManipulator/getUnmergedDictionaryByKeyPath.mjs +1 -1
  23. package/dist/esm/dictionaryManipulator/getUnmergedDictionaryByKeyPath.mjs.map +1 -1
  24. package/dist/esm/dictionaryManipulator/index.mjs +2 -3
  25. package/dist/esm/index.mjs +3 -3
  26. package/dist/esm/localization/getMultilingualUrls.mjs +1 -1
  27. package/dist/esm/localization/getMultilingualUrls.mjs.map +1 -1
  28. package/dist/esm/transpiler/file/file.mjs +1 -1
  29. package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs +6 -39
  30. package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs.map +1 -1
  31. package/dist/esm/utils/parseYaml.mjs +140 -6
  32. package/dist/esm/utils/parseYaml.mjs.map +1 -1
  33. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +4 -4
  34. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +4 -4
  35. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +4 -4
  36. package/dist/types/deepTransformPlugins/getSplittedContent.d.ts +42 -0
  37. package/dist/types/deepTransformPlugins/getSplittedContent.d.ts.map +1 -0
  38. package/dist/types/deepTransformPlugins/index.d.ts +2 -1
  39. package/dist/types/dictionaryManipulator/getContentNodeByKeyPath.d.ts +2 -2
  40. package/dist/types/dictionaryManipulator/getContentNodeByKeyPath.d.ts.map +1 -1
  41. package/dist/types/dictionaryManipulator/getUnmergedDictionaryByKeyPath.d.ts +2 -2
  42. package/dist/types/dictionaryManipulator/index.d.ts +1 -2
  43. package/dist/types/dictionaryManipulator/orderDictionaries.d.ts +2 -2
  44. package/dist/types/index.d.ts +2 -2
  45. package/dist/types/transpiler/enumeration/enumeration.d.ts.map +1 -1
  46. package/package.json +14 -14
@@ -0,0 +1,123 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ let __intlayer_types = require("@intlayer/types");
3
+ __intlayer_types = require_rolldown_runtime.__toESM(__intlayer_types);
4
+
5
+ //#region src/deepTransformPlugins/getSplittedContent.ts
6
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7
+ const hasNodeType = (value) => isObject(value) && typeof value.nodeType === "string";
8
+ const mergeValues = (a, b) => {
9
+ if (a === void 0) return b;
10
+ if (b === void 0) return a;
11
+ if (Array.isArray(a) && Array.isArray(b)) return [...a, ...b];
12
+ if (isObject(a) && isObject(b) && !hasNodeType(a) && !hasNodeType(b)) {
13
+ const result = { ...a };
14
+ for (const key of Object.keys(b)) result[key] = mergeValues(result[key], b[key]);
15
+ return result;
16
+ }
17
+ return b;
18
+ };
19
+ const mergeSplitResults = (base, addition) => {
20
+ const result = { ...base };
21
+ result.common = mergeValues(base.common, addition.common);
22
+ const localeKeys = new Set([...Object.keys(base).filter((k) => k !== "common"), ...Object.keys(addition).filter((k) => k !== "common")]);
23
+ for (const key of localeKeys) result[key] = mergeValues(base[key], addition[key]);
24
+ return result;
25
+ };
26
+ const splitNode = (node) => {
27
+ if (isObject(node) && node?.nodeType === __intlayer_types.NodeType.Translation) {
28
+ const translations = node[__intlayer_types.NodeType.Translation];
29
+ const result = {};
30
+ for (const locale of Object.keys(translations)) {
31
+ const child = translations[locale];
32
+ const childSplit = splitNode(child);
33
+ const mergedForLocale = mergeValues(childSplit.common, void 0);
34
+ let recomposed;
35
+ for (const key of Object.keys(childSplit)) {
36
+ if (key === "common") continue;
37
+ recomposed = mergeValues(recomposed, childSplit[key]);
38
+ }
39
+ const finalLocaleNode = mergeValues(mergedForLocale, recomposed);
40
+ if (finalLocaleNode !== void 0) result[locale] = finalLocaleNode;
41
+ }
42
+ return result;
43
+ }
44
+ if (Array.isArray(node)) {
45
+ const commonArray = [];
46
+ const perLocaleArrays = {};
47
+ node.forEach((child) => {
48
+ const childSplit = splitNode(child);
49
+ if (childSplit.common !== void 0) commonArray.push(childSplit.common);
50
+ for (const key of Object.keys(childSplit)) {
51
+ if (key === "common") continue;
52
+ if (!perLocaleArrays[key]) perLocaleArrays[key] = [];
53
+ const value = childSplit[key];
54
+ if (value !== void 0) perLocaleArrays[key].push(value);
55
+ }
56
+ });
57
+ const result = {};
58
+ if (commonArray.length > 0) result.common = commonArray;
59
+ for (const key of Object.keys(perLocaleArrays)) result[key] = perLocaleArrays[key];
60
+ return result;
61
+ }
62
+ if (isObject(node) && !hasNodeType(node)) {
63
+ let accumulated = {};
64
+ for (const key of Object.keys(node)) {
65
+ const childSplit = splitNode(node[key]);
66
+ if (childSplit.common !== void 0) accumulated = mergeSplitResults(accumulated, { common: { [key]: childSplit.common } });
67
+ for (const locale of Object.keys(childSplit)) {
68
+ if (locale === "common") continue;
69
+ accumulated = mergeSplitResults(accumulated, { [locale]: { [key]: childSplit[locale] } });
70
+ }
71
+ }
72
+ return accumulated;
73
+ }
74
+ return { common: node };
75
+ };
76
+ const getSplittedContent = (content) => {
77
+ const split = splitNode(content);
78
+ const output = {};
79
+ if (split.common !== void 0) output.common = split.common;
80
+ for (const key of Object.keys(split)) {
81
+ if (key === "common") continue;
82
+ const value = split[key];
83
+ if (value !== void 0) output[key] = value;
84
+ }
85
+ return output;
86
+ };
87
+ /**
88
+ * Splits the `content` field of a Dictionary into "common" and per-locale buckets.
89
+ *
90
+ * Given a dictionary like:
91
+ * ```js
92
+ * {
93
+ * key: "my-key",
94
+ * content: {
95
+ * commonContent: "common content",
96
+ * multilingualContent: t({
97
+ * en: "english content",
98
+ * fr: "french content",
99
+ * de: "german content",
100
+ * }),
101
+ * },
102
+ * }
103
+ * ```
104
+ *
105
+ * It produces:
106
+ * ```js
107
+ * {
108
+ * common: { commonContent: "common content" },
109
+ * en: { multilingualContent: "english content" },
110
+ * fr: { multilingualContent: "french content" },
111
+ * de: { multilingualContent: "german content" },
112
+ * }
113
+ * ```
114
+ *
115
+ * @param dictionary - The input dictionary object with possible multilingual or common content.
116
+ * @returns An object mapping "common" and each locale to their corresponding content subtrees.
117
+ */
118
+ const getSplittedDictionaryContent = (dictionary) => getSplittedContent(dictionary.content);
119
+
120
+ //#endregion
121
+ exports.getSplittedContent = getSplittedContent;
122
+ exports.getSplittedDictionaryContent = getSplittedDictionaryContent;
123
+ //# sourceMappingURL=getSplittedContent.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getSplittedContent.cjs","names":["result: Record<string, any>","result: SplitResult","NodeType","recomposed: ContentNode | undefined","commonArray: any[]","perLocaleArrays: Record<string, any[]>","accumulated: SplitResult","output: Record<string, ContentNode>"],"sources":["../../../src/deepTransformPlugins/getSplittedContent.ts"],"sourcesContent":["import {\n type ContentNode,\n type DeclaredLocales,\n type Dictionary,\n NodeType,\n} from '@intlayer/types';\n\ntype SplittedContentOutput<T = ContentNode> = Record<DeclaredLocales, T> & {\n common: T;\n};\n\ntype SplitResult = Record<string, ContentNode | undefined> & {\n common?: ContentNode;\n};\n\nconst isObject = (value: unknown): value is Record<string, any> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst hasNodeType = (value: unknown): value is { nodeType: string } =>\n isObject(value) && typeof (value as any).nodeType === 'string';\n\nconst mergeValues = (\n a: ContentNode | undefined,\n b: ContentNode | undefined\n): ContentNode | undefined => {\n if (a === undefined) return b;\n if (b === undefined) return a;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n // Concatenate arrays when merging sibling results\n return [...a, ...b] as unknown as ContentNode;\n }\n\n if (isObject(a) && isObject(b) && !hasNodeType(a) && !hasNodeType(b)) {\n const result: Record<string, any> = { ...a };\n for (const key of Object.keys(b)) {\n result[key] = mergeValues(\n result[key] as unknown as ContentNode | undefined,\n (b as Record<string, any>)[key] as unknown as ContentNode | undefined\n );\n }\n return result as ContentNode;\n }\n\n // For primitives or differing structures, prefer b (more recent)\n return b;\n};\n\nconst mergeSplitResults = (\n base: SplitResult,\n addition: SplitResult\n): SplitResult => {\n const result: SplitResult = { ...base };\n\n // Merge common\n result.common = mergeValues(base.common, addition.common);\n\n // Merge each locale key present in either side\n const localeKeys = new Set<string>([\n ...Object.keys(base).filter((k) => k !== 'common'),\n ...Object.keys(addition).filter((k) => k !== 'common'),\n ]);\n\n for (const key of localeKeys) {\n // @ts-ignore: dynamic keys for locales\n result[key] = mergeValues(\n base[key] as ContentNode | undefined,\n addition[key] as ContentNode | undefined\n );\n }\n\n return result;\n};\n\nconst splitNode = (node: ContentNode): SplitResult => {\n // Translation node: allocate entirely to per-locale buckets\n if (isObject(node) && (node as any)?.nodeType === NodeType.Translation) {\n const translations = (node as any)[NodeType.Translation] as Record<\n string,\n ContentNode\n >;\n\n const result: SplitResult = {};\n for (const locale of Object.keys(translations)) {\n const child = translations[locale];\n const childSplit = splitNode(child);\n\n // The content under a translation belongs to the locale, not common\n // Merge common portion of the child (if any) into the locale as well\n const mergedForLocale = mergeValues(childSplit.common, undefined);\n\n // Compose locale content: prefer the fully rebuilt child by resolving deeper translations recursively\n // which are already split inside childSplit. We need to recompose a single node for this locale.\n // Recompose by merging all keys in childSplit except 'common' into a single node, then merge child's common.\n let recomposed: ContentNode | undefined;\n for (const key of Object.keys(childSplit)) {\n if (key === 'common') continue;\n recomposed = mergeValues(\n recomposed,\n childSplit[key] as ContentNode | undefined\n );\n }\n const finalLocaleNode = mergeValues(mergedForLocale, recomposed);\n\n if (finalLocaleNode !== undefined) {\n // @ts-ignore dynamic locale key\n result[locale] = finalLocaleNode;\n }\n }\n\n return result;\n }\n\n // Arrays: split each element and merge results index-wise\n if (Array.isArray(node)) {\n const commonArray: any[] = [];\n const perLocaleArrays: Record<string, any[]> = {};\n\n node.forEach((child) => {\n const childSplit = splitNode(child as ContentNode);\n\n if (childSplit.common !== undefined) {\n commonArray.push(childSplit.common);\n }\n\n for (const key of Object.keys(childSplit)) {\n if (key === 'common') continue;\n if (!perLocaleArrays[key]) perLocaleArrays[key] = [];\n const value = childSplit[key];\n if (value !== undefined) perLocaleArrays[key].push(value);\n }\n });\n\n const result: SplitResult = {};\n if (commonArray.length > 0)\n result.common = commonArray as unknown as ContentNode;\n for (const key of Object.keys(perLocaleArrays)) {\n // @ts-ignore dynamic locale key\n result[key] = perLocaleArrays[key] as unknown as ContentNode;\n }\n return result;\n }\n\n // Objects (non-typed): recursively split properties\n if (isObject(node) && !hasNodeType(node)) {\n let accumulated: SplitResult = {};\n\n for (const key of Object.keys(node)) {\n const childSplit = splitNode((node as any)[key] as ContentNode);\n\n // Assign property into common\n if (childSplit.common !== undefined) {\n accumulated = mergeSplitResults(accumulated, {\n common: { [key]: childSplit.common } as unknown as ContentNode,\n });\n }\n\n // Assign property into each locale bucket\n for (const locale of Object.keys(childSplit)) {\n if (locale === 'common') continue;\n accumulated = mergeSplitResults(accumulated, {\n // @ts-ignore dynamic locale key\n [locale]: { [key]: childSplit[locale] } as unknown as ContentNode,\n });\n }\n }\n\n return accumulated;\n }\n\n // Primitives or typed nodes (non-translation): entirely common\n return { common: node } as SplitResult;\n};\n\nexport const getSplittedContent = (\n content: ContentNode\n): SplittedContentOutput => {\n const split = splitNode(content);\n\n // Build final output with only defined sections\n const output: Record<string, ContentNode> = {};\n if (split.common !== undefined) {\n output.common = split.common;\n }\n for (const key of Object.keys(split)) {\n if (key === 'common') continue;\n const value = split[key] as ContentNode | undefined;\n if (value !== undefined) {\n output[key] = value;\n }\n }\n\n return output as unknown as SplittedContentOutput;\n};\n\n/**\n * Splits the `content` field of a Dictionary into \"common\" and per-locale buckets.\n *\n * Given a dictionary like:\n * ```js\n * {\n * key: \"my-key\",\n * content: {\n * commonContent: \"common content\",\n * multilingualContent: t({\n * en: \"english content\",\n * fr: \"french content\",\n * de: \"german content\",\n * }),\n * },\n * }\n * ```\n *\n * It produces:\n * ```js\n * {\n * common: { commonContent: \"common content\" },\n * en: { multilingualContent: \"english content\" },\n * fr: { multilingualContent: \"french content\" },\n * de: { multilingualContent: \"german content\" },\n * }\n * ```\n *\n * @param dictionary - The input dictionary object with possible multilingual or common content.\n * @returns An object mapping \"common\" and each locale to their corresponding content subtrees.\n */\nexport const getSplittedDictionaryContent = (\n dictionary: Dictionary\n): SplittedContentOutput<Dictionary['content']> =>\n getSplittedContent(dictionary.content);\n"],"mappings":";;;;;AAeA,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;AAEtE,MAAM,eAAe,UACnB,SAAS,MAAM,IAAI,OAAQ,MAAc,aAAa;AAExD,MAAM,eACJ,GACA,MAC4B;AAC5B,KAAI,MAAM,OAAW,QAAO;AAC5B,KAAI,MAAM,OAAW,QAAO;AAE5B,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,CAEtC,QAAO,CAAC,GAAG,GAAG,GAAG,EAAE;AAGrB,KAAI,SAAS,EAAE,IAAI,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE;EACpE,MAAMA,SAA8B,EAAE,GAAG,GAAG;AAC5C,OAAK,MAAM,OAAO,OAAO,KAAK,EAAE,CAC9B,QAAO,OAAO,YACZ,OAAO,MACN,EAA0B,KAC5B;AAEH,SAAO;;AAIT,QAAO;;AAGT,MAAM,qBACJ,MACA,aACgB;CAChB,MAAMC,SAAsB,EAAE,GAAG,MAAM;AAGvC,QAAO,SAAS,YAAY,KAAK,QAAQ,SAAS,OAAO;CAGzD,MAAM,aAAa,IAAI,IAAY,CACjC,GAAG,OAAO,KAAK,KAAK,CAAC,QAAQ,MAAM,MAAM,SAAS,EAClD,GAAG,OAAO,KAAK,SAAS,CAAC,QAAQ,MAAM,MAAM,SAAS,CACvD,CAAC;AAEF,MAAK,MAAM,OAAO,WAEhB,QAAO,OAAO,YACZ,KAAK,MACL,SAAS,KACV;AAGH,QAAO;;AAGT,MAAM,aAAa,SAAmC;AAEpD,KAAI,SAAS,KAAK,IAAK,MAAc,aAAaC,0BAAS,aAAa;EACtE,MAAM,eAAgB,KAAaA,0BAAS;EAK5C,MAAMD,SAAsB,EAAE;AAC9B,OAAK,MAAM,UAAU,OAAO,KAAK,aAAa,EAAE;GAC9C,MAAM,QAAQ,aAAa;GAC3B,MAAM,aAAa,UAAU,MAAM;GAInC,MAAM,kBAAkB,YAAY,WAAW,QAAQ,OAAU;GAKjE,IAAIE;AACJ,QAAK,MAAM,OAAO,OAAO,KAAK,WAAW,EAAE;AACzC,QAAI,QAAQ,SAAU;AACtB,iBAAa,YACX,YACA,WAAW,KACZ;;GAEH,MAAM,kBAAkB,YAAY,iBAAiB,WAAW;AAEhE,OAAI,oBAAoB,OAEtB,QAAO,UAAU;;AAIrB,SAAO;;AAIT,KAAI,MAAM,QAAQ,KAAK,EAAE;EACvB,MAAMC,cAAqB,EAAE;EAC7B,MAAMC,kBAAyC,EAAE;AAEjD,OAAK,SAAS,UAAU;GACtB,MAAM,aAAa,UAAU,MAAqB;AAElD,OAAI,WAAW,WAAW,OACxB,aAAY,KAAK,WAAW,OAAO;AAGrC,QAAK,MAAM,OAAO,OAAO,KAAK,WAAW,EAAE;AACzC,QAAI,QAAQ,SAAU;AACtB,QAAI,CAAC,gBAAgB,KAAM,iBAAgB,OAAO,EAAE;IACpD,MAAM,QAAQ,WAAW;AACzB,QAAI,UAAU,OAAW,iBAAgB,KAAK,KAAK,MAAM;;IAE3D;EAEF,MAAMJ,SAAsB,EAAE;AAC9B,MAAI,YAAY,SAAS,EACvB,QAAO,SAAS;AAClB,OAAK,MAAM,OAAO,OAAO,KAAK,gBAAgB,CAE5C,QAAO,OAAO,gBAAgB;AAEhC,SAAO;;AAIT,KAAI,SAAS,KAAK,IAAI,CAAC,YAAY,KAAK,EAAE;EACxC,IAAIK,cAA2B,EAAE;AAEjC,OAAK,MAAM,OAAO,OAAO,KAAK,KAAK,EAAE;GACnC,MAAM,aAAa,UAAW,KAAa,KAAoB;AAG/D,OAAI,WAAW,WAAW,OACxB,eAAc,kBAAkB,aAAa,EAC3C,QAAQ,GAAG,MAAM,WAAW,QAAQ,EACrC,CAAC;AAIJ,QAAK,MAAM,UAAU,OAAO,KAAK,WAAW,EAAE;AAC5C,QAAI,WAAW,SAAU;AACzB,kBAAc,kBAAkB,aAAa,GAE1C,SAAS,GAAG,MAAM,WAAW,SAAS,EACxC,CAAC;;;AAIN,SAAO;;AAIT,QAAO,EAAE,QAAQ,MAAM;;AAGzB,MAAa,sBACX,YAC0B;CAC1B,MAAM,QAAQ,UAAU,QAAQ;CAGhC,MAAMC,SAAsC,EAAE;AAC9C,KAAI,MAAM,WAAW,OACnB,QAAO,SAAS,MAAM;AAExB,MAAK,MAAM,OAAO,OAAO,KAAK,MAAM,EAAE;AACpC,MAAI,QAAQ,SAAU;EACtB,MAAM,QAAQ,MAAM;AACpB,MAAI,UAAU,OACZ,QAAO,OAAO;;AAIlB,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCT,MAAa,gCACX,eAEA,mBAAmB,WAAW,QAAQ"}
@@ -5,6 +5,7 @@ const require_deepTransformPlugins_getLocalizedContent = require('./getLocalized
5
5
  const require_deepTransformPlugins_getMaskContent = require('./getMaskContent.cjs');
6
6
  const require_deepTransformPlugins_getMissingLocalesContent = require('./getMissingLocalesContent.cjs');
7
7
  const require_deepTransformPlugins_getReplacedValuesContent = require('./getReplacedValuesContent.cjs');
8
+ const require_deepTransformPlugins_getSplittedContent = require('./getSplittedContent.cjs');
8
9
  const require_deepTransformPlugins_insertContentInDictionary = require('./insertContentInDictionary.cjs');
9
10
 
10
11
  exports.buildMaskPlugin = require_deepTransformPlugins_getMaskContent.buildMaskPlugin;
@@ -22,4 +23,6 @@ exports.getMaskContent = require_deepTransformPlugins_getMaskContent.getMaskCont
22
23
  exports.getMissingLocalesContent = require_deepTransformPlugins_getMissingLocalesContent.getMissingLocalesContent;
23
24
  exports.getPerLocaleDictionary = require_deepTransformPlugins_getLocalizedContent.getPerLocaleDictionary;
24
25
  exports.getReplacedValuesContent = require_deepTransformPlugins_getReplacedValuesContent.getReplacedValuesContent;
26
+ exports.getSplittedContent = require_deepTransformPlugins_getSplittedContent.getSplittedContent;
27
+ exports.getSplittedDictionaryContent = require_deepTransformPlugins_getSplittedContent.getSplittedDictionaryContent;
25
28
  exports.insertContentInDictionary = require_deepTransformPlugins_insertContentInDictionary.insertContentInDictionary;
@@ -3,11 +3,14 @@ let __intlayer_types = require("@intlayer/types");
3
3
  __intlayer_types = require_rolldown_runtime.__toESM(__intlayer_types);
4
4
 
5
5
  //#region src/dictionaryManipulator/getContentNodeByKeyPath.ts
6
- const getContentNodeByKeyPath = (dictionaryContent, keyPath) => {
6
+ const getContentNodeByKeyPath = (dictionaryContent, keyPath, fallbackLocale) => {
7
7
  let currentValue = structuredClone(dictionaryContent);
8
- for (const keyObj of keyPath) if (keyObj.type === __intlayer_types.NodeType.Object || keyObj.type === __intlayer_types.NodeType.Array) currentValue = currentValue?.[keyObj.key];
9
- else if (keyObj.type === __intlayer_types.NodeType.Translation || keyObj.type === __intlayer_types.NodeType.Condition || keyObj.type === __intlayer_types.NodeType.Enumeration) currentValue = currentValue?.[keyObj.type]?.[keyObj.key];
10
- else if (keyObj.type === __intlayer_types.NodeType.Markdown || keyObj.type === __intlayer_types.NodeType.Insertion || keyObj.type === __intlayer_types.NodeType.File) currentValue = currentValue?.[keyObj.type];
8
+ for (const keyObj of keyPath) {
9
+ if (fallbackLocale && currentValue?.nodeType === __intlayer_types.NodeType.Translation) currentValue = currentValue?.[__intlayer_types.NodeType.Translation]?.[fallbackLocale];
10
+ if (keyObj.type === __intlayer_types.NodeType.Object || keyObj.type === __intlayer_types.NodeType.Array) currentValue = currentValue?.[keyObj.key];
11
+ if (keyObj.type === __intlayer_types.NodeType.Translation || keyObj.type === __intlayer_types.NodeType.Condition || keyObj.type === __intlayer_types.NodeType.Enumeration) currentValue = currentValue?.[keyObj.type]?.[keyObj.key];
12
+ if (keyObj.type === __intlayer_types.NodeType.Markdown || keyObj.type === __intlayer_types.NodeType.Insertion || keyObj.type === __intlayer_types.NodeType.File) currentValue = currentValue?.[keyObj.type];
13
+ }
11
14
  return currentValue;
12
15
  };
13
16
 
@@ -1 +1 @@
1
- {"version":3,"file":"getContentNodeByKeyPath.cjs","names":["currentValue: any","NodeType"],"sources":["../../../src/dictionaryManipulator/getContentNodeByKeyPath.ts"],"sourcesContent":["import { type ContentNode, type KeyPath, NodeType } from '@intlayer/types';\n\nexport const getContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[]\n): ContentNode => {\n let currentValue: any = structuredClone(dictionaryContent);\n\n for (const keyObj of keyPath) {\n if (keyObj.type === NodeType.Object || keyObj.type === NodeType.Array) {\n currentValue = currentValue?.[keyObj.key];\n } else if (\n keyObj.type === NodeType.Translation ||\n keyObj.type === NodeType.Condition ||\n keyObj.type === NodeType.Enumeration\n ) {\n currentValue = currentValue?.[keyObj.type]?.[keyObj.key];\n } else if (\n keyObj.type === NodeType.Markdown ||\n keyObj.type === NodeType.Insertion ||\n keyObj.type === NodeType.File\n ) {\n currentValue = currentValue?.[keyObj.type];\n }\n }\n\n return currentValue as ContentNode;\n};\n"],"mappings":";;;;;AAEA,MAAa,2BACX,mBACA,YACgB;CAChB,IAAIA,eAAoB,gBAAgB,kBAAkB;AAE1D,MAAK,MAAM,UAAU,QACnB,KAAI,OAAO,SAASC,0BAAS,UAAU,OAAO,SAASA,0BAAS,MAC9D,gBAAe,eAAe,OAAO;UAErC,OAAO,SAASA,0BAAS,eACzB,OAAO,SAASA,0BAAS,aACzB,OAAO,SAASA,0BAAS,YAEzB,gBAAe,eAAe,OAAO,QAAQ,OAAO;UAEpD,OAAO,SAASA,0BAAS,YACzB,OAAO,SAASA,0BAAS,aACzB,OAAO,SAASA,0BAAS,KAEzB,gBAAe,eAAe,OAAO;AAIzC,QAAO"}
1
+ {"version":3,"file":"getContentNodeByKeyPath.cjs","names":["currentValue: any","NodeType"],"sources":["../../../src/dictionaryManipulator/getContentNodeByKeyPath.ts"],"sourcesContent":["import {\n type ContentNode,\n type KeyPath,\n type Locale,\n NodeType,\n} from '@intlayer/types';\n\nexport const getContentNodeByKeyPath = (\n dictionaryContent: ContentNode,\n keyPath: KeyPath[],\n fallbackLocale?: Locale\n): ContentNode => {\n let currentValue: any = structuredClone(dictionaryContent);\n\n for (const keyObj of keyPath) {\n // Auto-resolve translation nodes when fallbackLocale is provided\n if (fallbackLocale && currentValue?.nodeType === NodeType.Translation) {\n currentValue = currentValue?.[NodeType.Translation]?.[fallbackLocale];\n }\n\n if (keyObj.type === NodeType.Object || keyObj.type === NodeType.Array) {\n currentValue = currentValue?.[keyObj.key];\n }\n\n if (\n keyObj.type === NodeType.Translation ||\n keyObj.type === NodeType.Condition ||\n keyObj.type === NodeType.Enumeration\n ) {\n currentValue = currentValue?.[keyObj.type]?.[keyObj.key];\n }\n\n if (\n keyObj.type === NodeType.Markdown ||\n keyObj.type === NodeType.Insertion ||\n keyObj.type === NodeType.File\n ) {\n currentValue = currentValue?.[keyObj.type];\n }\n }\n\n return currentValue as ContentNode;\n};\n"],"mappings":";;;;;AAOA,MAAa,2BACX,mBACA,SACA,mBACgB;CAChB,IAAIA,eAAoB,gBAAgB,kBAAkB;AAE1D,MAAK,MAAM,UAAU,SAAS;AAE5B,MAAI,kBAAkB,cAAc,aAAaC,0BAAS,YACxD,gBAAe,eAAeA,0BAAS,eAAe;AAGxD,MAAI,OAAO,SAASA,0BAAS,UAAU,OAAO,SAASA,0BAAS,MAC9D,gBAAe,eAAe,OAAO;AAGvC,MACE,OAAO,SAASA,0BAAS,eACzB,OAAO,SAASA,0BAAS,aACzB,OAAO,SAASA,0BAAS,YAEzB,gBAAe,eAAe,OAAO,QAAQ,OAAO;AAGtD,MACE,OAAO,SAASA,0BAAS,YACzB,OAAO,SAASA,0BAAS,aACzB,OAAO,SAASA,0BAAS,KAEzB,gBAAe,eAAe,OAAO;;AAIzC,QAAO"}
@@ -11,7 +11,7 @@ const getUnmergedDictionaryByKeyPath = (dictionaryKey, keyPath, dictionariesReco
11
11
  const unmergedEntries = (dictionariesRecord ?? (0, __intlayer_unmerged_dictionaries_entry.getUnmergedDictionaries)(configuration))?.[dictionaryKey];
12
12
  if (!unmergedEntries) return null;
13
13
  const normalizedUnmergedEntries = require_dictionaryManipulator_normalizeDictionary.normalizeDictionaries(unmergedEntries, configuration);
14
- for (const dictionary of normalizedUnmergedEntries) if (require_dictionaryManipulator_getContentNodeByKeyPath.getContentNodeByKeyPath(dictionary.content, keyPath)) return dictionary;
14
+ for (const dictionary of normalizedUnmergedEntries) if (require_dictionaryManipulator_getContentNodeByKeyPath.getContentNodeByKeyPath(dictionary.content, keyPath)) return unmergedEntries.find((entry) => entry.localId === dictionary.localId);
15
15
  for (const dictionary of unmergedEntries) if (require_dictionaryManipulator_getContentNodeByKeyPath.getContentNodeByKeyPath(dictionary.content, keyPath)) return dictionary;
16
16
  };
17
17
 
@@ -1 +1 @@
1
- {"version":3,"file":"getUnmergedDictionaryByKeyPath.cjs","names":["intlayerConfiguration","normalizeDictionaries","getContentNodeByKeyPath"],"sources":["../../../src/dictionaryManipulator/getUnmergedDictionaryByKeyPath.ts"],"sourcesContent":["import intlayerConfiguration from '@intlayer/config/built';\nimport type { IntlayerConfig, KeyPath } from '@intlayer/types';\nimport {\n getUnmergedDictionaries,\n type UnmergedDictionaries,\n} from '@intlayer/unmerged-dictionaries-entry';\nimport { getContentNodeByKeyPath } from './getContentNodeByKeyPath';\nimport { normalizeDictionaries } from './normalizeDictionary';\n\nexport const getUnmergedDictionaryByKeyPath = (\n dictionaryKey: string,\n keyPath: KeyPath[],\n dictionariesRecord?: UnmergedDictionaries,\n configuration: IntlayerConfig = intlayerConfiguration\n) => {\n const unmergedEntries = (dictionariesRecord ??\n getUnmergedDictionaries(configuration))?.[dictionaryKey];\n\n if (!unmergedEntries) {\n return null;\n }\n\n const normalizedUnmergedEntries = normalizeDictionaries(\n unmergedEntries,\n configuration\n );\n\n for (const dictionary of normalizedUnmergedEntries) {\n const content = getContentNodeByKeyPath(dictionary.content, keyPath);\n\n if (content) {\n return dictionary;\n }\n }\n\n for (const dictionary of unmergedEntries) {\n const content = getContentNodeByKeyPath(dictionary.content, keyPath);\n\n if (content) {\n return dictionary;\n }\n }\n};\n"],"mappings":";;;;;;;;;AASA,MAAa,kCACX,eACA,SACA,oBACA,gBAAgCA,oCAC7B;CACH,MAAM,mBAAmB,0FACC,cAAc,IAAI;AAE5C,KAAI,CAAC,gBACH,QAAO;CAGT,MAAM,4BAA4BC,wEAChC,iBACA,cACD;AAED,MAAK,MAAM,cAAc,0BAGvB,KAFgBC,8EAAwB,WAAW,SAAS,QAAQ,CAGlE,QAAO;AAIX,MAAK,MAAM,cAAc,gBAGvB,KAFgBA,8EAAwB,WAAW,SAAS,QAAQ,CAGlE,QAAO"}
1
+ {"version":3,"file":"getUnmergedDictionaryByKeyPath.cjs","names":["intlayerConfiguration","normalizeDictionaries","getContentNodeByKeyPath"],"sources":["../../../src/dictionaryManipulator/getUnmergedDictionaryByKeyPath.ts"],"sourcesContent":["import intlayerConfiguration from '@intlayer/config/built';\nimport type { IntlayerConfig, KeyPath } from '@intlayer/types';\nimport {\n getUnmergedDictionaries,\n type UnmergedDictionaries,\n} from '@intlayer/unmerged-dictionaries-entry';\nimport { getContentNodeByKeyPath } from './getContentNodeByKeyPath';\nimport { normalizeDictionaries } from './normalizeDictionary';\n\nexport const getUnmergedDictionaryByKeyPath = (\n dictionaryKey: string,\n keyPath: KeyPath[],\n dictionariesRecord?: UnmergedDictionaries,\n configuration: IntlayerConfig = intlayerConfiguration\n) => {\n const unmergedEntries = (dictionariesRecord ??\n getUnmergedDictionaries(configuration))?.[dictionaryKey];\n\n if (!unmergedEntries) {\n return null;\n }\n\n // First search for the dictionary in the normalized dictionaries as it's what see the client editor selector\n // Then return the original unmerged dictionary if not found in the normalized dictionaries\n\n const normalizedUnmergedEntries = normalizeDictionaries(\n unmergedEntries,\n configuration\n );\n\n for (const dictionary of normalizedUnmergedEntries) {\n const content = getContentNodeByKeyPath(dictionary.content, keyPath);\n\n if (content) {\n return unmergedEntries.find(\n (entry) => entry.localId === dictionary.localId\n );\n }\n }\n\n // If not found in the normalized dictionaries, search in the original unmerged dictionaries directly\n\n for (const dictionary of unmergedEntries) {\n const content = getContentNodeByKeyPath(dictionary.content, keyPath);\n\n if (content) {\n return dictionary;\n }\n }\n};\n"],"mappings":";;;;;;;;;AASA,MAAa,kCACX,eACA,SACA,oBACA,gBAAgCA,oCAC7B;CACH,MAAM,mBAAmB,0FACC,cAAc,IAAI;AAE5C,KAAI,CAAC,gBACH,QAAO;CAMT,MAAM,4BAA4BC,wEAChC,iBACA,cACD;AAED,MAAK,MAAM,cAAc,0BAGvB,KAFgBC,8EAAwB,WAAW,SAAS,QAAQ,CAGlE,QAAO,gBAAgB,MACpB,UAAU,MAAM,YAAY,WAAW,QACzC;AAML,MAAK,MAAM,cAAc,gBAGvB,KAFgBA,8EAAwB,WAAW,SAAS,QAAQ,CAGlE,QAAO"}
@@ -4,10 +4,9 @@ const require_dictionaryManipulator_getDefaultNode = require('./getDefaultNode.c
4
4
  const require_dictionaryManipulator_getEmptyNode = require('./getEmptyNode.cjs');
5
5
  const require_dictionaryManipulator_getNodeChildren = require('./getNodeChildren.cjs');
6
6
  const require_dictionaryManipulator_getNodeType = require('./getNodeType.cjs');
7
+ const require_dictionaryManipulator_mergeDictionaries = require('./mergeDictionaries.cjs');
7
8
  const require_dictionaryManipulator_orderDictionaries = require('./orderDictionaries.cjs');
8
9
  const require_dictionaryManipulator_normalizeDictionary = require('./normalizeDictionary.cjs');
9
- const require_dictionaryManipulator_getUnmergedDictionaryByKeyPath = require('./getUnmergedDictionaryByKeyPath.cjs');
10
- const require_dictionaryManipulator_mergeDictionaries = require('./mergeDictionaries.cjs');
11
10
  const require_dictionaryManipulator_removeContentNodeByKeyPath = require('./removeContentNodeByKeyPath.cjs');
12
11
  const require_dictionaryManipulator_renameContentNodeByKeyPath = require('./renameContentNodeByKeyPath.cjs');
13
12
  const require_dictionaryManipulator_updateNodeChildren = require('./updateNodeChildren.cjs');
@@ -18,7 +17,6 @@ exports.getDefaultNode = require_dictionaryManipulator_getDefaultNode.getDefault
18
17
  exports.getEmptyNode = require_dictionaryManipulator_getEmptyNode.getEmptyNode;
19
18
  exports.getNodeChildren = require_dictionaryManipulator_getNodeChildren.getNodeChildren;
20
19
  exports.getNodeType = require_dictionaryManipulator_getNodeType.getNodeType;
21
- exports.getUnmergedDictionaryByKeyPath = require_dictionaryManipulator_getUnmergedDictionaryByKeyPath.getUnmergedDictionaryByKeyPath;
22
20
  exports.mergeDictionaries = require_dictionaryManipulator_mergeDictionaries.mergeDictionaries;
23
21
  exports.normalizeDictionaries = require_dictionaryManipulator_normalizeDictionary.normalizeDictionaries;
24
22
  exports.normalizeDictionary = require_dictionaryManipulator_normalizeDictionary.normalizeDictionary;
@@ -25,6 +25,7 @@ const require_deepTransformPlugins_getLocalizedContent = require('./deepTransfor
25
25
  const require_deepTransformPlugins_getMaskContent = require('./deepTransformPlugins/getMaskContent.cjs');
26
26
  const require_deepTransformPlugins_getMissingLocalesContent = require('./deepTransformPlugins/getMissingLocalesContent.cjs');
27
27
  const require_deepTransformPlugins_getReplacedValuesContent = require('./deepTransformPlugins/getReplacedValuesContent.cjs');
28
+ const require_deepTransformPlugins_getSplittedContent = require('./deepTransformPlugins/getSplittedContent.cjs');
28
29
  const require_deepTransformPlugins_insertContentInDictionary = require('./deepTransformPlugins/insertContentInDictionary.cjs');
29
30
  const require_dictionaryManipulator_editDictionaryByKeyPath = require('./dictionaryManipulator/editDictionaryByKeyPath.cjs');
30
31
  const require_dictionaryManipulator_getContentNodeByKeyPath = require('./dictionaryManipulator/getContentNodeByKeyPath.cjs');
@@ -33,10 +34,9 @@ const require_dictionaryManipulator_getEmptyNode = require('./dictionaryManipula
33
34
  const require_dictionaryManipulator_getNodeChildren = require('./dictionaryManipulator/getNodeChildren.cjs');
34
35
  const require_utils_isValidReactElement = require('./utils/isValidReactElement.cjs');
35
36
  const require_dictionaryManipulator_getNodeType = require('./dictionaryManipulator/getNodeType.cjs');
37
+ const require_dictionaryManipulator_mergeDictionaries = require('./dictionaryManipulator/mergeDictionaries.cjs');
36
38
  const require_dictionaryManipulator_orderDictionaries = require('./dictionaryManipulator/orderDictionaries.cjs');
37
39
  const require_dictionaryManipulator_normalizeDictionary = require('./dictionaryManipulator/normalizeDictionary.cjs');
38
- const require_dictionaryManipulator_getUnmergedDictionaryByKeyPath = require('./dictionaryManipulator/getUnmergedDictionaryByKeyPath.cjs');
39
- const require_dictionaryManipulator_mergeDictionaries = require('./dictionaryManipulator/mergeDictionaries.cjs');
40
40
  const require_dictionaryManipulator_removeContentNodeByKeyPath = require('./dictionaryManipulator/removeContentNodeByKeyPath.cjs');
41
41
  const require_dictionaryManipulator_renameContentNodeByKeyPath = require('./dictionaryManipulator/renameContentNodeByKeyPath.cjs');
42
42
  const require_dictionaryManipulator_updateNodeChildren = require('./dictionaryManipulator/updateNodeChildren.cjs');
@@ -119,9 +119,10 @@ exports.getNodeType = require_dictionaryManipulator_getNodeType.getNodeType;
119
119
  exports.getPathWithoutLocale = require_localization_getPathWithoutLocale.getPathWithoutLocale;
120
120
  exports.getPerLocaleDictionary = require_deepTransformPlugins_getLocalizedContent.getPerLocaleDictionary;
121
121
  exports.getReplacedValuesContent = require_deepTransformPlugins_getReplacedValuesContent.getReplacedValuesContent;
122
+ exports.getSplittedContent = require_deepTransformPlugins_getSplittedContent.getSplittedContent;
123
+ exports.getSplittedDictionaryContent = require_deepTransformPlugins_getSplittedContent.getSplittedDictionaryContent;
122
124
  exports.getStorageAttributes = require_getStorageAttributes.getStorageAttributes;
123
125
  exports.getTranslation = require_interpreter_getTranslation.getTranslation;
124
- exports.getUnmergedDictionaryByKeyPath = require_dictionaryManipulator_getUnmergedDictionaryByKeyPath.getUnmergedDictionaryByKeyPath;
125
126
  exports.insert = require_transpiler_insertion_insertion.insert;
126
127
  exports.insertContentInDictionary = require_deepTransformPlugins_insertContentInDictionary.insertContentInDictionary;
127
128
  exports.insertionPlugin = require_interpreter_getContent_plugins.insertionPlugin;
@@ -1,10 +1,10 @@
1
1
  const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
2
  const require_utils_checkIsURLAbsolute = require('../utils/checkIsURLAbsolute.cjs');
3
3
  const require_localization_getPathWithoutLocale = require('./getPathWithoutLocale.cjs');
4
+ let __intlayer_config_client = require("@intlayer/config/client");
5
+ __intlayer_config_client = require_rolldown_runtime.__toESM(__intlayer_config_client);
4
6
  let __intlayer_config_built = require("@intlayer/config/built");
5
7
  __intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
6
- let __intlayer_config = require("@intlayer/config");
7
- __intlayer_config = require_rolldown_runtime.__toESM(__intlayer_config);
8
8
 
9
9
  //#region src/localization/getMultilingualUrls.ts
10
10
  /**
@@ -47,7 +47,7 @@ const getMultilingualUrls = (url, locales = __intlayer_config_built.default?.int
47
47
  let pathname = parsedUrl.pathname;
48
48
  if (!pathname.startsWith("/")) pathname = `/${pathname}`;
49
49
  const baseUrl = isAbsoluteUrl ? `${parsedUrl.protocol}//${parsedUrl.host}` : "";
50
- const routingMode = mode ?? __intlayer_config.DefaultValues.Routing.ROUTING_MODE;
50
+ const routingMode = mode ?? __intlayer_config_client.DefaultValues.Routing.ROUTING_MODE;
51
51
  return (locales ?? []).reduce((acc, locale) => {
52
52
  const isDefaultLocale = locale?.toString() === defaultLocale?.toString();
53
53
  let localizedUrl;
@@ -1 +1 @@
1
- {"version":3,"file":"getMultilingualUrls.cjs","names":["configuration","getPathWithoutLocale","checkIsURLAbsolute","DefaultValues","localizedUrl: string"],"sources":["../../../src/localization/getMultilingualUrls.ts"],"sourcesContent":["import { DefaultValues } from '@intlayer/config';\nimport configuration from '@intlayer/config/built';\nimport type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\n\n/**\n * Generates multilingual URLs by prefixing the given URL with each supported locale\n * or adding search parameters based on the routing mode.\n * Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'prefix-no-default')\n * // Returns { en: '/dashboard', fr: '/fr/dashboard' }\n *\n * // prefix-all mode\n * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'prefix-all')\n * // Returns { en: '/en/dashboard', fr: '/fr/dashboard' }\n *\n * // search-params mode\n * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'search-params')\n * // Returns { en: '/dashboard?locale=en', fr: '/dashboard?locale=fr' }\n *\n * // no-prefix mode\n * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'no-prefix')\n * // Returns { en: '/dashboard', fr: '/dashboard' }\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param locales - Optional array of supported locales. Defaults to configured locales.\n * @param defaultLocale - The default locale. Defaults to configured default locale.\n * @param mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object mapping each locale to its corresponding multilingual URL.\n */\nexport const getMultilingualUrls = (\n url: string,\n locales: LocalesValues[] | undefined = configuration?.internationalization\n ?.locales,\n defaultLocale: LocalesValues | undefined = configuration?.internationalization\n ?.defaultLocale,\n mode:\n | 'prefix-no-default'\n | 'prefix-all'\n | 'no-prefix'\n | 'search-params'\n | undefined = configuration?.routing?.mode\n): StrictModeLocaleMap<string> => {\n // Remove any existing locale segment from the URL\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n\n // Determine if the original URL is absolute (includes protocol)\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n\n // Initialize a URL object if the URL is absolute\n // For relative URLs, use a dummy base to leverage the URL API\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n // Extract the pathname from the parsed URL\n let pathname = parsedUrl.pathname;\n\n // Ensure the pathname starts with a '/'\n if (!pathname.startsWith('/')) {\n pathname = `/${pathname}`;\n }\n\n // Prepare the base URL (protocol + host) if it's absolute\n const baseUrl = isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n\n // Default mode to 'prefix-no-default' if not provided\n const routingMode = mode ?? DefaultValues.Routing.ROUTING_MODE;\n\n // Generate multilingual URLs by iterating over each locale\n const multilingualUrls = (locales ?? []).reduce<StrictModeLocaleMap<string>>(\n (acc, locale) => {\n // Determine if the current locale is the default locale\n const isDefaultLocale = locale?.toString() === defaultLocale?.toString();\n\n let localizedUrl: string;\n\n if (routingMode === 'search-params') {\n // Use search parameters for locale handling\n const searchParams = new URLSearchParams(parsedUrl.search);\n searchParams.set('locale', locale.toString());\n\n const queryString = searchParams.toString();\n const pathWithQuery = queryString\n ? `${pathname}?${queryString}`\n : pathname;\n\n localizedUrl = isAbsoluteUrl\n ? `${baseUrl}${pathWithQuery}${parsedUrl.hash}`\n : `${pathWithQuery}${parsedUrl.hash}`;\n } else if (routingMode === 'no-prefix') {\n // No locale prefixing\n localizedUrl = isAbsoluteUrl\n ? `${baseUrl}${pathname}${parsedUrl.search}${parsedUrl.hash}`\n : `${pathname}${parsedUrl.search}${parsedUrl.hash}`;\n } else {\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n routingMode === 'prefix-all' ||\n (routingMode === 'prefix-no-default' && !isDefaultLocale);\n\n // Construct the new pathname with or without the locale prefix\n let localizedPath = shouldPrefix ? `/${locale}${pathname}` : pathname;\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n // Combine with the base URL if the original URL was absolute\n localizedUrl = isAbsoluteUrl\n ? `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`\n : `${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n }\n\n // Assign the constructed URL to the corresponding locale key\n acc[locale as unknown as keyof typeof acc] = localizedUrl;\n\n return acc;\n },\n {} as StrictModeLocaleMap<string>\n );\n\n return multilingualUrls;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAa,uBACX,KACA,UAAuCA,iCAAe,sBAClD,SACJ,gBAA2CA,iCAAe,sBACtD,eACJ,OAKgBA,iCAAe,SAAS,SACR;CAEhC,MAAM,mBAAmBC,+DAAqB,KAAK,QAAQ;CAG3D,MAAM,gBAAgBC,oDAAmB,iBAAiB;CAI1D,MAAM,YAAY,gBACd,IAAI,IAAI,iBAAiB,GACzB,IAAI,IAAI,kBAAkB,qBAAqB;CAGnD,IAAI,WAAW,UAAU;AAGzB,KAAI,CAAC,SAAS,WAAW,IAAI,CAC3B,YAAW,IAAI;CAIjB,MAAM,UAAU,gBACZ,GAAG,UAAU,SAAS,IAAI,UAAU,SACpC;CAGJ,MAAM,cAAc,QAAQC,gCAAc,QAAQ;AAuDlD,SApD0B,WAAW,EAAE,EAAE,QACtC,KAAK,WAAW;EAEf,MAAM,kBAAkB,QAAQ,UAAU,KAAK,eAAe,UAAU;EAExE,IAAIC;AAEJ,MAAI,gBAAgB,iBAAiB;GAEnC,MAAM,eAAe,IAAI,gBAAgB,UAAU,OAAO;AAC1D,gBAAa,IAAI,UAAU,OAAO,UAAU,CAAC;GAE7C,MAAM,cAAc,aAAa,UAAU;GAC3C,MAAM,gBAAgB,cAClB,GAAG,SAAS,GAAG,gBACf;AAEJ,kBAAe,gBACX,GAAG,UAAU,gBAAgB,UAAU,SACvC,GAAG,gBAAgB,UAAU;aACxB,gBAAgB,YAEzB,gBAAe,gBACX,GAAG,UAAU,WAAW,UAAU,SAAS,UAAU,SACrD,GAAG,WAAW,UAAU,SAAS,UAAU;OAC1C;GAOL,IAAI,gBAJF,gBAAgB,gBACf,gBAAgB,uBAAuB,CAAC,kBAGR,IAAI,SAAS,aAAa;AAE7D,OAAI,cAAc,SAAS,KAAK,cAAc,SAAS,IAAI,CACzD,iBAAgB,cAAc,MAAM,GAAG,GAAG;AAI5C,kBAAe,gBACX,GAAG,UAAU,gBAAgB,UAAU,SAAS,UAAU,SAC1D,GAAG,gBAAgB,UAAU,SAAS,UAAU;;AAItD,MAAI,UAAyC;AAE7C,SAAO;IAET,EAAE,CACH"}
1
+ {"version":3,"file":"getMultilingualUrls.cjs","names":["configuration","getPathWithoutLocale","checkIsURLAbsolute","DefaultValues","localizedUrl: string"],"sources":["../../../src/localization/getMultilingualUrls.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\n\n/**\n * Generates multilingual URLs by prefixing the given URL with each supported locale\n * or adding search parameters based on the routing mode.\n * Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'prefix-no-default')\n * // Returns { en: '/dashboard', fr: '/fr/dashboard' }\n *\n * // prefix-all mode\n * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'prefix-all')\n * // Returns { en: '/en/dashboard', fr: '/fr/dashboard' }\n *\n * // search-params mode\n * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'search-params')\n * // Returns { en: '/dashboard?locale=en', fr: '/dashboard?locale=fr' }\n *\n * // no-prefix mode\n * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'no-prefix')\n * // Returns { en: '/dashboard', fr: '/dashboard' }\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param locales - Optional array of supported locales. Defaults to configured locales.\n * @param defaultLocale - The default locale. Defaults to configured default locale.\n * @param mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object mapping each locale to its corresponding multilingual URL.\n */\nexport const getMultilingualUrls = (\n url: string,\n locales: LocalesValues[] | undefined = configuration?.internationalization\n ?.locales,\n defaultLocale: LocalesValues | undefined = configuration?.internationalization\n ?.defaultLocale,\n mode:\n | 'prefix-no-default'\n | 'prefix-all'\n | 'no-prefix'\n | 'search-params'\n | undefined = configuration?.routing?.mode\n): StrictModeLocaleMap<string> => {\n // Remove any existing locale segment from the URL\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n\n // Determine if the original URL is absolute (includes protocol)\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n\n // Initialize a URL object if the URL is absolute\n // For relative URLs, use a dummy base to leverage the URL API\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n // Extract the pathname from the parsed URL\n let pathname = parsedUrl.pathname;\n\n // Ensure the pathname starts with a '/'\n if (!pathname.startsWith('/')) {\n pathname = `/${pathname}`;\n }\n\n // Prepare the base URL (protocol + host) if it's absolute\n const baseUrl = isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n\n // Default mode to 'prefix-no-default' if not provided\n const routingMode = mode ?? DefaultValues.Routing.ROUTING_MODE;\n\n // Generate multilingual URLs by iterating over each locale\n const multilingualUrls = (locales ?? []).reduce<StrictModeLocaleMap<string>>(\n (acc, locale) => {\n // Determine if the current locale is the default locale\n const isDefaultLocale = locale?.toString() === defaultLocale?.toString();\n\n let localizedUrl: string;\n\n if (routingMode === 'search-params') {\n // Use search parameters for locale handling\n const searchParams = new URLSearchParams(parsedUrl.search);\n searchParams.set('locale', locale.toString());\n\n const queryString = searchParams.toString();\n const pathWithQuery = queryString\n ? `${pathname}?${queryString}`\n : pathname;\n\n localizedUrl = isAbsoluteUrl\n ? `${baseUrl}${pathWithQuery}${parsedUrl.hash}`\n : `${pathWithQuery}${parsedUrl.hash}`;\n } else if (routingMode === 'no-prefix') {\n // No locale prefixing\n localizedUrl = isAbsoluteUrl\n ? `${baseUrl}${pathname}${parsedUrl.search}${parsedUrl.hash}`\n : `${pathname}${parsedUrl.search}${parsedUrl.hash}`;\n } else {\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n routingMode === 'prefix-all' ||\n (routingMode === 'prefix-no-default' && !isDefaultLocale);\n\n // Construct the new pathname with or without the locale prefix\n let localizedPath = shouldPrefix ? `/${locale}${pathname}` : pathname;\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n // Combine with the base URL if the original URL was absolute\n localizedUrl = isAbsoluteUrl\n ? `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`\n : `${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n }\n\n // Assign the constructed URL to the corresponding locale key\n acc[locale as unknown as keyof typeof acc] = localizedUrl;\n\n return acc;\n },\n {} as StrictModeLocaleMap<string>\n );\n\n return multilingualUrls;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAa,uBACX,KACA,UAAuCA,iCAAe,sBAClD,SACJ,gBAA2CA,iCAAe,sBACtD,eACJ,OAKgBA,iCAAe,SAAS,SACR;CAEhC,MAAM,mBAAmBC,+DAAqB,KAAK,QAAQ;CAG3D,MAAM,gBAAgBC,oDAAmB,iBAAiB;CAI1D,MAAM,YAAY,gBACd,IAAI,IAAI,iBAAiB,GACzB,IAAI,IAAI,kBAAkB,qBAAqB;CAGnD,IAAI,WAAW,UAAU;AAGzB,KAAI,CAAC,SAAS,WAAW,IAAI,CAC3B,YAAW,IAAI;CAIjB,MAAM,UAAU,gBACZ,GAAG,UAAU,SAAS,IAAI,UAAU,SACpC;CAGJ,MAAM,cAAc,QAAQC,uCAAc,QAAQ;AAuDlD,SApD0B,WAAW,EAAE,EAAE,QACtC,KAAK,WAAW;EAEf,MAAM,kBAAkB,QAAQ,UAAU,KAAK,eAAe,UAAU;EAExE,IAAIC;AAEJ,MAAI,gBAAgB,iBAAiB;GAEnC,MAAM,eAAe,IAAI,gBAAgB,UAAU,OAAO;AAC1D,gBAAa,IAAI,UAAU,OAAO,UAAU,CAAC;GAE7C,MAAM,cAAc,aAAa,UAAU;GAC3C,MAAM,gBAAgB,cAClB,GAAG,SAAS,GAAG,gBACf;AAEJ,kBAAe,gBACX,GAAG,UAAU,gBAAgB,UAAU,SACvC,GAAG,gBAAgB,UAAU;aACxB,gBAAgB,YAEzB,gBAAe,gBACX,GAAG,UAAU,WAAW,UAAU,SAAS,UAAU,SACrD,GAAG,WAAW,UAAU,SAAS,UAAU;OAC1C;GAOL,IAAI,gBAJF,gBAAgB,gBACf,gBAAgB,uBAAuB,CAAC,kBAGR,IAAI,SAAS,aAAa;AAE7D,OAAI,cAAc,SAAS,KAAK,cAAc,SAAS,IAAI,CACzD,iBAAgB,cAAc,MAAM,GAAG,GAAG;AAI5C,kBAAe,gBACX,GAAG,UAAU,gBAAgB,UAAU,SAAS,UAAU,SAC1D,GAAG,gBAAgB,UAAU,SAAS,UAAU;;AAItD,MAAI,UAAyC;AAE7C,SAAO;IAET,EAAE,CACH"}
@@ -1,12 +1,12 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
2
  let __intlayer_types = require("@intlayer/types");
3
3
  __intlayer_types = require_rolldown_runtime.__toESM(__intlayer_types);
4
- let __intlayer_config = require("@intlayer/config");
5
- __intlayer_config = require_rolldown_runtime.__toESM(__intlayer_config);
6
4
  let node_fs = require("node:fs");
7
5
  node_fs = require_rolldown_runtime.__toESM(node_fs);
8
6
  let node_path = require("node:path");
9
7
  node_path = require_rolldown_runtime.__toESM(node_path);
8
+ let __intlayer_config = require("@intlayer/config");
9
+ __intlayer_config = require_rolldown_runtime.__toESM(__intlayer_config);
10
10
 
11
11
  //#region src/transpiler/file/file.ts
12
12
  const fileContent = (path, callerDir, baseDir) => {
@@ -6,46 +6,13 @@ const getMarkdownMetadata = (markdown) => {
6
6
  const lines = markdown.split(/\r?\n/);
7
7
  const firstNonEmptyLine = lines.find((line) => line.trim() !== "");
8
8
  if (!firstNonEmptyLine || firstNonEmptyLine.trim() !== "---") return {};
9
- const metadata = {};
10
- let inMetadataBlock = false;
11
- let currentKey = null;
12
- let currentArrayItems = [];
13
- for (let i = 0; i < lines.length; i++) {
14
- const line = lines[i];
15
- if (line.trim() === "---") if (!inMetadataBlock) {
16
- inMetadataBlock = true;
17
- continue;
18
- } else {
19
- if (currentKey && currentArrayItems.length > 0) metadata[currentKey] = currentArrayItems;
20
- break;
21
- }
22
- if (inMetadataBlock) {
23
- const arrayItemMatch = line.match(/^\s*-\s+(.+)$/);
24
- if (arrayItemMatch && currentKey) {
25
- currentArrayItems.push(arrayItemMatch[1].trim());
26
- continue;
27
- }
28
- if (currentKey && currentArrayItems.length > 0) {
29
- metadata[currentKey] = currentArrayItems;
30
- currentKey = null;
31
- currentArrayItems = [];
32
- }
33
- const match = line.match(/^([^:]+)\s*:\s*(.*)$/);
34
- if (match) {
35
- const key = match[1].trim();
36
- const value = match[2].trim();
37
- if (value === "") {
38
- currentKey = key;
39
- currentArrayItems = [];
40
- } else try {
41
- metadata[key] = require_utils_parseYaml.parseYaml(value);
42
- } catch (_e) {
43
- metadata[key] = value;
44
- }
45
- }
46
- }
9
+ let metadataEndIndex = -1;
10
+ for (let i = 1; i < lines.length; i++) if (lines[i].trim() === "---") {
11
+ metadataEndIndex = i;
12
+ break;
47
13
  }
48
- return metadata;
14
+ if (metadataEndIndex === -1) return {};
15
+ return require_utils_parseYaml.parseYaml(lines.slice(1, metadataEndIndex).join("\n")) ?? {};
49
16
  } catch (_e) {
50
17
  return {};
51
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getMarkdownMetadata.cjs","names":["metadata: T","currentKey: string | null","currentArrayItems: string[]","parseYaml"],"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["import { parseYaml } from '../../utils/parseYaml';\n\nexport const getMarkdownMetadata = <T extends Record<string, any>>(\n markdown: string\n): T => {\n try {\n const lines = markdown.split(/\\r?\\n/);\n\n // Check if the very first non-empty line is the metadata start delimiter.\n const firstNonEmptyLine = lines.find((line) => line.trim() !== '');\n\n if (!firstNonEmptyLine || firstNonEmptyLine.trim() !== '---') {\n const result: T = {} as T;\n return result;\n }\n\n const metadata: T = {} as T;\n let inMetadataBlock = false;\n let currentKey: string | null = null;\n let currentArrayItems: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmedLine = line.trim();\n\n // Toggle metadata block on encountering the delimiter.\n if (trimmedLine === '---') {\n if (!inMetadataBlock) {\n // Begin metadata block.\n inMetadataBlock = true;\n continue;\n } else {\n // End of metadata block; finalize any pending array and stop processing.\n if (currentKey && currentArrayItems.length > 0) {\n (metadata as Record<string, any>)[currentKey] = currentArrayItems;\n }\n break;\n }\n }\n\n // If we're inside the metadata block, parse key: value pairs.\n if (inMetadataBlock) {\n // Check if this line is an array item (starts with - )\n const arrayItemMatch = line.match(/^\\s*-\\s+(.+)$/);\n if (arrayItemMatch && currentKey) {\n // This is an array item for the current key\n currentArrayItems.push(arrayItemMatch[1].trim());\n continue;\n }\n\n // If we have a pending array from a previous key, save it\n if (currentKey && currentArrayItems.length > 0) {\n (metadata as Record<string, any>)[currentKey] = currentArrayItems;\n currentKey = null;\n currentArrayItems = [];\n }\n\n // Check for key: value pairs\n const match = line.match(/^([^:]+)\\s*:\\s*(.*)$/);\n if (match) {\n const key = match[1].trim();\n const value = match[2].trim();\n\n if (value === '') {\n // This might be the start of a multi-line structure (like an array)\n currentKey = key;\n currentArrayItems = [];\n } else {\n try {\n (metadata as Record<string, any>)[key] = parseYaml(value);\n } catch (_e) {\n (metadata as Record<string, any>)[key] = value;\n }\n }\n }\n }\n }\n\n return metadata;\n } catch (_e) {\n const result: T = {} as T;\n return result;\n }\n};\n"],"mappings":";;;AAEA,MAAa,uBACX,aACM;AACN,KAAI;EACF,MAAM,QAAQ,SAAS,MAAM,QAAQ;EAGrC,MAAM,oBAAoB,MAAM,MAAM,SAAS,KAAK,MAAM,KAAK,GAAG;AAElE,MAAI,CAAC,qBAAqB,kBAAkB,MAAM,KAAK,MAErD,QADkB,EAAE;EAItB,MAAMA,WAAc,EAAE;EACtB,IAAI,kBAAkB;EACtB,IAAIC,aAA4B;EAChC,IAAIC,oBAA8B,EAAE;AAEpC,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,OAAO,MAAM;AAInB,OAHoB,KAAK,MAAM,KAGX,MAClB,KAAI,CAAC,iBAAiB;AAEpB,sBAAkB;AAClB;UACK;AAEL,QAAI,cAAc,kBAAkB,SAAS,EAC3C,CAAC,SAAiC,cAAc;AAElD;;AAKJ,OAAI,iBAAiB;IAEnB,MAAM,iBAAiB,KAAK,MAAM,gBAAgB;AAClD,QAAI,kBAAkB,YAAY;AAEhC,uBAAkB,KAAK,eAAe,GAAG,MAAM,CAAC;AAChD;;AAIF,QAAI,cAAc,kBAAkB,SAAS,GAAG;AAC9C,KAAC,SAAiC,cAAc;AAChD,kBAAa;AACb,yBAAoB,EAAE;;IAIxB,MAAM,QAAQ,KAAK,MAAM,uBAAuB;AAChD,QAAI,OAAO;KACT,MAAM,MAAM,MAAM,GAAG,MAAM;KAC3B,MAAM,QAAQ,MAAM,GAAG,MAAM;AAE7B,SAAI,UAAU,IAAI;AAEhB,mBAAa;AACb,0BAAoB,EAAE;WAEtB,KAAI;AACF,MAAC,SAAiC,OAAOC,kCAAU,MAAM;cAClD,IAAI;AACX,MAAC,SAAiC,OAAO;;;;;AAOnD,SAAO;UACA,IAAI;AAEX,SADkB,EAAE"}
1
+ {"version":3,"file":"getMarkdownMetadata.cjs","names":["parseYaml"],"sources":["../../../../src/transpiler/markdown/getMarkdownMetadata.ts"],"sourcesContent":["import { parseYaml } from '../../utils/parseYaml';\n\nexport const getMarkdownMetadata = <T extends Record<string, any>>(\n markdown: string\n): T => {\n try {\n const lines = markdown.split(/\\r?\\n/);\n\n // Check if the very first non-empty line is the metadata start delimiter.\n const firstNonEmptyLine = lines.find((line) => line.trim() !== '');\n\n if (!firstNonEmptyLine || firstNonEmptyLine.trim() !== '---') {\n const result: T = {} as T;\n return result;\n }\n\n // Find the end of the metadata block\n let metadataEndIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i].trim() === '---') {\n metadataEndIndex = i;\n break;\n }\n }\n\n if (metadataEndIndex === -1) {\n // No closing delimiter found\n const result: T = {} as T;\n return result;\n }\n\n // Extract the metadata content between the delimiters\n const metadataLines = lines.slice(1, metadataEndIndex);\n const metadataContent = metadataLines.join('\\n');\n\n // Use the improved parseYaml function to parse the entire metadata block\n const metadata = parseYaml<T>(metadataContent);\n\n return metadata ?? ({} as T);\n } catch (_e) {\n const result: T = {} as T;\n return result;\n }\n};\n"],"mappings":";;;AAEA,MAAa,uBACX,aACM;AACN,KAAI;EACF,MAAM,QAAQ,SAAS,MAAM,QAAQ;EAGrC,MAAM,oBAAoB,MAAM,MAAM,SAAS,KAAK,MAAM,KAAK,GAAG;AAElE,MAAI,CAAC,qBAAqB,kBAAkB,MAAM,KAAK,MAErD,QADkB,EAAE;EAKtB,IAAI,mBAAmB;AACvB,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IAChC,KAAI,MAAM,GAAG,MAAM,KAAK,OAAO;AAC7B,sBAAmB;AACnB;;AAIJ,MAAI,qBAAqB,GAGvB,QADkB,EAAE;AAWtB,SAFiBA,kCAJK,MAAM,MAAM,GAAG,iBAAiB,CAChB,KAAK,KAAK,CAGF,IAE1B,EAAE;UACf,IAAI;AAEX,SADkB,EAAE"}
@@ -74,11 +74,94 @@ const parseYaml = (input) => {
74
74
  }
75
75
  return arr;
76
76
  };
77
+ const parseYamlListItem = () => {
78
+ next();
79
+ skipWhitespace();
80
+ if (peek() === "{") return parseObject();
81
+ const ch = peek();
82
+ if (ch === "\"" || ch === "'") return parseQuotedString(ch);
83
+ let hasColon = false;
84
+ let tempIdx = index;
85
+ while (tempIdx < text.length && text[tempIdx] !== "\n") {
86
+ if (text[tempIdx] === ":" && tempIdx + 1 < text.length && text[tempIdx + 1] === " ") {
87
+ hasColon = true;
88
+ break;
89
+ }
90
+ tempIdx++;
91
+ }
92
+ if (hasColon) return parseIndentedObject();
93
+ return toTypedValue(parseUnquotedToken(["\n"]));
94
+ };
95
+ const parseIndentedObject = () => {
96
+ const obj = {};
97
+ const baseIndent = getCurrentIndent();
98
+ while (!eof()) {
99
+ const lineStart = index;
100
+ const prevChar = text[lineStart - 1];
101
+ skipWhitespace();
102
+ const currentIndent = getCurrentIndent();
103
+ if ((lineStart === 0 || prevChar === "\n") && currentIndent <= baseIndent) {
104
+ index = lineStart;
105
+ break;
106
+ }
107
+ const ch = peek();
108
+ if (ch === "-" || eof()) {
109
+ index = lineStart;
110
+ break;
111
+ }
112
+ let key = "";
113
+ if (ch === "\"" || ch === "'") key = parseQuotedString(ch);
114
+ else {
115
+ while (!eof() && peek() !== ":") key += next();
116
+ key = key.trim();
117
+ }
118
+ if (eof() || next() !== ":") break;
119
+ skipWhitespace();
120
+ if (peek() === "\n") {
121
+ next();
122
+ skipWhitespace();
123
+ if (peek() === "-") {
124
+ obj[key] = parseYamlList();
125
+ continue;
126
+ }
127
+ }
128
+ obj[key] = toTypedValue(parseUnquotedToken(["\n"]));
129
+ if (peek() === "\n") next();
130
+ }
131
+ return obj;
132
+ };
133
+ const getCurrentIndent = () => {
134
+ let indent = 0;
135
+ let i = index;
136
+ while (i > 0 && text[i - 1] !== "\n") i--;
137
+ while (i < text.length && text[i] === " ") {
138
+ indent++;
139
+ i++;
140
+ }
141
+ return indent;
142
+ };
143
+ const parseYamlList = () => {
144
+ const arr = [];
145
+ const baseIndent = getCurrentIndent();
146
+ while (!eof()) {
147
+ while (!eof() && isWhitespace(peek())) {
148
+ next();
149
+ if (peek() === "-") break;
150
+ }
151
+ if (eof()) break;
152
+ if (getCurrentIndent() < baseIndent) break;
153
+ if (peek() !== "-") break;
154
+ arr.push(parseYamlListItem());
155
+ }
156
+ return arr;
157
+ };
77
158
  const parseObjectBody = (stops) => {
78
159
  const obj = {};
79
160
  skipWhitespace();
80
161
  while (true) {
81
162
  skipWhitespace();
163
+ if (eof()) return obj;
164
+ if (isStopChar(peek(), stops)) return obj;
82
165
  let key = "";
83
166
  const ch = peek();
84
167
  if (ch === "\"" || ch === "'") key = parseQuotedString(ch);
@@ -86,22 +169,72 @@ const parseYaml = (input) => {
86
169
  while (!eof()) {
87
170
  const c = peek();
88
171
  if (c === ":") break;
172
+ if (c === "\n") break;
89
173
  if (isStopChar(c, stops)) throw new SyntaxError("Expected ':' in object entry");
90
174
  key += next();
91
175
  }
92
176
  key = key.trim();
93
177
  }
178
+ if (!key) return obj;
94
179
  if (eof() || next() !== ":") throw new SyntaxError("Expected ':' after key");
95
- skipWhitespace();
96
- obj[key] = parseValue([",", ...stops]);
97
- skipWhitespace();
98
- const sep = peek();
180
+ if (!eof() && peek() === " ") next();
181
+ while (!eof() && (peek() === " " || peek() === " ")) next();
182
+ if (eof()) {
183
+ obj[key] = "";
184
+ return obj;
185
+ }
186
+ if (peek() === "\n") {
187
+ next();
188
+ const afterNewlinePos = index;
189
+ skipWhitespace();
190
+ if (peek() === "-") {
191
+ obj[key] = parseYamlList();
192
+ skipWhitespace();
193
+ continue;
194
+ } else {
195
+ index = afterNewlinePos;
196
+ skipWhitespace();
197
+ if (!eof()) {
198
+ const nextChar = peek();
199
+ if (nextChar && !isStopChar(nextChar, stops) && nextChar !== "-") {
200
+ obj[key] = "";
201
+ continue;
202
+ }
203
+ }
204
+ obj[key] = "";
205
+ return obj;
206
+ }
207
+ }
208
+ obj[key] = parseValue(stops.includes("}") ? [
209
+ ",",
210
+ "\n",
211
+ ...stops
212
+ ] : ["\n", ...stops]);
213
+ if (eof()) return obj;
214
+ let sep = peek();
99
215
  if (sep === ",") {
100
216
  next();
217
+ skipWhitespace();
218
+ continue;
219
+ }
220
+ if (sep === "\n") {
221
+ next();
222
+ skipWhitespace();
223
+ continue;
224
+ }
225
+ if (sep === " " || sep === " ") {
226
+ while (!eof() && (peek() === " " || peek() === " ")) next();
227
+ sep = peek();
228
+ if (sep === "\n") {
229
+ next();
230
+ skipWhitespace();
231
+ continue;
232
+ }
233
+ if (eof() || isStopChar(sep, stops)) return obj;
101
234
  continue;
102
235
  }
103
236
  if (isStopChar(sep, stops)) return obj;
104
- if (!eof()) throw new SyntaxError("Expected ',' or end of object");
237
+ if (!eof()) continue;
105
238
  return obj;
106
239
  }
107
240
  };
@@ -152,7 +285,8 @@ const parseYaml = (input) => {
152
285
  continue;
153
286
  }
154
287
  if (depth === 0 && char === ":") {
155
- if (s[i + 1] === " ") return true;
288
+ const nextCh = s[i + 1];
289
+ if (nextCh === " " || nextCh === "\n" || nextCh === void 0) return true;
156
290
  }
157
291
  i++;
158
292
  }