@apollo/gateway
Version:
39 lines (33 loc) • 1.26 kB
text/typescript
import { defineOwn } from './own';
import { isObject } from './predicates';
export function deepMerge(target: any, source: any): any {
if (source === undefined || source === null) return target;
for (const key of Object.keys(source)) {
if (source[key] === undefined) continue;
// While `Object.keys()` guarantees that `key` is an own property name in
// `source`, we do not have that same guarantee for `target`. In the event
// the property is absent from `target`, we don't want to accidentally
// fetch the property in `target`'s prototype chain (if present), and
// accordingly we define the property on `target` in such cases.
defineOwn(target, key);
if (target[key] && isObject(source[key])) {
deepMerge(target[key], source[key]);
} else if (
Array.isArray(source[key]) &&
Array.isArray(target[key]) &&
source[key].length === target[key].length
) {
let i = 0;
for (; i < source[key].length; i++) {
if (isObject(target[key][i]) && isObject(source[key][i])) {
deepMerge(target[key][i], source[key][i]);
} else {
target[key][i] = source[key][i];
}
}
} else {
target[key] = source[key];
}
}
return target;
}