cjs.js 3.9 KB

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