"use strict"; var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default; exports.__esModule = true; exports.default = deepmerge; var _minim = require("minim"); var _index = require("./predicates/index.cjs"); var _index2 = require("./clone/index.cjs"); var _index3 = _interopRequireDefault(require("./transformers/serializers/value/index.cjs")); /* eslint-disable @typescript-eslint/no-use-before-define */ const emptyElement = element => { const meta = (0, _index2.cloneDeep)(element.meta); const attributes = (0, _index2.cloneDeep)(element.attributes); // @ts-ignore return new element.constructor(undefined, meta, attributes); }; const cloneUnlessOtherwiseSpecified = (element, options) => options.clone && options.isMergeableElement(element) ? deepmerge(emptyElement(element), element, options) : element; const getMergeFunction = (keyElement, options) => { if (typeof options.customMerge !== 'function') { return deepmerge; } const customMerge = options.customMerge(keyElement, options); return typeof customMerge === 'function' ? customMerge : deepmerge; }; const mergeArrayElement = (targetElement, sourceElement, options) => targetElement.concat(sourceElement)['fantasy-land/map'](item => cloneUnlessOtherwiseSpecified(item, options)); const mergeObjectElement = (targetElement, sourceElement, options) => { const destination = (0, _index.isObjectElement)(targetElement) ? emptyElement(targetElement) : emptyElement(sourceElement); if ((0, _index.isObjectElement)(targetElement)) { targetElement.forEach((value, key, member) => { const clonedMember = (0, _index2.cloneShallow)(member); clonedMember.value = cloneUnlessOtherwiseSpecified(value, options); destination.content.push(clonedMember); }); } sourceElement.forEach((value, key, member) => { const keyValue = (0, _index3.default)(key); let clonedMember; if ((0, _index.isObjectElement)(targetElement) && targetElement.hasKey(keyValue) && options.isMergeableElement(value)) { const targetValue = targetElement.get(keyValue); clonedMember = (0, _index2.cloneShallow)(member); clonedMember.value = getMergeFunction(key, options)(targetValue, value); } else { clonedMember = (0, _index2.cloneShallow)(member); clonedMember.value = cloneUnlessOtherwiseSpecified(value, options); } destination.remove(keyValue); destination.content.push(clonedMember); }); return destination; }; function deepmerge(targetElement, sourceElement, options) { var _mergedOptions$isMerg, _mergedOptions$arrayE, _mergedOptions$object; const defaultOptions = { clone: true, isMergeableElement: element => (0, _index.isObjectElement)(element) || (0, _index.isArrayElement)(element), arrayElementMerge: mergeArrayElement, objectElementMerge: mergeObjectElement, customMerge: undefined }; const mergedOptions = { ...defaultOptions, ...options }; mergedOptions.isMergeableElement = (_mergedOptions$isMerg = mergedOptions.isMergeableElement) != null ? _mergedOptions$isMerg : defaultOptions.isMergeableElement; mergedOptions.arrayElementMerge = (_mergedOptions$arrayE = mergedOptions.arrayElementMerge) != null ? _mergedOptions$arrayE : defaultOptions.arrayElementMerge; mergedOptions.objectElementMerge = (_mergedOptions$object = mergedOptions.objectElementMerge) != null ? _mergedOptions$object : defaultOptions.objectElementMerge; const sourceIsArrayElement = (0, _index.isArrayElement)(sourceElement); const targetIsArrayElement = (0, _index.isArrayElement)(targetElement); const sourceAndTargetTypesMatch = sourceIsArrayElement === targetIsArrayElement; if (!sourceAndTargetTypesMatch) { return cloneUnlessOtherwiseSpecified(sourceElement, mergedOptions); } if (sourceIsArrayElement && typeof mergedOptions.arrayElementMerge === 'function') { return mergedOptions.arrayElementMerge(targetElement, sourceElement, mergedOptions); } return mergedOptions.objectElementMerge(targetElement, sourceElement, mergedOptions); } deepmerge.all = (list, options) => { if (!Array.isArray(list)) { throw new TypeError('First argument of deepmerge should be an array.'); } if (list.length === 0) { return new _minim.ObjectElement(); } return list.reduce((target, source) => { return deepmerge(target, source, options); }, emptyElement(list[0])); }; /* eslint-enable @typescript-eslint/no-use-before-define */