axios 0.18.0 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of axios might be problematic. Click here for more details.

package/index.d.ts CHANGED
@@ -17,12 +17,32 @@ export interface AxiosProxyConfig {
17
17
  auth?: {
18
18
  username: string;
19
19
  password:string;
20
- }
21
- }
20
+ };
21
+ protocol?: string;
22
+ }
23
+
24
+ export type Method =
25
+ | 'get' | 'GET'
26
+ | 'delete' | 'DELETE'
27
+ | 'head' | 'HEAD'
28
+ | 'options' | 'OPTIONS'
29
+ | 'post' | 'POST'
30
+ | 'put' | 'PUT'
31
+ | 'patch' | 'PATCH'
32
+ | 'link' | 'LINK'
33
+ | 'unlink' | 'UNLINK'
34
+
35
+ export type ResponseType =
36
+ | 'arraybuffer'
37
+ | 'blob'
38
+ | 'document'
39
+ | 'json'
40
+ | 'text'
41
+ | 'stream'
22
42
 
23
43
  export interface AxiosRequestConfig {
24
44
  url?: string;
25
- method?: string;
45
+ method?: Method;
26
46
  baseURL?: string;
27
47
  transformRequest?: AxiosTransformer | AxiosTransformer[];
28
48
  transformResponse?: AxiosTransformer | AxiosTransformer[];
@@ -31,10 +51,11 @@ export interface AxiosRequestConfig {
31
51
  paramsSerializer?: (params: any) => string;
32
52
  data?: any;
33
53
  timeout?: number;
54
+ timeoutErrorMessage?: string;
34
55
  withCredentials?: boolean;
35
56
  adapter?: AxiosAdapter;
36
57
  auth?: AxiosBasicCredentials;
37
- responseType?: string;
58
+ responseType?: ResponseType;
38
59
  xsrfCookieName?: string;
39
60
  xsrfHeaderName?: string;
40
61
  onUploadProgress?: (progressEvent: any) => void;
@@ -42,6 +63,7 @@ export interface AxiosRequestConfig {
42
63
  maxContentLength?: number;
43
64
  validateStatus?: (status: number) => boolean;
44
65
  maxRedirects?: number;
66
+ socketPath?: string | null;
45
67
  httpAgent?: any;
46
68
  httpsAgent?: any;
47
69
  proxy?: AxiosProxyConfig | false;
@@ -57,11 +79,13 @@ export interface AxiosResponse<T = any> {
57
79
  request?: any;
58
80
  }
59
81
 
60
- export interface AxiosError extends Error {
82
+ export interface AxiosError<T = any> extends Error {
61
83
  config: AxiosRequestConfig;
62
84
  code?: string;
63
85
  request?: any;
64
- response?: AxiosResponse;
86
+ response?: AxiosResponse<T>;
87
+ isAxiosError: boolean;
88
+ toJSON: () => object;
65
89
  }
66
90
 
67
91
  export interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> {
@@ -108,13 +132,15 @@ export interface AxiosInstance {
108
132
  request: AxiosInterceptorManager<AxiosRequestConfig>;
109
133
  response: AxiosInterceptorManager<AxiosResponse>;
110
134
  };
111
- request<T = any>(config: AxiosRequestConfig): AxiosPromise<T>;
112
- get<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
113
- delete(url: string, config?: AxiosRequestConfig): AxiosPromise;
114
- head(url: string, config?: AxiosRequestConfig): AxiosPromise;
115
- post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
116
- put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
117
- patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
135
+ getUri(config?: AxiosRequestConfig): string;
136
+ request<T = any, R = AxiosResponse<T>> (config: AxiosRequestConfig): Promise<R>;
137
+ get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
138
+ delete<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
139
+ head<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
140
+ options<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
141
+ post<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
142
+ put<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
143
+ patch<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
118
144
  }
119
145
 
120
146
  export interface AxiosStatic extends AxiosInstance {
@@ -2,6 +2,7 @@
2
2
 
3
3
  var utils = require('./../utils');
4
4
  var settle = require('./../core/settle');
5
+ var buildFullPath = require('../core/buildFullPath');
5
6
  var buildURL = require('./../helpers/buildURL');
6
7
  var http = require('http');
7
8
  var https = require('https');
@@ -13,12 +14,19 @@ var pkg = require('./../../package.json');
13
14
  var createError = require('../core/createError');
14
15
  var enhanceError = require('../core/enhanceError');
15
16
 
17
+ var isHttps = /https:?/;
18
+
16
19
  /*eslint consistent-return:0*/
17
20
  module.exports = function httpAdapter(config) {
18
- return new Promise(function dispatchHttpRequest(resolve, reject) {
21
+ return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) {
22
+ var resolve = function resolve(value) {
23
+ resolvePromise(value);
24
+ };
25
+ var reject = function reject(value) {
26
+ rejectPromise(value);
27
+ };
19
28
  var data = config.data;
20
29
  var headers = config.headers;
21
- var timer;
22
30
 
23
31
  // Set User-Agent (required by some servers)
24
32
  // Only set header if it hasn't been set in config
@@ -31,9 +39,9 @@ module.exports = function httpAdapter(config) {
31
39
  if (Buffer.isBuffer(data)) {
32
40
  // Nothing to do...
33
41
  } else if (utils.isArrayBuffer(data)) {
34
- data = new Buffer(new Uint8Array(data));
42
+ data = Buffer.from(new Uint8Array(data));
35
43
  } else if (utils.isString(data)) {
36
- data = new Buffer(data, 'utf-8');
44
+ data = Buffer.from(data, 'utf-8');
37
45
  } else {
38
46
  return reject(createError(
39
47
  'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',
@@ -54,7 +62,8 @@ module.exports = function httpAdapter(config) {
54
62
  }
55
63
 
56
64
  // Parse url
57
- var parsed = url.parse(config.url);
65
+ var fullPath = buildFullPath(config.baseURL, config.url);
66
+ var parsed = url.parse(fullPath);
58
67
  var protocol = parsed.protocol || 'http:';
59
68
 
60
69
  if (!auth && parsed.auth) {
@@ -68,14 +77,15 @@ module.exports = function httpAdapter(config) {
68
77
  delete headers.Authorization;
69
78
  }
70
79
 
71
- var isHttps = protocol === 'https:';
72
- var agent = isHttps ? config.httpsAgent : config.httpAgent;
80
+ var isHttpsRequest = isHttps.test(protocol);
81
+ var agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
73
82
 
74
83
  var options = {
75
84
  path: buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, ''),
76
- method: config.method,
85
+ method: config.method.toUpperCase(),
77
86
  headers: headers,
78
87
  agent: agent,
88
+ agents: { http: config.httpAgent, https: config.httpsAgent },
79
89
  auth: auth
80
90
  };
81
91
 
@@ -92,17 +102,44 @@ module.exports = function httpAdapter(config) {
92
102
  var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()];
93
103
  if (proxyUrl) {
94
104
  var parsedProxyUrl = url.parse(proxyUrl);
95
- proxy = {
96
- host: parsedProxyUrl.hostname,
97
- port: parsedProxyUrl.port
98
- };
99
-
100
- if (parsedProxyUrl.auth) {
101
- var proxyUrlAuth = parsedProxyUrl.auth.split(':');
102
- proxy.auth = {
103
- username: proxyUrlAuth[0],
104
- password: proxyUrlAuth[1]
105
+ var noProxyEnv = process.env.no_proxy || process.env.NO_PROXY;
106
+ var shouldProxy = true;
107
+
108
+ if (noProxyEnv) {
109
+ var noProxy = noProxyEnv.split(',').map(function trim(s) {
110
+ return s.trim();
111
+ });
112
+
113
+ shouldProxy = !noProxy.some(function proxyMatch(proxyElement) {
114
+ if (!proxyElement) {
115
+ return false;
116
+ }
117
+ if (proxyElement === '*') {
118
+ return true;
119
+ }
120
+ if (proxyElement[0] === '.' &&
121
+ parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement) {
122
+ return true;
123
+ }
124
+
125
+ return parsed.hostname === proxyElement;
126
+ });
127
+ }
128
+
129
+
130
+ if (shouldProxy) {
131
+ proxy = {
132
+ host: parsedProxyUrl.hostname,
133
+ port: parsedProxyUrl.port
105
134
  };
135
+
136
+ if (parsedProxyUrl.auth) {
137
+ var proxyUrlAuth = parsedProxyUrl.auth.split(':');
138
+ proxy.auth = {
139
+ username: proxyUrlAuth[0],
140
+ password: proxyUrlAuth[1]
141
+ };
142
+ }
106
143
  }
107
144
  }
108
145
  }
@@ -116,21 +153,22 @@ module.exports = function httpAdapter(config) {
116
153
 
117
154
  // Basic proxy authorization
118
155
  if (proxy.auth) {
119
- var base64 = new Buffer(proxy.auth.username + ':' + proxy.auth.password, 'utf8').toString('base64');
156
+ var base64 = Buffer.from(proxy.auth.username + ':' + proxy.auth.password, 'utf8').toString('base64');
120
157
  options.headers['Proxy-Authorization'] = 'Basic ' + base64;
121
158
  }
122
159
  }
123
160
 
124
161
  var transport;
162
+ var isHttpsProxy = isHttpsRequest && (proxy ? isHttps.test(proxy.protocol) : true);
125
163
  if (config.transport) {
126
164
  transport = config.transport;
127
165
  } else if (config.maxRedirects === 0) {
128
- transport = isHttps ? https : http;
166
+ transport = isHttpsProxy ? https : http;
129
167
  } else {
130
168
  if (config.maxRedirects) {
131
169
  options.maxRedirects = config.maxRedirects;
132
170
  }
133
- transport = isHttps ? httpsFollow : httpFollow;
171
+ transport = isHttpsProxy ? httpsFollow : httpFollow;
134
172
  }
135
173
 
136
174
  if (config.maxContentLength && config.maxContentLength > -1) {
@@ -141,10 +179,6 @@ module.exports = function httpAdapter(config) {
141
179
  var req = transport.request(options, function handleResponse(res) {
142
180
  if (req.aborted) return;
143
181
 
144
- // Response has been received so kill timer that handles request timeout
145
- clearTimeout(timer);
146
- timer = null;
147
-
148
182
  // uncompress the response body transparently if required
149
183
  var stream = res;
150
184
  switch (res.headers['content-encoding']) {
@@ -153,7 +187,7 @@ module.exports = function httpAdapter(config) {
153
187
  case 'compress':
154
188
  case 'deflate':
155
189
  // add the unzipper to the body stream processing pipeline
156
- stream = stream.pipe(zlib.createUnzip());
190
+ stream = (res.statusCode === 204) ? stream : stream.pipe(zlib.createUnzip());
157
191
 
158
192
  // remove the content-encoding in order to not confuse downstream operations
159
193
  delete res.headers['content-encoding'];
@@ -181,6 +215,7 @@ module.exports = function httpAdapter(config) {
181
215
 
182
216
  // make sure the content length is not over the maxContentLength if specified
183
217
  if (config.maxContentLength > -1 && Buffer.concat(responseBuffer).length > config.maxContentLength) {
218
+ stream.destroy();
184
219
  reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
185
220
  config, null, lastRequest));
186
221
  }
@@ -194,7 +229,7 @@ module.exports = function httpAdapter(config) {
194
229
  stream.on('end', function handleStreamEnd() {
195
230
  var responseData = Buffer.concat(responseBuffer);
196
231
  if (config.responseType !== 'arraybuffer') {
197
- responseData = responseData.toString('utf8');
232
+ responseData = responseData.toString(config.responseEncoding);
198
233
  }
199
234
 
200
235
  response.data = responseData;
@@ -210,11 +245,16 @@ module.exports = function httpAdapter(config) {
210
245
  });
211
246
 
212
247
  // Handle request timeout
213
- if (config.timeout && !timer) {
214
- timer = setTimeout(function handleRequestTimeout() {
248
+ if (config.timeout) {
249
+ // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.
250
+ // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET.
251
+ // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up.
252
+ // And then these socket which be hang up will devoring CPU little by little.
253
+ // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.
254
+ req.setTimeout(config.timeout, function handleRequestTimeout() {
215
255
  req.abort();
216
256
  reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', req));
217
- }, config.timeout);
257
+ });
218
258
  }
219
259
 
220
260
  if (config.cancelToken) {
@@ -229,7 +269,9 @@ module.exports = function httpAdapter(config) {
229
269
 
230
270
  // Send the request
231
271
  if (utils.isStream(data)) {
232
- data.pipe(req);
272
+ data.on('error', function handleStreamError(err) {
273
+ reject(enhanceError(err, config, null, req));
274
+ }).pipe(req);
233
275
  } else {
234
276
  req.end(data);
235
277
  }
@@ -3,10 +3,10 @@
3
3
  var utils = require('./../utils');
4
4
  var settle = require('./../core/settle');
5
5
  var buildURL = require('./../helpers/buildURL');
6
+ var buildFullPath = require('../core/buildFullPath');
6
7
  var parseHeaders = require('./../helpers/parseHeaders');
7
8
  var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
8
9
  var createError = require('../core/createError');
9
- var btoa = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || require('./../helpers/btoa');
10
10
 
11
11
  module.exports = function xhrAdapter(config) {
12
12
  return new Promise(function dispatchXhrRequest(resolve, reject) {
@@ -18,22 +18,6 @@ module.exports = function xhrAdapter(config) {
18
18
  }
19
19
 
20
20
  var request = new XMLHttpRequest();
21
- var loadEvent = 'onreadystatechange';
22
- var xDomain = false;
23
-
24
- // For IE 8/9 CORS support
25
- // Only supports POST and GET calls and doesn't returns the response headers.
26
- // DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest.
27
- if (process.env.NODE_ENV !== 'test' &&
28
- typeof window !== 'undefined' &&
29
- window.XDomainRequest && !('withCredentials' in request) &&
30
- !isURLSameOrigin(config.url)) {
31
- request = new window.XDomainRequest();
32
- loadEvent = 'onload';
33
- xDomain = true;
34
- request.onprogress = function handleProgress() {};
35
- request.ontimeout = function handleTimeout() {};
36
- }
37
21
 
38
22
  // HTTP basic authentication
39
23
  if (config.auth) {
@@ -42,14 +26,15 @@ module.exports = function xhrAdapter(config) {
42
26
  requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
43
27
  }
44
28
 
45
- request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);
29
+ var fullPath = buildFullPath(config.baseURL, config.url);
30
+ request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
46
31
 
47
32
  // Set the request timeout in MS
48
33
  request.timeout = config.timeout;
49
34
 
50
35
  // Listen for ready state
51
- request[loadEvent] = function handleLoad() {
52
- if (!request || (request.readyState !== 4 && !xDomain)) {
36
+ request.onreadystatechange = function handleLoad() {
37
+ if (!request || request.readyState !== 4) {
53
38
  return;
54
39
  }
55
40
 
@@ -66,9 +51,8 @@ module.exports = function xhrAdapter(config) {
66
51
  var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
67
52
  var response = {
68
53
  data: responseData,
69
- // IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201)
70
- status: request.status === 1223 ? 204 : request.status,
71
- statusText: request.status === 1223 ? 'No Content' : request.statusText,
54
+ status: request.status,
55
+ statusText: request.statusText,
72
56
  headers: responseHeaders,
73
57
  config: config,
74
58
  request: request
@@ -80,6 +64,18 @@ module.exports = function xhrAdapter(config) {
80
64
  request = null;
81
65
  };
82
66
 
67
+ // Handle browser request cancellation (as opposed to a manual cancellation)
68
+ request.onabort = function handleAbort() {
69
+ if (!request) {
70
+ return;
71
+ }
72
+
73
+ reject(createError('Request aborted', config, 'ECONNABORTED', request));
74
+
75
+ // Clean up request
76
+ request = null;
77
+ };
78
+
83
79
  // Handle low level network errors
84
80
  request.onerror = function handleError() {
85
81
  // Real errors are hidden from us by the browser
@@ -92,7 +88,11 @@ module.exports = function xhrAdapter(config) {
92
88
 
93
89
  // Handle timeout
94
90
  request.ontimeout = function handleTimeout() {
95
- reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
91
+ var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';
92
+ if (config.timeoutErrorMessage) {
93
+ timeoutErrorMessage = config.timeoutErrorMessage;
94
+ }
95
+ reject(createError(timeoutErrorMessage, config, 'ECONNABORTED',
96
96
  request));
97
97
 
98
98
  // Clean up request
@@ -106,9 +106,9 @@ module.exports = function xhrAdapter(config) {
106
106
  var cookies = require('./../helpers/cookies');
107
107
 
108
108
  // Add xsrf header
109
- var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
110
- cookies.read(config.xsrfCookieName) :
111
- undefined;
109
+ var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?
110
+ cookies.read(config.xsrfCookieName) :
111
+ undefined;
112
112
 
113
113
  if (xsrfValue) {
114
114
  requestHeaders[config.xsrfHeaderName] = xsrfValue;
@@ -129,8 +129,8 @@ module.exports = function xhrAdapter(config) {
129
129
  }
130
130
 
131
131
  // Add withCredentials to request if needed
132
- if (config.withCredentials) {
133
- request.withCredentials = true;
132
+ if (!utils.isUndefined(config.withCredentials)) {
133
+ request.withCredentials = !!config.withCredentials;
134
134
  }
135
135
 
136
136
  // Add responseType to request if needed
package/lib/axios.js CHANGED
@@ -3,6 +3,7 @@
3
3
  var utils = require('./utils');
4
4
  var bind = require('./helpers/bind');
5
5
  var Axios = require('./core/Axios');
6
+ var mergeConfig = require('./core/mergeConfig');
6
7
  var defaults = require('./defaults');
7
8
 
8
9
  /**
@@ -32,7 +33,7 @@ axios.Axios = Axios;
32
33
 
33
34
  // Factory for creating new instances
34
35
  axios.create = function create(instanceConfig) {
35
- return createInstance(utils.merge(defaults, instanceConfig));
36
+ return createInstance(mergeConfig(axios.defaults, instanceConfig));
36
37
  };
37
38
 
38
39
  // Expose Cancel & CancelToken
package/lib/core/Axios.js CHANGED
@@ -1,9 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var defaults = require('./../defaults');
4
3
  var utils = require('./../utils');
4
+ var buildURL = require('../helpers/buildURL');
5
5
  var InterceptorManager = require('./InterceptorManager');
6
6
  var dispatchRequest = require('./dispatchRequest');
7
+ var mergeConfig = require('./mergeConfig');
7
8
 
8
9
  /**
9
10
  * Create a new instance of Axios
@@ -27,13 +28,22 @@ Axios.prototype.request = function request(config) {
27
28
  /*eslint no-param-reassign:0*/
28
29
  // Allow for axios('example/url'[, config]) a la fetch API
29
30
  if (typeof config === 'string') {
30
- config = utils.merge({
31
- url: arguments[0]
32
- }, arguments[1]);
31
+ config = arguments[1] || {};
32
+ config.url = arguments[0];
33
+ } else {
34
+ config = config || {};
33
35
  }
34
36
 
35
- config = utils.merge(defaults, {method: 'get'}, this.defaults, config);
36
- config.method = config.method.toLowerCase();
37
+ config = mergeConfig(this.defaults, config);
38
+
39
+ // Set config.method
40
+ if (config.method) {
41
+ config.method = config.method.toLowerCase();
42
+ } else if (this.defaults.method) {
43
+ config.method = this.defaults.method.toLowerCase();
44
+ } else {
45
+ config.method = 'get';
46
+ }
37
47
 
38
48
  // Hook up interceptors middleware
39
49
  var chain = [dispatchRequest, undefined];
@@ -54,6 +64,11 @@ Axios.prototype.request = function request(config) {
54
64
  return promise;
55
65
  };
56
66
 
67
+ Axios.prototype.getUri = function getUri(config) {
68
+ config = mergeConfig(this.defaults, config);
69
+ return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, '');
70
+ };
71
+
57
72
  // Provide aliases for supported request methods
58
73
  utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
59
74
  /*eslint func-names:0*/
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var isAbsoluteURL = require('../helpers/isAbsoluteURL');
4
+ var combineURLs = require('../helpers/combineURLs');
5
+
6
+ /**
7
+ * Creates a new URL by combining the baseURL with the requestedURL,
8
+ * only when the requestedURL is not already an absolute URL.
9
+ * If the requestURL is absolute, this function returns the requestedURL untouched.
10
+ *
11
+ * @param {string} baseURL The base URL
12
+ * @param {string} requestedURL Absolute or relative URL to combine
13
+ * @returns {string} The combined full path
14
+ */
15
+ module.exports = function buildFullPath(baseURL, requestedURL) {
16
+ if (baseURL && !isAbsoluteURL(requestedURL)) {
17
+ return combineURLs(baseURL, requestedURL);
18
+ }
19
+ return requestedURL;
20
+ };
@@ -4,8 +4,6 @@ var utils = require('./../utils');
4
4
  var transformData = require('./transformData');
5
5
  var isCancel = require('../cancel/isCancel');
6
6
  var defaults = require('../defaults');
7
- var isAbsoluteURL = require('./../helpers/isAbsoluteURL');
8
- var combineURLs = require('./../helpers/combineURLs');
9
7
 
10
8
  /**
11
9
  * Throws a `Cancel` if cancellation has been requested.
@@ -25,11 +23,6 @@ function throwIfCancellationRequested(config) {
25
23
  module.exports = function dispatchRequest(config) {
26
24
  throwIfCancellationRequested(config);
27
25
 
28
- // Support baseURL config
29
- if (config.baseURL && !isAbsoluteURL(config.url)) {
30
- config.url = combineURLs(config.baseURL, config.url);
31
- }
32
-
33
26
  // Ensure headers exist
34
27
  config.headers = config.headers || {};
35
28
 
@@ -44,7 +37,7 @@ module.exports = function dispatchRequest(config) {
44
37
  config.headers = utils.merge(
45
38
  config.headers.common || {},
46
39
  config.headers[config.method] || {},
47
- config.headers || {}
40
+ config.headers
48
41
  );
49
42
 
50
43
  utils.forEach(
@@ -15,7 +15,28 @@ module.exports = function enhanceError(error, config, code, request, response) {
15
15
  if (code) {
16
16
  error.code = code;
17
17
  }
18
+
18
19
  error.request = request;
19
20
  error.response = response;
21
+ error.isAxiosError = true;
22
+
23
+ error.toJSON = function() {
24
+ return {
25
+ // Standard
26
+ message: this.message,
27
+ name: this.name,
28
+ // Microsoft
29
+ description: this.description,
30
+ number: this.number,
31
+ // Mozilla
32
+ fileName: this.fileName,
33
+ lineNumber: this.lineNumber,
34
+ columnNumber: this.columnNumber,
35
+ stack: this.stack,
36
+ // Axios
37
+ config: this.config,
38
+ code: this.code
39
+ };
40
+ };
20
41
  return error;
21
42
  };
@@ -0,0 +1,73 @@
1
+ 'use strict';
2
+
3
+ var utils = require('../utils');
4
+
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
+ * @returns {Object} New object resulting from merging config2 to config1
12
+ */
13
+ module.exports = function mergeConfig(config1, config2) {
14
+ // eslint-disable-next-line no-param-reassign
15
+ config2 = config2 || {};
16
+ var config = {};
17
+
18
+ var valueFromConfig2Keys = ['url', 'method', 'params', 'data'];
19
+ var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy'];
20
+ var defaultToConfig2Keys = [
21
+ 'baseURL', 'url', 'transformRequest', 'transformResponse', 'paramsSerializer',
22
+ 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
23
+ 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress',
24
+ 'maxContentLength', 'validateStatus', 'maxRedirects', 'httpAgent',
25
+ 'httpsAgent', 'cancelToken', 'socketPath'
26
+ ];
27
+
28
+ utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {
29
+ if (typeof config2[prop] !== 'undefined') {
30
+ config[prop] = config2[prop];
31
+ }
32
+ });
33
+
34
+ utils.forEach(mergeDeepPropertiesKeys, function mergeDeepProperties(prop) {
35
+ if (utils.isObject(config2[prop])) {
36
+ config[prop] = utils.deepMerge(config1[prop], config2[prop]);
37
+ } else if (typeof config2[prop] !== 'undefined') {
38
+ config[prop] = config2[prop];
39
+ } else if (utils.isObject(config1[prop])) {
40
+ config[prop] = utils.deepMerge(config1[prop]);
41
+ } else if (typeof config1[prop] !== 'undefined') {
42
+ config[prop] = config1[prop];
43
+ }
44
+ });
45
+
46
+ utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {
47
+ if (typeof config2[prop] !== 'undefined') {
48
+ config[prop] = config2[prop];
49
+ } else if (typeof config1[prop] !== 'undefined') {
50
+ config[prop] = config1[prop];
51
+ }
52
+ });
53
+
54
+ var axiosKeys = valueFromConfig2Keys
55
+ .concat(mergeDeepPropertiesKeys)
56
+ .concat(defaultToConfig2Keys);
57
+
58
+ var otherKeys = Object
59
+ .keys(config2)
60
+ .filter(function filterAxiosKeys(key) {
61
+ return axiosKeys.indexOf(key) === -1;
62
+ });
63
+
64
+ utils.forEach(otherKeys, function otherKeysDefaultToConfig2(prop) {
65
+ if (typeof config2[prop] !== 'undefined') {
66
+ config[prop] = config2[prop];
67
+ } else if (typeof config1[prop] !== 'undefined') {
68
+ config[prop] = config1[prop];
69
+ }
70
+ });
71
+
72
+ return config;
73
+ };
@@ -11,8 +11,7 @@ var createError = require('./createError');
11
11
  */
12
12
  module.exports = function settle(resolve, reject, response) {
13
13
  var validateStatus = response.config.validateStatus;
14
- // Note: status is not exposed by XDomainRequest
15
- if (!response.status || !validateStatus || validateStatus(response.status)) {
14
+ if (!validateStatus || validateStatus(response.status)) {
16
15
  resolve(response);
17
16
  } else {
18
17
  reject(createError(