You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.6 KiB

4 years ago
  1. var isMergeableObject = function isMergeableObject(value) {
  2. return isNonNullObject(value)
  3. && !isSpecial(value)
  4. };
  5. function isNonNullObject(value) {
  6. return !!value && typeof value === 'object'
  7. }
  8. function isSpecial(value) {
  9. var stringValue = Object.prototype.toString.call(value);
  10. return stringValue === '[object RegExp]'
  11. || stringValue === '[object Date]'
  12. || isReactElement(value)
  13. }
  14. // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
  15. var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
  16. var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
  17. function isReactElement(value) {
  18. return value.$$typeof === REACT_ELEMENT_TYPE
  19. }
  20. function emptyTarget(val) {
  21. return Array.isArray(val) ? [] : {}
  22. }
  23. function cloneUnlessOtherwiseSpecified(value, options) {
  24. return (options.clone !== false && options.isMergeableObject(value))
  25. ? deepmerge(emptyTarget(value), value, options)
  26. : value
  27. }
  28. function defaultArrayMerge(target, source, options) {
  29. return target.concat(source).map(function(element) {
  30. return cloneUnlessOtherwiseSpecified(element, options)
  31. })
  32. }
  33. function mergeObject(target, source, options) {
  34. var destination = {};
  35. if (options.isMergeableObject(target)) {
  36. Object.keys(target).forEach(function(key) {
  37. destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
  38. });
  39. }
  40. Object.keys(source).forEach(function(key) {
  41. if (!options.isMergeableObject(source[key]) || !target[key]) {
  42. destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
  43. } else {
  44. destination[key] = deepmerge(target[key], source[key], options);
  45. }
  46. });
  47. return destination
  48. }
  49. function deepmerge(target, source, options) {
  50. options = options || {};
  51. options.arrayMerge = options.arrayMerge || defaultArrayMerge;
  52. options.isMergeableObject = options.isMergeableObject || isMergeableObject;
  53. var sourceIsArray = Array.isArray(source);
  54. var targetIsArray = Array.isArray(target);
  55. var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
  56. if (!sourceAndTargetTypesMatch) {
  57. return cloneUnlessOtherwiseSpecified(source, options)
  58. } else if (sourceIsArray) {
  59. return options.arrayMerge(target, source, options)
  60. } else {
  61. return mergeObject(target, source, options)
  62. }
  63. }
  64. deepmerge.all = function deepmergeAll(array, options) {
  65. if (!Array.isArray(array)) {
  66. throw new Error('first argument should be an array')
  67. }
  68. return array.reduce(function(prev, next) {
  69. return deepmerge(prev, next, options)
  70. }, {})
  71. };
  72. var deepmerge_1 = deepmerge;
  73. export default deepmerge_1;