From 72c66dfdecbcc165c52fcd19d1f8444ad8c011c6 Mon Sep 17 00:00:00 2001 From: Martti Laine Date: Fri, 23 Mar 2018 20:21:02 +0100 Subject: [PATCH] Refactor and introduce deepMerge --- lib/axios.js | 3 +- lib/core/Axios.js | 3 +- lib/core/mergeConfig.js | 44 +++++++++++++++++++++++++++ lib/utils.js | 67 +++++++++++++++++------------------------ 4 files changed, 76 insertions(+), 41 deletions(-) create mode 100644 lib/core/mergeConfig.js diff --git a/lib/axios.js b/lib/axios.js index 11e274c..8142437 100644 --- a/lib/axios.js +++ b/lib/axios.js @@ -3,6 +3,7 @@ var utils = require('./utils'); var bind = require('./helpers/bind'); var Axios = require('./core/Axios'); +var mergeConfig = require('./core/mergeConfig'); var defaults = require('./defaults'); /** @@ -32,7 +33,7 @@ axios.Axios = Axios; // Factory for creating new instances axios.create = function create(instanceConfig) { - return createInstance(utils.mergeConfig(axios.defaults, instanceConfig)); + return createInstance(mergeConfig(axios.defaults, instanceConfig)); }; // Expose Cancel & CancelToken diff --git a/lib/core/Axios.js b/lib/core/Axios.js index 92865d3..8407a96 100644 --- a/lib/core/Axios.js +++ b/lib/core/Axios.js @@ -3,6 +3,7 @@ var utils = require('./../utils'); var InterceptorManager = require('./InterceptorManager'); var dispatchRequest = require('./dispatchRequest'); +var mergeConfig = require('./mergeConfig'); /** * Create a new instance of Axios @@ -32,7 +33,7 @@ Axios.prototype.request = function request(config) { config = config || {}; } - config = utils.mergeConfig(this.defaults, config); + config = mergeConfig(this.defaults, config); config.method = config.method ? config.method.toLowerCase() : 'get'; // Hook up interceptors middleware diff --git a/lib/core/mergeConfig.js b/lib/core/mergeConfig.js new file mode 100644 index 0000000..fea1238 --- /dev/null +++ b/lib/core/mergeConfig.js @@ -0,0 +1,44 @@ +'use strict'; + +var utils = require('../utils'); + +/** + * Config-specific merge-function which creates a new config-object + * based on given defaults and instance config. + * + * @param {Object} defaults Defaults + * @param {Object} instanceConfig Instance-specific config + * @returns {Object} New object resulting from merging instanceConfig to defaults + */ +module.exports = function mergeConfig(defaults, instanceConfig) { + // eslint-disable-next-line no-param-reassign + instanceConfig = instanceConfig || {}; + var config = {}; + + utils.forEach(['url', 'method', 'params', 'data'], function valueFromInstanceConfig(prop) { + config[prop] = instanceConfig[prop]; + }); + + utils.forEach(['headers', 'auth', 'proxy'], function mergeInstanceConfigWithDefaults(prop) { + if (typeof instanceConfig[prop] !== 'undefined') { + if (typeof instanceConfig[prop] === 'object') { + config[prop] = utils.deepMerge(defaults[prop], instanceConfig[prop]); + } else { + config[prop] = instanceConfig[prop]; + } + } else if (typeof defaults[prop] !== 'undefined') { + config[prop] = utils.deepMerge(defaults[prop]); + } + }); + + utils.forEach([ + 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer', + 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', + 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength', + 'validateStatus', 'maxRedirects', 'httpAgent', 'httpsAgent', 'cancelToken' + ], function defaultToInstanceConfig(prop) { + config[prop] = typeof instanceConfig[prop] === 'undefined' ? defaults[prop] : instanceConfig[prop]; + }); + + return config; +}; diff --git a/lib/utils.js b/lib/utils.js index 14225bd..856aba3 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -260,6 +260,32 @@ function merge(/* obj1, obj2, obj3, ... */) { return result; } +/** + * Function equal to merge with the difference being that no reference + * to original objects is kept. + * + * @see merge + * @param {Object} obj1 Object to merge + * @returns {Object} Result of all merge properties + */ +function deepMerge(/* obj1, obj2, obj3, ... */) { + var result = {}; + function assignValue(val, key) { + if (typeof result[key] === 'object' && typeof val === 'object') { + result[key] = merge(result[key], val); + } else if (typeof val === 'object') { + result[key] = merge({}, val); + } else { + result[key] = val; + } + } + + for (var i = 0, l = arguments.length; i < l; i++) { + forEach(arguments[i], assignValue); + } + return result; +} + /** * Extends object a by mutably adding to it the properties of object b. * @@ -279,43 +305,6 @@ function extend(a, b, thisArg) { return a; } - -/** - * Config-specific merge-function which creates a new config-object - * based on given defaults and instance config. - * - * @param {Object} defaults Defaults - * @param {Object} instanceConfig Instance-specific config - * @returns {Object} New object resulting from merging instanceConfig to defaults - */ -function mergeConfig(defaults, instanceConfig) { - instanceConfig = instanceConfig || {}; - var config = {}; - forEach(['url', 'method', 'params', 'data'], function valueFromInstanceConfig(prop) { - config[prop] = instanceConfig[prop]; - }); - forEach(['headers', 'auth', 'proxy'], function mergeInstanceConfigWithDefaults(prop) { - if (!isUndefined(instanceConfig[prop])) { - if (isObject(instanceConfig[prop])) { - config[prop] = merge(defaults[prop], instanceConfig[prop]); - } else { - config[prop] = instanceConfig[prop]; - } - } else if (!isUndefined(defaults[prop])) { - config[prop] = JSON.parse(JSON.stringify(defaults[prop])); - } - }); - forEach([ - 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer', - 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', - 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength', - 'validateStatus', 'maxRedirects', 'httpAgent', 'httpsAgent', 'cancelToken' - ], function defaultToInstanceConfig(prop) { - config[prop] = isUndefined(instanceConfig[prop]) ? defaults[prop] : instanceConfig[prop]; - }); - return config; -} - module.exports = { isArray: isArray, isArrayBuffer: isArrayBuffer, @@ -335,7 +324,7 @@ module.exports = { isStandardBrowserEnv: isStandardBrowserEnv, forEach: forEach, merge: merge, + deepMerge: deepMerge, extend: extend, - trim: trim, - mergeConfig: mergeConfig + trim: trim }; -- GitLab