UNPKG

@intlayer/chokidar

Version:

Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.

1 lines 7.43 kB
{"version":3,"sources":["../../src/mergeDictionaries.ts"],"sourcesContent":["import { getAppLogger } from '@intlayer/config';\nimport configuration from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/core';\nimport { getNodeType } from '@intlayer/core';\nimport merge, { Options } from 'deepmerge';\n\nconst checkTypesMatch = (\n obj1: any,\n obj2: any,\n dictionaryKey: string,\n path: string[] = []\n): void => {\n const appLogger = getAppLogger(configuration);\n const type1 = getNodeType(obj1);\n const type2 = getNodeType(obj2);\n\n if (type1 !== type2) {\n appLogger(\n `Error: Dictionary \"${dictionaryKey}\" has a multiple content files with type mismatch at path \"${path.join('.')}\": Cannot merge ${type1} with ${type2}`,\n {\n level: 'error',\n }\n );\n }\n\n if (type1 === 'object' && obj1 && obj2) {\n const allKeys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]);\n for (const key of allKeys) {\n if (key in obj1 && key in obj2) {\n checkTypesMatch(obj1[key], obj2[key], dictionaryKey, [...path, key]);\n }\n }\n }\n};\n\n// Custom array merge strategy that merges arrays by key when present, otherwise by index\nconst arrayMerge = (destinationArray: any[], sourceArray: any[]): any[] => {\n const isObject = (value: unknown): value is Record<string, any> =>\n !!value && typeof value === 'object' && !Array.isArray(value);\n\n const getKey = (item: any): string | number | undefined => {\n if (!isObject(item)) return undefined;\n const key = (item as any).key;\n if (typeof key === 'string' || typeof key === 'number') return key;\n return undefined;\n };\n\n const result: any[] = [];\n\n // Build a lookup for destination keyed items and track usage of all destination indices\n const destKeyToIndex = new Map<string | number, number>();\n const destUsed: boolean[] = new Array(destinationArray.length).fill(false);\n for (let i = 0; i < destinationArray.length; i++) {\n const k = getKey(destinationArray[i]);\n if (k !== undefined && !destKeyToIndex.has(k)) {\n destKeyToIndex.set(k, i);\n }\n }\n\n // First pass: respect source (already merged) order\n for (let i = 0; i < sourceArray.length; i++) {\n const sourceItem = sourceArray[i];\n const sourceKey = getKey(sourceItem);\n\n if (sourceKey !== undefined && destKeyToIndex.has(sourceKey)) {\n const destIndex = destKeyToIndex.get(sourceKey)!;\n const destItem = destinationArray[destIndex];\n destUsed[destIndex] = true;\n\n if (isObject(destItem) && isObject(sourceItem)) {\n result.push(merge(sourceItem, destItem, { arrayMerge }));\n } else {\n // Prefer destination item (later dictionary) when primitive\n result.push(destItem !== undefined ? destItem : sourceItem);\n }\n continue;\n }\n\n // Fallback to index-based merge when no key match\n const destItem = destinationArray[i];\n if (destItem !== undefined && !destUsed[i]) {\n destUsed[i] = true;\n if (isObject(destItem) && isObject(sourceItem)) {\n result.push(merge(sourceItem, destItem, { arrayMerge }));\n } else if (destItem !== undefined) {\n result.push(destItem);\n } else {\n result.push(sourceItem);\n }\n } else {\n result.push(sourceItem);\n }\n }\n\n // Second pass: append remaining unused destination items (including keyed-only in destination or extra by index)\n for (let i = 0; i < destinationArray.length; i++) {\n if (!destUsed[i]) {\n result.push(destinationArray[i]);\n destUsed[i] = true;\n }\n }\n\n return result;\n};\n\nexport const mergeDictionaries = (dictionaries: Dictionary[]): Dictionary => {\n const { editor } = configuration;\n\n let mergedDictionaries: Dictionary = dictionaries[0];\n\n // Configure deepmerge options with custom array merge strategy\n const mergeOptions: Options = {\n arrayMerge,\n };\n\n for (let i = 1; i < dictionaries.length; i++) {\n const currentDictionary = dictionaries[i];\n\n // Check types before merging\n checkTypesMatch(\n mergedDictionaries,\n currentDictionary,\n currentDictionary.key,\n []\n );\n\n const isDistant = currentDictionary.location === 'distant';\n\n if (editor.dictionaryPriorityStrategy === 'distant_first' && isDistant) {\n mergedDictionaries = merge(\n mergedDictionaries,\n currentDictionary,\n mergeOptions\n );\n } else {\n mergedDictionaries = merge(\n currentDictionary,\n mergedDictionaries,\n mergeOptions\n );\n }\n }\n\n return { ...mergedDictionaries, filePath: undefined };\n};\n"],"mappings":"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","names":["configuration","destItem","merge"]}