-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into esm-compat
- Loading branch information
Showing
3 changed files
with
127 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
"use strict"; | ||
|
||
function defaultIsMergeableObject(value) { | ||
return !!value && typeof value === "object"; | ||
} | ||
|
||
function emptyTarget(val) { | ||
return Array.isArray(val) ? [] : {}; | ||
} | ||
|
||
function cloneUnlessOtherwiseSpecified(value, options) { | ||
return options.clone !== false && options.isMergeableObject(value) | ||
? deepmerge(emptyTarget(value), value, options) | ||
: value; | ||
} | ||
|
||
function defaultArrayMerge(target, source, options) { | ||
return target.concat(source).map(function (element) { | ||
return cloneUnlessOtherwiseSpecified(element, options); | ||
}); | ||
} | ||
|
||
function getMergeFunction(key, options) { | ||
if (!options.customMerge) { | ||
return deepmerge; | ||
} | ||
var customMerge = options.customMerge(key); | ||
return typeof customMerge === "function" ? customMerge : deepmerge; | ||
} | ||
|
||
function getEnumerableOwnPropertySymbols(target) { | ||
return Object.getOwnPropertySymbols | ||
? Object.getOwnPropertySymbols(target).filter(function (symbol) { | ||
// eslint-disable-next-line no-prototype-builtins | ||
return target.propertyIsEnumerable(symbol); | ||
}) | ||
: []; | ||
} | ||
|
||
function getKeys(target) { | ||
return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)); | ||
} | ||
|
||
function propertyIsOnObject(object, property) { | ||
try { | ||
return property in object; | ||
} catch (_) { | ||
return false; | ||
} | ||
} | ||
|
||
// Protects from prototype poisoning and unexpected merging up the prototype chain. | ||
function propertyIsUnsafe(target, key) { | ||
return ( | ||
propertyIsOnObject(target, key) && // Properties are safe to merge if they don't exist in the target yet, | ||
!( | ||
Object.hasOwnProperty.call(target, key) && // unsafe if they exist up the prototype chain, | ||
Object.propertyIsEnumerable.call(target, key) | ||
) | ||
); // and also unsafe if they're nonenumerable. | ||
} | ||
|
||
function mergeObject(target, source, options) { | ||
var destination = {}; | ||
if (options.isMergeableObject(target)) { | ||
getKeys(target).forEach(function (key) { | ||
destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); | ||
}); | ||
} | ||
getKeys(source).forEach(function (key) { | ||
if (propertyIsUnsafe(target, key)) { | ||
return; | ||
} | ||
|
||
if ( | ||
propertyIsOnObject(target, key) && | ||
options.isMergeableObject(source[key]) | ||
) { | ||
destination[key] = getMergeFunction(key, options)( | ||
target[key], | ||
source[key], | ||
options | ||
); | ||
} else { | ||
destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); | ||
} | ||
}); | ||
return destination; | ||
} | ||
|
||
function deepmerge(target, source, options) { | ||
options = options || {}; | ||
options.arrayMerge = options.arrayMerge || defaultArrayMerge; | ||
options.isMergeableObject = | ||
options.isMergeableObject || defaultIsMergeableObject; | ||
// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() | ||
// implementations can use it. The caller may not replace it. | ||
options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; | ||
|
||
var sourceIsArray = Array.isArray(source); | ||
var targetIsArray = Array.isArray(target); | ||
var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; | ||
|
||
if (!sourceAndTargetTypesMatch) { | ||
return cloneUnlessOtherwiseSpecified(source, options); | ||
} else if (sourceIsArray) { | ||
return options.arrayMerge(target, source, options); | ||
} else { | ||
return mergeObject(target, source, options); | ||
} | ||
} | ||
|
||
deepmerge.all = function deepmergeAll(array, options) { | ||
if (!Array.isArray(array)) { | ||
throw new Error("first argument should be an array"); | ||
} | ||
|
||
return array.reduce(function (prev, next) { | ||
return deepmerge(prev, next, options); | ||
}, {}); | ||
}; | ||
|
||
module.exports = deepmerge; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters