@storm-stack/utilities
Version:
This package includes various base utility class and various functions to assist in the development process.
70 lines (69 loc) • 2.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.deepMerge = void 0;
var _types = require("@storm-stack/types");
const emptyTarget = val => {
return Array.isArray(val) ? [] : {};
};
const cloneUnlessOtherwiseSpecified = (value, options) => {
return options.clone !== false && options.isMergeableObject(value) ? deepMerge(emptyTarget(value), value, options) : value;
};
const defaultArrayMerge = (target, source, options) => {
return [...target, ...source].map(element => {
return cloneUnlessOtherwiseSpecified(element, options);
});
};
const getMergeFunction = (key, options) => {
if (!options.customMerge) {
return deepMerge;
}
const customMerge = options.customMerge(key);
return (0, _types.isFunction)(customMerge) ? customMerge : deepMerge;
};
const getKeys = target => {
return [...Object.keys(target), ...(Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(target).filter(symbol => {
return Object.propertyIsEnumerable.call(target, symbol);
}) : [])];
};
const mergeObject = (target, source, options) => {
const destination = {};
if (options.isMergeableObject(target)) {
for (const key of getKeys(target)) {
destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
}
}
for (const key of getKeys(source)) {
destination[key] = (0, _types.propertyUnsafe)(target, key) && options.isMergeableObject(source[key]) ? getMergeFunction(key, options)(target[key], source[key], options) : cloneUnlessOtherwiseSpecified(source[key], options);
}
return destination;
};
const deepMerge = (target, source, options = {}) => {
if (!target || !source) {
return target || source;
}
const _options = options || {};
_options.arrayMerge = options.arrayMerge || defaultArrayMerge;
_options.isMergeableObject = _options.isMergeableObject || _types.isMergeableObject;
_options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
const sourceIsArray = Array.isArray(source);
const targetIsArray = Array.isArray(target);
const sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
if (!sourceAndTargetTypesMatch) {
return cloneUnlessOtherwiseSpecified(source, _options);
}
if (sourceIsArray) {
return _options.arrayMerge(target, source, _options);
}
return mergeObject(target, source, _options);
};
exports.deepMerge = deepMerge;
deepMerge.all = function deepMergeAll(array, options) {
if (!Array.isArray(array)) {
throw new TypeError("first argument should be an array");
}
return array.reduce((prev, next) => {
return deepMerge(prev, next, options);
}, {});
};