@snipsonian/core
Version:
Core/base reusable javascript code snippets
61 lines (60 loc) • 2.12 kB
JavaScript
import isUndefined from '../is/isUndefined';
import isNull from '../is/isNull';
import isObjectPure from '../is/isObjectPure';
import cloneObjectDataProps from '../object/cloneObjectDataProps';
export default function mergeObjectPropsDeeply(...sources) {
return mergeObjectPropsDeeplyOptionable({
sources,
});
}
export function mergeObjectPropsDeeplyOptionable({ options, sources, }) {
const initialValue = {};
return sources.reduce((accumulator, source, index) => {
if (index === 0) {
return cloneObjectDataProps(source);
}
return mergeObjectPropsDeeplyFromSourceToTarget({
target: accumulator,
source,
options,
});
}, initialValue);
}
export function mergeObjectPropsDeeplyFromSourceToTarget({ target, source, options, }) {
const { ignoreUndefinedSourceProps = true, ignoreNullSourceProps = true, ignoreDifferentTypeSourceProps = true, } = options || {};
if (isUndefined(target) || isNull(target)) {
return cloneProp(source);
}
if (isUndefined(source)) {
return ignoreUndefinedSourceProps ? target : cloneProp(source);
}
if (isNull(source)) {
return ignoreNullSourceProps ? target : cloneProp(source);
}
if ((typeof source !== typeof target)) {
return ignoreDifferentTypeSourceProps ? target : cloneProp(source);
}
if (isObjectPure(target)) {
if (isObjectPure(source)) {
Object.keys(source).forEach((key) => {
target[key] = mergeObjectPropsDeeplyFromSourceToTarget({
target: target[key],
source: source[key],
options,
});
});
return target;
}
return ignoreDifferentTypeSourceProps ? target : cloneProp(source);
}
return cloneProp(source);
}
function cloneProp(prop) {
if (isUndefined(prop) || isNull(prop)) {
return prop;
}
if (isObjectPure(prop)) {
return cloneObjectDataProps(prop);
}
return cloneObjectDataProps({ temp: prop })['temp'];
}