blob: 8d4586b019aa92c5e27820dfaf265cdbb6364865 [file] [log] [blame]
/**
* Deeply merge two plain objects (or arrays) without mutating the inputs.
*
* Rules:
* - Arrays from the source replace arrays on the target.
* - Plain objects are merged recursively.
* - Primitive values from the source overwrite the target.
*/
export function deepMerge(target, source) {
if (typeof target !== 'object' || target === null) return source;
if (typeof source !== 'object' || source === null) return target;
const output = Array.isArray(target) ? target.slice() : { ...target };
Object.keys(source).forEach((key) => {
const sourceValue = source[key];
const targetValue = output[key];
if (Array.isArray(sourceValue)) {
output[key] = sourceValue.slice();
} else if (
typeof sourceValue === 'object' &&
sourceValue !== null &&
typeof targetValue === 'object' &&
targetValue !== null &&
!Array.isArray(targetValue)
) {
output[key] = deepMerge(targetValue, sourceValue);
} else {
output[key] = sourceValue;
}
});
return output;
}