Skip to content

Instantly share code, notes, and snippets.

@jeffposnick
Created February 15, 2022 22:08
Show Gist options
  • Save jeffposnick/cd46ff6ca5cf1d2ec1d87edae863f17e to your computer and use it in GitHub Desktop.
Save jeffposnick/cd46ff6ca5cf1d2ec1d87edae863f17e to your computer and use it in GitHub Desktop.
const isPlainObject = require("lodash/isPlainObject");
const OVERRIDE_PREFIX = "override:";
function getMergedItem(target, source, parentKey) {
// if key is prefixed with OVERRIDE_PREFIX, it just keeps the new source value (no merging)
if (parentKey && parentKey.indexOf(OVERRIDE_PREFIX) === 0) {
return source;
}
const isTargetArray = Array.isArray(target);
let isTargetPlainObject;
if (isTargetArray) {
isTargetPlainObject = false;
}
const isSourceArray = Array.isArray(source);
let isSourcePlainObject;
if (isSourceArray) {
isSourcePlainObject = false;
}
// deep copy objects to avoid sharing and to effect key renaming
if (!target) {
if (isSourcePlainObject === undefined) {
isSourcePlainObject = isPlainObject(source);
}
if (isSourcePlainObject) {
target = {};
isTargetPlainObject = true;
}
}
if (isTargetArray && isSourceArray) {
return target.concat(source);
} else if (isTargetPlainObject !== undefined ? isTargetPlainObject : isPlainObject(target)) {
if (isSourcePlainObject !== undefined ? isSourcePlainObject : isPlainObject(source)) {
for (var key in source) {
let newKey = key;
if (key.indexOf(OVERRIDE_PREFIX) === 0) {
newKey = key.substr(OVERRIDE_PREFIX.length);
}
target[newKey] = getMergedItem(target[key], source[key], newKey);
}
}
return target;
} else {
// number, string, class instance, etc
return source;
}
}
function Merge(target, ...sources) {
// Remove override prefixes from root target.
if (isPlainObject(target)) {
for (var key in target) {
if (key.indexOf(OVERRIDE_PREFIX) === 0) {
target[key.substr(OVERRIDE_PREFIX.length)] = target[key];
delete target[key];
}
}
}
for (var source of sources) {
if (!source) {
continue;
}
target = getMergedItem(target, source);
}
return target;
}
module.exports = Merge;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment