@75lb/deep-merge
Version:
Deep-merge the values of one object structure into another
30 lines (25 loc) • 1 kB
JavaScript
import assignWith from 'lodash/assignWith.js'
import { isPlainObject, isDefined } from 'typical'
const FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype'])
function customiser (previousValue, newValue, key, object, source) {
/* refuse to merge into prototype-affecting keys */
if (FORBIDDEN_KEYS.has(key)) {
return previousValue
}
/* deep merge plain objects */
if (isPlainObject(previousValue) && isPlainObject(newValue)) {
return assignWith(previousValue, newValue, customiser)
/* overwrite arrays if the new array has items */
} else if (Array.isArray(previousValue) && Array.isArray(newValue) && newValue.length) {
return newValue
/* ignore incoming arrays if empty */
} else if (Array.isArray(newValue) && !newValue.length) {
return previousValue
} else if (!isDefined(previousValue) && Array.isArray(newValue)) {
return newValue
}
}
function deepMerge (...args) {
return assignWith(...args, customiser)
}
export default deepMerge