[d24f17c] | 1 | "use strict";
|
---|
| 2 |
|
---|
| 3 | var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
|
---|
| 4 | exports.__esModule = true;
|
---|
| 5 | exports.default = deepmerge;
|
---|
| 6 | var _minim = require("minim");
|
---|
| 7 | var _index = require("./predicates/index.cjs");
|
---|
| 8 | var _index2 = require("./clone/index.cjs");
|
---|
| 9 | var _index3 = _interopRequireDefault(require("./transformers/serializers/value/index.cjs"));
|
---|
| 10 | /* eslint-disable @typescript-eslint/no-use-before-define */
|
---|
| 11 |
|
---|
| 12 | const emptyElement = element => {
|
---|
| 13 | const meta = (0, _index2.cloneDeep)(element.meta);
|
---|
| 14 | const attributes = (0, _index2.cloneDeep)(element.attributes);
|
---|
| 15 |
|
---|
| 16 | // @ts-ignore
|
---|
| 17 | return new element.constructor(undefined, meta, attributes);
|
---|
| 18 | };
|
---|
| 19 | const cloneUnlessOtherwiseSpecified = (element, options) => options.clone && options.isMergeableElement(element) ? deepmerge(emptyElement(element), element, options) : element;
|
---|
| 20 | const getMergeFunction = (keyElement, options) => {
|
---|
| 21 | if (typeof options.customMerge !== 'function') {
|
---|
| 22 | return deepmerge;
|
---|
| 23 | }
|
---|
| 24 | const customMerge = options.customMerge(keyElement, options);
|
---|
| 25 | return typeof customMerge === 'function' ? customMerge : deepmerge;
|
---|
| 26 | };
|
---|
| 27 | const mergeArrayElement = (targetElement, sourceElement, options) => targetElement.concat(sourceElement)['fantasy-land/map'](item => cloneUnlessOtherwiseSpecified(item, options));
|
---|
| 28 | const mergeObjectElement = (targetElement, sourceElement, options) => {
|
---|
| 29 | const destination = (0, _index.isObjectElement)(targetElement) ? emptyElement(targetElement) : emptyElement(sourceElement);
|
---|
| 30 | if ((0, _index.isObjectElement)(targetElement)) {
|
---|
| 31 | targetElement.forEach((value, key, member) => {
|
---|
| 32 | const clonedMember = (0, _index2.cloneShallow)(member);
|
---|
| 33 | clonedMember.value = cloneUnlessOtherwiseSpecified(value, options);
|
---|
| 34 | destination.content.push(clonedMember);
|
---|
| 35 | });
|
---|
| 36 | }
|
---|
| 37 | sourceElement.forEach((value, key, member) => {
|
---|
| 38 | const keyValue = (0, _index3.default)(key);
|
---|
| 39 | let clonedMember;
|
---|
| 40 | if ((0, _index.isObjectElement)(targetElement) && targetElement.hasKey(keyValue) && options.isMergeableElement(value)) {
|
---|
| 41 | const targetValue = targetElement.get(keyValue);
|
---|
| 42 | clonedMember = (0, _index2.cloneShallow)(member);
|
---|
| 43 | clonedMember.value = getMergeFunction(key, options)(targetValue, value);
|
---|
| 44 | } else {
|
---|
| 45 | clonedMember = (0, _index2.cloneShallow)(member);
|
---|
| 46 | clonedMember.value = cloneUnlessOtherwiseSpecified(value, options);
|
---|
| 47 | }
|
---|
| 48 | destination.remove(keyValue);
|
---|
| 49 | destination.content.push(clonedMember);
|
---|
| 50 | });
|
---|
| 51 | return destination;
|
---|
| 52 | };
|
---|
| 53 | function deepmerge(targetElement, sourceElement, options) {
|
---|
| 54 | var _mergedOptions$isMerg, _mergedOptions$arrayE, _mergedOptions$object;
|
---|
| 55 | const defaultOptions = {
|
---|
| 56 | clone: true,
|
---|
| 57 | isMergeableElement: element => (0, _index.isObjectElement)(element) || (0, _index.isArrayElement)(element),
|
---|
| 58 | arrayElementMerge: mergeArrayElement,
|
---|
| 59 | objectElementMerge: mergeObjectElement,
|
---|
| 60 | customMerge: undefined
|
---|
| 61 | };
|
---|
| 62 | const mergedOptions = {
|
---|
| 63 | ...defaultOptions,
|
---|
| 64 | ...options
|
---|
| 65 | };
|
---|
| 66 | mergedOptions.isMergeableElement = (_mergedOptions$isMerg = mergedOptions.isMergeableElement) != null ? _mergedOptions$isMerg : defaultOptions.isMergeableElement;
|
---|
| 67 | mergedOptions.arrayElementMerge = (_mergedOptions$arrayE = mergedOptions.arrayElementMerge) != null ? _mergedOptions$arrayE : defaultOptions.arrayElementMerge;
|
---|
| 68 | mergedOptions.objectElementMerge = (_mergedOptions$object = mergedOptions.objectElementMerge) != null ? _mergedOptions$object : defaultOptions.objectElementMerge;
|
---|
| 69 | const sourceIsArrayElement = (0, _index.isArrayElement)(sourceElement);
|
---|
| 70 | const targetIsArrayElement = (0, _index.isArrayElement)(targetElement);
|
---|
| 71 | const sourceAndTargetTypesMatch = sourceIsArrayElement === targetIsArrayElement;
|
---|
| 72 | if (!sourceAndTargetTypesMatch) {
|
---|
| 73 | return cloneUnlessOtherwiseSpecified(sourceElement, mergedOptions);
|
---|
| 74 | }
|
---|
| 75 | if (sourceIsArrayElement && typeof mergedOptions.arrayElementMerge === 'function') {
|
---|
| 76 | return mergedOptions.arrayElementMerge(targetElement, sourceElement, mergedOptions);
|
---|
| 77 | }
|
---|
| 78 | return mergedOptions.objectElementMerge(targetElement, sourceElement, mergedOptions);
|
---|
| 79 | }
|
---|
| 80 | deepmerge.all = (list, options) => {
|
---|
| 81 | if (!Array.isArray(list)) {
|
---|
| 82 | throw new TypeError('First argument of deepmerge should be an array.');
|
---|
| 83 | }
|
---|
| 84 | if (list.length === 0) {
|
---|
| 85 | return new _minim.ObjectElement();
|
---|
| 86 | }
|
---|
| 87 | return list.reduce((target, source) => {
|
---|
| 88 | return deepmerge(target, source, options);
|
---|
| 89 | }, emptyElement(list[0]));
|
---|
| 90 | };
|
---|
| 91 | /* eslint-enable @typescript-eslint/no-use-before-define */ |
---|