umd.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (global = global || self, global.deepmerge = factory());
  5. }(this, function () { 'use strict';
  6. var isMergeableObject = function isMergeableObject(value) {
  7. return isNonNullObject(value)
  8. && !isSpecial(value)
  9. };
  10. function isNonNullObject(value) {
  11. return !!value && typeof value === 'object'
  12. }
  13. function isSpecial(value) {
  14. var stringValue = Object.prototype.toString.call(value);
  15. return stringValue === '[object RegExp]'
  16. || stringValue === '[object Date]'
  17. || isReactElement(value)
  18. }
  19. // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
  20. var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
  21. var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
  22. function isReactElement(value) {
  23. return value.$$typeof === REACT_ELEMENT_TYPE
  24. }
  25. function emptyTarget(val) {
  26. return Array.isArray(val) ? [] : {}
  27. }
  28. function cloneUnlessOtherwiseSpecified(value, options) {
  29. return (options.clone !== false && options.isMergeableObject(value))
  30. ? deepmerge(emptyTarget(value), value, options)
  31. : value
  32. }
  33. function defaultArrayMerge(target, source, options) {
  34. return target.concat(source).map(function(element) {
  35. return cloneUnlessOtherwiseSpecified(element, options)
  36. })
  37. }
  38. function getMergeFunction(key, options) {
  39. if (!options.customMerge) {
  40. return deepmerge
  41. }
  42. var customMerge = options.customMerge(key);
  43. return typeof customMerge === 'function' ? customMerge : deepmerge
  44. }
  45. function getEnumerableOwnPropertySymbols(target) {
  46. return Object.getOwnPropertySymbols
  47. ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
  48. return Object.propertyIsEnumerable.call(target, symbol)
  49. })
  50. : []
  51. }
  52. function getKeys(target) {
  53. return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
  54. }
  55. function propertyIsOnObject(object, property) {
  56. try {
  57. return property in object
  58. } catch(_) {
  59. return false
  60. }
  61. }
  62. // Protects from prototype poisoning and unexpected merging up the prototype chain.
  63. function propertyIsUnsafe(target, key) {
  64. return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
  65. && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
  66. && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
  67. }
  68. function mergeObject(target, source, options) {
  69. var destination = {};
  70. if (options.isMergeableObject(target)) {
  71. getKeys(target).forEach(function(key) {
  72. destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
  73. });
  74. }
  75. getKeys(source).forEach(function(key) {
  76. if (propertyIsUnsafe(target, key)) {
  77. return
  78. }
  79. if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
  80. destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
  81. } else {
  82. destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
  83. }
  84. });
  85. return destination
  86. }
  87. function deepmerge(target, source, options) {
  88. options = options || {};
  89. options.arrayMerge = options.arrayMerge || defaultArrayMerge;
  90. options.isMergeableObject = options.isMergeableObject || isMergeableObject;
  91. // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
  92. // implementations can use it. The caller may not replace it.
  93. options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
  94. var sourceIsArray = Array.isArray(source);
  95. var targetIsArray = Array.isArray(target);
  96. var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
  97. if (!sourceAndTargetTypesMatch) {
  98. return cloneUnlessOtherwiseSpecified(source, options)
  99. } else if (sourceIsArray) {
  100. return options.arrayMerge(target, source, options)
  101. } else {
  102. return mergeObject(target, source, options)
  103. }
  104. }
  105. deepmerge.all = function deepmergeAll(array, options) {
  106. if (!Array.isArray(array)) {
  107. throw new Error('first argument should be an array')
  108. }
  109. return array.reduce(function(prev, next) {
  110. return deepmerge(prev, next, options)
  111. }, {})
  112. };
  113. var deepmerge_1 = deepmerge;
  114. return deepmerge_1;
  115. }));