axios
Version:
Promise based HTTP client for the browser and node.js
118 lines (105 loc) • 4.07 kB
JavaScript
;
var utils = require('../utils');
/**
* Config-specific merge-function which creates a new config-object
* by merging two configuration objects together.
*
* @param {Object} config1
* @param {Object} config2
* @returns {Object} New object resulting from merging config2 to config1
*/
module.exports = function mergeConfig(config1, config2) {
// eslint-disable-next-line no-param-reassign
config2 = config2 || {};
// Use a null-prototype object so a polluted Object.prototype cannot leak
// values (e.g. transport, adapter) into the returned config via inheritance.
var config = Object.create(null);
function getOwn(source, prop) {
return utils.hasOwnProperty(source, prop) ? source[prop] : undefined;
}
function hasOwn(source, prop) {
return utils.hasOwnProperty(source, prop);
}
function getMergedValue(target, source) {
if (utils.isPlainObject(target) && utils.isPlainObject(source)) {
return utils.merge(target, source);
} else if (utils.isEmptyObject(source)) {
return utils.merge({}, target);
} else if (utils.isPlainObject(source)) {
return utils.merge({}, source);
} else if (utils.isArray(source)) {
return source.slice();
}
return source;
}
// eslint-disable-next-line consistent-return
function mergeDeepProperties(prop) {
if (hasOwn(config2, prop) && !utils.isUndefined(config2[prop])) {
return getMergedValue(getOwn(config1, prop), config2[prop]);
} else if (hasOwn(config1, prop) && !utils.isUndefined(config1[prop])) {
return getMergedValue(undefined, config1[prop]);
}
}
// eslint-disable-next-line consistent-return
function valueFromConfig2(prop) {
if (hasOwn(config2, prop) && !utils.isUndefined(config2[prop])) {
return getMergedValue(undefined, config2[prop]);
}
}
// eslint-disable-next-line consistent-return
function defaultToConfig2(prop) {
if (hasOwn(config2, prop) && !utils.isUndefined(config2[prop])) {
return getMergedValue(undefined, config2[prop]);
} else if (hasOwn(config1, prop) && !utils.isUndefined(config1[prop])) {
return getMergedValue(undefined, config1[prop]);
}
}
// eslint-disable-next-line consistent-return
function mergeDirectKeys(prop) {
if (hasOwn(config2, prop)) {
return getMergedValue(getOwn(config1, prop), config2[prop]);
} else if (hasOwn(config1, prop)) {
return getMergedValue(undefined, config1[prop]);
}
}
var mergeMap = {
'url': valueFromConfig2,
'method': valueFromConfig2,
'data': valueFromConfig2,
'baseURL': defaultToConfig2,
'transformRequest': defaultToConfig2,
'transformResponse': defaultToConfig2,
'paramsSerializer': defaultToConfig2,
'timeout': defaultToConfig2,
'timeoutMessage': defaultToConfig2,
'withCredentials': defaultToConfig2,
'withXSRFToken': defaultToConfig2,
'adapter': defaultToConfig2,
'responseType': defaultToConfig2,
'xsrfCookieName': defaultToConfig2,
'xsrfHeaderName': defaultToConfig2,
'onUploadProgress': defaultToConfig2,
'onDownloadProgress': defaultToConfig2,
'decompress': defaultToConfig2,
'maxContentLength': defaultToConfig2,
'maxBodyLength': defaultToConfig2,
'beforeRedirect': defaultToConfig2,
'transport': defaultToConfig2,
'httpAgent': defaultToConfig2,
'httpsAgent': defaultToConfig2,
'cancelToken': defaultToConfig2,
'socketPath': defaultToConfig2,
'allowedSocketPaths': defaultToConfig2,
'responseEncoding': defaultToConfig2,
'validateStatus': mergeDirectKeys
};
utils.forEach(Object.keys(config1).concat(Object.keys(config2)), function computeConfigValue(prop) {
if (prop === '__proto__' || prop === 'constructor' || prop === 'prototype') {
return;
}
var merge = utils.hasOwnProperty(mergeMap, prop) ? mergeMap[prop] : mergeDeepProperties;
var configValue = merge(prop);
(utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
});
return config;
};