@toolsycc/json-merge
Version:
A utility to deeply and safely merge JSON objects, with full TypeScript support.
68 lines (67 loc) • 2.28 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.deepMerge = deepMerge;
exports.mergeMany = mergeMany;
function deepMerge(target, source, options = {}) {
const { arrayStrategy = 'replace', depthLimit = Infinity, ignoreKeys = [], preserveUndefined = false, customMerge, dateStrategy = 'copy', overwriteFalsy = true, cloneInputs = true } = options;
if (depthLimit === 0)
return source;
const result = cloneInputs ? { ...target } : target;
for (const key in source) {
if (ignoreKeys.includes(key))
continue;
const val1 = result[key];
const val2 = source[key];
if (customMerge) {
result[key] = customMerge(key, val1, val2);
continue;
}
if (val2 instanceof Date) {
switch (dateStrategy) {
case 'stringify':
result[key] = val2.toISOString();
break;
case 'timestamp':
result[key] = val2.getTime();
break;
default:
result[key] = new Date(val2.getTime());
}
continue;
}
if (val2 &&
typeof val2 === 'object' &&
!Array.isArray(val2) &&
!(val2 instanceof Date)) {
result[key] = deepMerge(val1 || {}, val2, {
arrayStrategy,
depthLimit: depthLimit - 1,
ignoreKeys,
preserveUndefined,
customMerge,
dateStrategy,
overwriteFalsy,
cloneInputs
});
}
else if (Array.isArray(val2)) {
if (arrayStrategy === 'concat' && Array.isArray(val1)) {
result[key] = [...val1, ...val2];
}
else {
result[key] = val2;
}
}
else {
if (val2 === undefined && !preserveUndefined)
continue;
if (!overwriteFalsy && val2 == null)
continue;
result[key] = val2;
}
}
return result;
}
function mergeMany(objects, options) {
return objects.reduce((acc, obj) => deepMerge(acc, obj, options), {});
}
;