mergeConfig.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 'use strict';
  2. import utils from '../utils.js';
  3. import AxiosHeaders from './AxiosHeaders.js';
  4. const headersToObject = (thing) => (thing instanceof AxiosHeaders ? { ...thing } : thing);
  5. /**
  6. * Config-specific merge-function which creates a new config-object
  7. * by merging two configuration objects together.
  8. *
  9. * @param {Object} config1
  10. * @param {Object} config2
  11. *
  12. * @returns {Object} New object resulting from merging config2 to config1
  13. */
  14. export default function mergeConfig(config1, config2) {
  15. // eslint-disable-next-line no-param-reassign
  16. config2 = config2 || {};
  17. const config = {};
  18. function getMergedValue(target, source, prop, caseless) {
  19. if (utils.isPlainObject(target) && utils.isPlainObject(source)) {
  20. return utils.merge.call({ caseless }, target, source);
  21. } else if (utils.isPlainObject(source)) {
  22. return utils.merge({}, source);
  23. } else if (utils.isArray(source)) {
  24. return source.slice();
  25. }
  26. return source;
  27. }
  28. function mergeDeepProperties(a, b, prop, caseless) {
  29. if (!utils.isUndefined(b)) {
  30. return getMergedValue(a, b, prop, caseless);
  31. } else if (!utils.isUndefined(a)) {
  32. return getMergedValue(undefined, a, prop, caseless);
  33. }
  34. }
  35. // eslint-disable-next-line consistent-return
  36. function valueFromConfig2(a, b) {
  37. if (!utils.isUndefined(b)) {
  38. return getMergedValue(undefined, b);
  39. }
  40. }
  41. // eslint-disable-next-line consistent-return
  42. function defaultToConfig2(a, b) {
  43. if (!utils.isUndefined(b)) {
  44. return getMergedValue(undefined, b);
  45. } else if (!utils.isUndefined(a)) {
  46. return getMergedValue(undefined, a);
  47. }
  48. }
  49. // eslint-disable-next-line consistent-return
  50. function mergeDirectKeys(a, b, prop) {
  51. if (prop in config2) {
  52. return getMergedValue(a, b);
  53. } else if (prop in config1) {
  54. return getMergedValue(undefined, a);
  55. }
  56. }
  57. const mergeMap = {
  58. url: valueFromConfig2,
  59. method: valueFromConfig2,
  60. data: valueFromConfig2,
  61. baseURL: defaultToConfig2,
  62. transformRequest: defaultToConfig2,
  63. transformResponse: defaultToConfig2,
  64. paramsSerializer: defaultToConfig2,
  65. timeout: defaultToConfig2,
  66. timeoutMessage: defaultToConfig2,
  67. withCredentials: defaultToConfig2,
  68. withXSRFToken: defaultToConfig2,
  69. adapter: defaultToConfig2,
  70. responseType: defaultToConfig2,
  71. xsrfCookieName: defaultToConfig2,
  72. xsrfHeaderName: defaultToConfig2,
  73. onUploadProgress: defaultToConfig2,
  74. onDownloadProgress: defaultToConfig2,
  75. decompress: defaultToConfig2,
  76. maxContentLength: defaultToConfig2,
  77. maxBodyLength: defaultToConfig2,
  78. beforeRedirect: defaultToConfig2,
  79. transport: defaultToConfig2,
  80. httpAgent: defaultToConfig2,
  81. httpsAgent: defaultToConfig2,
  82. cancelToken: defaultToConfig2,
  83. socketPath: defaultToConfig2,
  84. responseEncoding: defaultToConfig2,
  85. validateStatus: mergeDirectKeys,
  86. headers: (a, b, prop) =>
  87. mergeDeepProperties(headersToObject(a), headersToObject(b), prop, true),
  88. };
  89. utils.forEach(Object.keys({ ...config1, ...config2 }), function computeConfigValue(prop) {
  90. if (prop === '__proto__' || prop === 'constructor' || prop === 'prototype') return;
  91. const merge = utils.hasOwnProp(mergeMap, prop) ? mergeMap[prop] : mergeDeepProperties;
  92. const configValue = merge(config1[prop], config2[prop], prop);
  93. (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
  94. });
  95. return config;
  96. }