axios 0.27.0 → 1.0.0-alpha.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +124 -927
  2. package/LICENSE +4 -16
  3. package/README.md +257 -69
  4. package/SECURITY.md +3 -3
  5. package/UPGRADE_GUIDE.md +1 -166
  6. package/bin/ssl_hotfix.js +22 -0
  7. package/dist/axios.js +1956 -3592
  8. package/dist/axios.js.map +1 -0
  9. package/dist/axios.min.js +2 -4
  10. package/dist/axios.min.js.map +1 -0
  11. package/dist/esm/axios.js +2336 -0
  12. package/dist/esm/axios.js.map +1 -0
  13. package/dist/esm/axios.min.js +2 -0
  14. package/dist/esm/axios.min.js.map +1 -0
  15. package/index.d.ts +96 -18
  16. package/lib/adapters/http.js +154 -113
  17. package/lib/adapters/xhr.js +12 -11
  18. package/lib/axios.js +5 -1
  19. package/lib/cancel/CancelToken.js +4 -5
  20. package/lib/cancel/CanceledError.js +4 -2
  21. package/lib/core/Axios.js +2 -1
  22. package/lib/core/AxiosError.js +12 -1
  23. package/lib/core/InterceptorManager.js +9 -0
  24. package/lib/core/dispatchRequest.js +7 -0
  25. package/lib/core/transformData.js +3 -2
  26. package/lib/defaults/index.js +45 -13
  27. package/lib/{defaults/env → env/classes}/FormData.js +0 -0
  28. package/lib/env/data.js +1 -1
  29. package/lib/helpers/AxiosURLSearchParams.js +42 -0
  30. package/lib/helpers/bind.js +1 -5
  31. package/lib/helpers/buildURL.js +14 -37
  32. package/lib/helpers/formDataToJSON.js +71 -0
  33. package/lib/helpers/fromDataURI.js +51 -0
  34. package/lib/helpers/isURLSameOrigin.js +12 -12
  35. package/lib/helpers/parseHeaders.js +2 -2
  36. package/lib/helpers/parseProtocol.js +6 -0
  37. package/lib/helpers/toFormData.js +141 -34
  38. package/lib/helpers/toURLEncodedForm.js +18 -0
  39. package/lib/platform/browser/classes/FormData.js +3 -0
  40. package/lib/platform/browser/classes/URLSearchParams.js +5 -0
  41. package/lib/platform/browser/index.js +11 -0
  42. package/lib/platform/index.js +3 -0
  43. package/lib/platform/node/classes/FormData.js +3 -0
  44. package/lib/platform/node/classes/URLSearchParams.js +5 -0
  45. package/lib/platform/node/index.js +11 -0
  46. package/lib/utils.js +57 -34
  47. package/package.json +18 -8
  48. package/rollup.config.js +60 -0
  49. package/dist/axios.map +0 -1
  50. package/dist/axios.min.map +0 -1
@@ -4,41 +4,79 @@ var utils = require('./../utils');
4
4
  var settle = require('./../core/settle');
5
5
  var buildFullPath = require('../core/buildFullPath');
6
6
  var buildURL = require('./../helpers/buildURL');
7
+ var getProxyForUrl = require('proxy-from-env').getProxyForUrl;
7
8
  var http = require('http');
8
9
  var https = require('https');
9
- var httpFollow = require('follow-redirects').http;
10
- var httpsFollow = require('follow-redirects').https;
10
+ var httpFollow = require('follow-redirects/http');
11
+ var httpsFollow = require('follow-redirects/https');
11
12
  var url = require('url');
12
13
  var zlib = require('zlib');
13
14
  var VERSION = require('./../env/data').version;
14
15
  var transitionalDefaults = require('../defaults/transitional');
15
16
  var AxiosError = require('../core/AxiosError');
16
17
  var CanceledError = require('../cancel/CanceledError');
18
+ var platform = require('../platform');
19
+ var fromDataURI = require('../helpers/fromDataURI');
20
+ var stream = require('stream');
17
21
 
18
22
  var isHttps = /https:?/;
19
23
 
24
+ var supportedProtocols = platform.protocols.map(function(protocol) {
25
+ return protocol + ':';
26
+ });
27
+
28
+ function dispatchBeforeRedirect(options) {
29
+ if (options.beforeRedirects.proxy) {
30
+ options.beforeRedirects.proxy(options);
31
+ }
32
+ if (options.beforeRedirects.config) {
33
+ options.beforeRedirects.config(options);
34
+ }
35
+ }
36
+
20
37
  /**
21
38
  *
22
39
  * @param {http.ClientRequestArgs} options
23
- * @param {AxiosProxyConfig} proxy
40
+ * @param {AxiosProxyConfig} configProxy
24
41
  * @param {string} location
25
42
  */
26
- function setProxy(options, proxy, location) {
27
- options.hostname = proxy.host;
28
- options.host = proxy.host;
29
- options.port = proxy.port;
30
- options.path = location;
31
-
32
- // Basic proxy authorization
33
- if (proxy.auth) {
34
- var base64 = Buffer.from(proxy.auth.username + ':' + proxy.auth.password, 'utf8').toString('base64');
35
- options.headers['Proxy-Authorization'] = 'Basic ' + base64;
43
+ function setProxy(options, configProxy, location) {
44
+ var proxy = configProxy;
45
+ if (!proxy && proxy !== false) {
46
+ var proxyUrl = getProxyForUrl(location);
47
+ if (proxyUrl) {
48
+ proxy = url.parse(proxyUrl);
49
+ // replace 'host' since the proxy object is not a URL object
50
+ proxy.host = proxy.hostname;
51
+ }
36
52
  }
53
+ if (proxy) {
54
+ // Basic proxy authorization
55
+ if (proxy.auth) {
56
+ // Support proxy auth object form
57
+ if (proxy.auth.username || proxy.auth.password) {
58
+ proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || '');
59
+ }
60
+ var base64 = Buffer
61
+ .from(proxy.auth, 'utf8')
62
+ .toString('base64');
63
+ options.headers['Proxy-Authorization'] = 'Basic ' + base64;
64
+ }
37
65
 
38
- // If a proxy is used, any redirects must also pass through the proxy
39
- options.beforeRedirect = function beforeRedirect(redirection) {
40
- redirection.headers.host = redirection.host;
41
- setProxy(redirection, proxy, redirection.href);
66
+ options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
67
+ options.hostname = proxy.host;
68
+ options.host = proxy.host;
69
+ options.port = proxy.port;
70
+ options.path = location;
71
+ if (proxy.protocol) {
72
+ options.protocol = proxy.protocol;
73
+ }
74
+ }
75
+
76
+ options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {
77
+ // Configure proxy for redirected request, passing the original config proxy to apply
78
+ // the exact same logic as if the redirected request was performed by axios directly.
79
+ setProxy(redirectOptions, configProxy, redirectOptions.href);
42
80
  };
43
81
  }
44
82
 
@@ -66,6 +104,62 @@ module.exports = function httpAdapter(config) {
66
104
  rejectPromise(value);
67
105
  };
68
106
  var data = config.data;
107
+ var responseType = config.responseType;
108
+ var responseEncoding = config.responseEncoding;
109
+ var method = config.method.toUpperCase();
110
+
111
+ // Parse url
112
+ var fullPath = buildFullPath(config.baseURL, config.url);
113
+ var parsed = url.parse(fullPath);
114
+ var protocol = parsed.protocol || supportedProtocols[0];
115
+
116
+ if (protocol === 'data:') {
117
+ var convertedData;
118
+
119
+ if (method !== 'GET') {
120
+ return settle(resolve, reject, {
121
+ status: 405,
122
+ statusText: 'method not allowed',
123
+ headers: {},
124
+ config: config
125
+ });
126
+ }
127
+
128
+ try {
129
+ convertedData = fromDataURI(config.url, responseType === 'blob', {
130
+ Blob: config.env && config.env.Blob
131
+ });
132
+ } catch (err) {
133
+ throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config);
134
+ }
135
+
136
+ if (responseType === 'text') {
137
+ convertedData = convertedData.toString(responseEncoding);
138
+
139
+ if (!responseEncoding || responseEncoding === 'utf8') {
140
+ data = utils.stripBOM(convertedData);
141
+ }
142
+ } else if (responseType === 'stream') {
143
+ convertedData = stream.Readable.from(convertedData);
144
+ }
145
+
146
+ return settle(resolve, reject, {
147
+ data: convertedData,
148
+ status: 200,
149
+ statusText: 'OK',
150
+ headers: {},
151
+ config: config
152
+ });
153
+ }
154
+
155
+ if (supportedProtocols.indexOf(protocol) === -1) {
156
+ return reject(new AxiosError(
157
+ 'Unsupported protocol ' + protocol,
158
+ AxiosError.ERR_BAD_REQUEST,
159
+ config
160
+ ));
161
+ }
162
+
69
163
  var headers = config.headers;
70
164
  var headerNames = {};
71
165
 
@@ -126,19 +220,6 @@ module.exports = function httpAdapter(config) {
126
220
  auth = username + ':' + password;
127
221
  }
128
222
 
129
- // Parse url
130
- var fullPath = buildFullPath(config.baseURL, config.url);
131
- var parsed = url.parse(fullPath);
132
- var protocol = utils.getProtocol(parsed.protocol);
133
-
134
- if (!utils.supportedProtocols.includes(protocol)) {
135
- return reject(new AxiosError(
136
- 'Unsupported protocol ' + protocol,
137
- AxiosError.ERR_BAD_REQUEST,
138
- config
139
- ));
140
- }
141
-
142
223
  if (!auth && parsed.auth) {
143
224
  var urlAuth = parsed.auth.split(':');
144
225
  var urlUsername = urlAuth[0] || '';
@@ -150,9 +231,6 @@ module.exports = function httpAdapter(config) {
150
231
  delete headers[headerNames.authorization];
151
232
  }
152
233
 
153
- var isHttpsRequest = isHttps.test(protocol);
154
- var agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
155
-
156
234
  try {
157
235
  buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, '');
158
236
  } catch (err) {
@@ -165,11 +243,13 @@ module.exports = function httpAdapter(config) {
165
243
 
166
244
  var options = {
167
245
  path: buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, ''),
168
- method: config.method.toUpperCase(),
246
+ method: method,
169
247
  headers: headers,
170
- agent: agent,
171
248
  agents: { http: config.httpAgent, https: config.httpsAgent },
172
- auth: auth
249
+ auth: auth,
250
+ protocol: protocol,
251
+ beforeRedirect: dispatchBeforeRedirect,
252
+ beforeRedirects: {}
173
253
  };
174
254
 
175
255
  if (config.socketPath) {
@@ -177,79 +257,31 @@ module.exports = function httpAdapter(config) {
177
257
  } else {
178
258
  options.hostname = parsed.hostname;
179
259
  options.port = parsed.port;
180
- }
181
-
182
- var proxy = config.proxy;
183
- if (!proxy && proxy !== false) {
184
- var proxyEnv = protocol.slice(0, -1) + '_proxy';
185
- var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()];
186
- if (proxyUrl) {
187
- var parsedProxyUrl = url.parse(proxyUrl);
188
- var noProxyEnv = process.env.no_proxy || process.env.NO_PROXY;
189
- var shouldProxy = true;
190
-
191
- if (noProxyEnv) {
192
- var noProxy = noProxyEnv.split(',').map(function trim(s) {
193
- return s.trim();
194
- });
195
-
196
- shouldProxy = !noProxy.some(function proxyMatch(proxyElement) {
197
- if (!proxyElement) {
198
- return false;
199
- }
200
- if (proxyElement === '*') {
201
- return true;
202
- }
203
- if (proxyElement[0] === '.' &&
204
- parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement) {
205
- return true;
206
- }
207
-
208
- return parsed.hostname === proxyElement;
209
- });
210
- }
211
-
212
- if (shouldProxy) {
213
- proxy = {
214
- host: parsedProxyUrl.hostname,
215
- port: parsedProxyUrl.port,
216
- protocol: parsedProxyUrl.protocol
217
- };
218
-
219
- if (parsedProxyUrl.auth) {
220
- var proxyUrlAuth = parsedProxyUrl.auth.split(':');
221
- proxy.auth = {
222
- username: proxyUrlAuth[0],
223
- password: proxyUrlAuth[1]
224
- };
225
- }
226
- }
227
- }
228
- }
229
-
230
- if (proxy) {
231
- options.headers.host = parsed.hostname + (parsed.port ? ':' + parsed.port : '');
232
- setProxy(options, proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);
260
+ setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);
233
261
  }
234
262
 
235
263
  var transport;
236
- var isHttpsProxy = isHttpsRequest && (proxy ? isHttps.test(proxy.protocol) : true);
264
+ var isHttpsRequest = isHttps.test(options.protocol);
265
+ options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
237
266
  if (config.transport) {
238
267
  transport = config.transport;
239
268
  } else if (config.maxRedirects === 0) {
240
- transport = isHttpsProxy ? https : http;
269
+ transport = isHttpsRequest ? https : http;
241
270
  } else {
242
271
  if (config.maxRedirects) {
243
272
  options.maxRedirects = config.maxRedirects;
244
273
  }
245
274
  if (config.beforeRedirect) {
246
- options.beforeRedirect = config.beforeRedirect;
275
+ options.beforeRedirects.config = config.beforeRedirect;
247
276
  }
248
- transport = isHttpsProxy ? httpsFollow : httpFollow;
277
+ transport = isHttpsRequest ? httpsFollow : httpFollow;
249
278
  }
250
279
 
251
280
  if (config.maxBodyLength > -1) {
252
281
  options.maxBodyLength = config.maxBodyLength;
282
+ } else {
283
+ // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
284
+ options.maxBodyLength = Infinity;
253
285
  }
254
286
 
255
287
  if (config.insecureHTTPParser) {
@@ -261,21 +293,26 @@ module.exports = function httpAdapter(config) {
261
293
  if (req.aborted) return;
262
294
 
263
295
  // uncompress the response body transparently if required
264
- var stream = res;
296
+ var responseStream = res;
265
297
 
266
298
  // return the last request in case of redirects
267
299
  var lastRequest = res.req || req;
268
300
 
301
+ // if decompress disabled we should not decompress
302
+ if (config.decompress !== false) {
303
+ // if no content, but headers still say that it is encoded,
304
+ // remove the header not confuse downstream operations
305
+ if (data && data.length === 0 && res.headers['content-encoding']) {
306
+ delete res.headers['content-encoding'];
307
+ }
269
308
 
270
- // if no content, is HEAD request or decompress disabled we should not decompress
271
- if (res.statusCode !== 204 && lastRequest.method !== 'HEAD' && config.decompress !== false) {
272
309
  switch (res.headers['content-encoding']) {
273
310
  /*eslint default-case:0*/
274
311
  case 'gzip':
275
312
  case 'compress':
276
313
  case 'deflate':
277
- // add the unzipper to the body stream processing pipeline
278
- stream = stream.pipe(zlib.createUnzip());
314
+ // add the unzipper to the body stream processing pipeline
315
+ responseStream = responseStream.pipe(zlib.createUnzip());
279
316
 
280
317
  // remove the content-encoding in order to not confuse downstream operations
281
318
  delete res.headers['content-encoding'];
@@ -291,31 +328,31 @@ module.exports = function httpAdapter(config) {
291
328
  request: lastRequest
292
329
  };
293
330
 
294
- if (config.responseType === 'stream') {
295
- response.data = stream;
331
+ if (responseType === 'stream') {
332
+ response.data = responseStream;
296
333
  settle(resolve, reject, response);
297
334
  } else {
298
335
  var responseBuffer = [];
299
336
  var totalResponseBytes = 0;
300
- stream.on('data', function handleStreamData(chunk) {
337
+ responseStream.on('data', function handleStreamData(chunk) {
301
338
  responseBuffer.push(chunk);
302
339
  totalResponseBytes += chunk.length;
303
340
 
304
341
  // make sure the content length is not over the maxContentLength if specified
305
342
  if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
306
- // stream.destoy() emit aborted event before calling reject() on Node.js v16
343
+ // stream.destroy() emit aborted event before calling reject() on Node.js v16
307
344
  rejected = true;
308
- stream.destroy();
345
+ responseStream.destroy();
309
346
  reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
310
347
  AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
311
348
  }
312
349
  });
313
350
 
314
- stream.on('aborted', function handlerStreamAborted() {
351
+ responseStream.on('aborted', function handlerStreamAborted() {
315
352
  if (rejected) {
316
353
  return;
317
354
  }
318
- stream.destroy();
355
+ responseStream.destroy();
319
356
  reject(new AxiosError(
320
357
  'maxContentLength size of ' + config.maxContentLength + ' exceeded',
321
358
  AxiosError.ERR_BAD_RESPONSE,
@@ -324,17 +361,17 @@ module.exports = function httpAdapter(config) {
324
361
  ));
325
362
  });
326
363
 
327
- stream.on('error', function handleStreamError(err) {
364
+ responseStream.on('error', function handleStreamError(err) {
328
365
  if (req.aborted) return;
329
366
  reject(AxiosError.from(err, null, config, lastRequest));
330
367
  });
331
368
 
332
- stream.on('end', function handleStreamEnd() {
369
+ responseStream.on('end', function handleStreamEnd() {
333
370
  try {
334
371
  var responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);
335
- if (config.responseType !== 'arraybuffer') {
336
- responseData = responseData.toString(config.responseEncoding);
337
- if (!config.responseEncoding || config.responseEncoding === 'utf8') {
372
+ if (responseType !== 'arraybuffer') {
373
+ responseData = responseData.toString(responseEncoding);
374
+ if (!responseEncoding || responseEncoding === 'utf8') {
338
375
  responseData = utils.stripBOM(responseData);
339
376
  }
340
377
  }
@@ -379,13 +416,17 @@ module.exports = function httpAdapter(config) {
379
416
  // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.
380
417
  // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET.
381
418
  // 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.
382
- // And then these socket which be hang up will devoring CPU little by little.
419
+ // And then these socket which be hang up will devouring CPU little by little.
383
420
  // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.
384
421
  req.setTimeout(timeout, function handleRequestTimeout() {
385
422
  req.abort();
423
+ var timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';
386
424
  var transitional = config.transitional || transitionalDefaults;
425
+ if (config.timeoutErrorMessage) {
426
+ timeoutErrorMessage = config.timeoutErrorMessage;
427
+ }
387
428
  reject(new AxiosError(
388
- 'timeout of ' + timeout + 'ms exceeded',
429
+ timeoutErrorMessage,
389
430
  transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
390
431
  config,
391
432
  req
@@ -400,7 +441,7 @@ module.exports = function httpAdapter(config) {
400
441
  if (req.aborted) return;
401
442
 
402
443
  req.abort();
403
- reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);
444
+ reject(!cancel || cancel.type ? new CanceledError(null, config, req) : cancel);
404
445
  };
405
446
 
406
447
  config.cancelToken && config.cancelToken.subscribe(onCanceled);
@@ -7,10 +7,11 @@ var buildURL = require('./../helpers/buildURL');
7
7
  var buildFullPath = require('../core/buildFullPath');
8
8
  var parseHeaders = require('./../helpers/parseHeaders');
9
9
  var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
10
- var url = require('url');
11
10
  var transitionalDefaults = require('../defaults/transitional');
12
11
  var AxiosError = require('../core/AxiosError');
13
12
  var CanceledError = require('../cancel/CanceledError');
13
+ var parseProtocol = require('../helpers/parseProtocol');
14
+ var platform = require('../platform');
14
15
 
15
16
  module.exports = function xhrAdapter(config) {
16
17
  return new Promise(function dispatchXhrRequest(resolve, reject) {
@@ -28,6 +29,10 @@ module.exports = function xhrAdapter(config) {
28
29
  }
29
30
  }
30
31
 
32
+ if (utils.isFormData(requestData) && utils.isStandardBrowserEnv()) {
33
+ delete requestHeaders['Content-Type']; // Let the browser set it
34
+ }
35
+
31
36
  var request = new XMLHttpRequest();
32
37
 
33
38
  // HTTP basic authentication
@@ -38,8 +43,6 @@ module.exports = function xhrAdapter(config) {
38
43
  }
39
44
 
40
45
  var fullPath = buildFullPath(config.baseURL, config.url);
41
- var parsed = url.parse(fullPath);
42
- var protocol = utils.getProtocol(parsed.protocol);
43
46
 
44
47
  request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
45
48
 
@@ -114,7 +117,7 @@ module.exports = function xhrAdapter(config) {
114
117
  request.onerror = function handleError() {
115
118
  // Real errors are hidden from us by the browser
116
119
  // onerror should only fire if it's a network error
117
- reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request, request));
120
+ reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));
118
121
 
119
122
  // Clean up request
120
123
  request = null;
@@ -191,7 +194,7 @@ module.exports = function xhrAdapter(config) {
191
194
  if (!request) {
192
195
  return;
193
196
  }
194
- reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);
197
+ reject(!cancel || cancel.type ? new CanceledError(null, config, req) : cancel);
195
198
  request.abort();
196
199
  request = null;
197
200
  };
@@ -206,16 +209,14 @@ module.exports = function xhrAdapter(config) {
206
209
  requestData = null;
207
210
  }
208
211
 
209
- if (parsed.path === null) {
210
- reject(new AxiosError('Malformed URL ' + fullPath, AxiosError.ERR_BAD_REQUEST, config));
211
- return;
212
- }
212
+ var protocol = parseProtocol(fullPath);
213
213
 
214
- if (!utils.supportedProtocols.includes(protocol)) {
215
- reject(new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_BAD_REQUEST, config));
214
+ if (protocol && platform.protocols.indexOf(protocol) === -1) {
215
+ reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));
216
216
  return;
217
217
  }
218
218
 
219
+
219
220
  // Send the request
220
221
  request.send(requestData);
221
222
  });
package/lib/axios.js CHANGED
@@ -5,7 +5,7 @@ var bind = require('./helpers/bind');
5
5
  var Axios = require('./core/Axios');
6
6
  var mergeConfig = require('./core/mergeConfig');
7
7
  var defaults = require('./defaults');
8
-
8
+ var formDataToJSON = require('./helpers/formDataToJSON');
9
9
  /**
10
10
  * Create an instance of Axios
11
11
  *
@@ -58,6 +58,10 @@ axios.spread = require('./helpers/spread');
58
58
  // Expose isAxiosError
59
59
  axios.isAxiosError = require('./helpers/isAxiosError');
60
60
 
61
+ axios.formToJSON = function(thing) {
62
+ return formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
63
+ };
64
+
61
65
  module.exports = axios;
62
66
 
63
67
  // Allow use of default import syntax in TypeScript
@@ -25,10 +25,9 @@ function CancelToken(executor) {
25
25
  this.promise.then(function(cancel) {
26
26
  if (!token._listeners) return;
27
27
 
28
- var i;
29
- var l = token._listeners.length;
28
+ var i = token._listeners.length;
30
29
 
31
- for (i = 0; i < l; i++) {
30
+ while (i-- > 0) {
32
31
  token._listeners[i](cancel);
33
32
  }
34
33
  token._listeners = null;
@@ -50,13 +49,13 @@ function CancelToken(executor) {
50
49
  return promise;
51
50
  };
52
51
 
53
- executor(function cancel(message) {
52
+ executor(function cancel(message, config, request) {
54
53
  if (token.reason) {
55
54
  // Cancellation has already been requested
56
55
  return;
57
56
  }
58
57
 
59
- token.reason = new CanceledError(message);
58
+ token.reason = new CanceledError(message, config, request);
60
59
  resolvePromise(token.reason);
61
60
  });
62
61
  }
@@ -8,10 +8,12 @@ var utils = require('../utils');
8
8
  *
9
9
  * @class
10
10
  * @param {string=} message The message.
11
+ * @param {Object=} config The config.
12
+ * @param {Object=} request The request.
11
13
  */
12
- function CanceledError(message) {
14
+ function CanceledError(message, config, request) {
13
15
  // eslint-disable-next-line no-eq-null,eqeqeq
14
- AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED);
16
+ AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);
15
17
  this.name = 'CanceledError';
16
18
  }
17
19
 
package/lib/core/Axios.js CHANGED
@@ -25,7 +25,8 @@ function Axios(instanceConfig) {
25
25
  /**
26
26
  * Dispatch a request
27
27
  *
28
- * @param {Object} config The config specific for this request (merged with this.defaults)
28
+ * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)
29
+ * @param {?Object} config
29
30
  */
30
31
  Axios.prototype.request = function request(configOrUrl, config) {
31
32
  /*eslint no-param-reassign:0*/
@@ -14,6 +14,13 @@ var utils = require('../utils');
14
14
  */
15
15
  function AxiosError(message, code, config, request, response) {
16
16
  Error.call(this);
17
+
18
+ if (Error.captureStackTrace) {
19
+ Error.captureStackTrace(this, this.constructor);
20
+ } else {
21
+ this.stack = (new Error()).stack;
22
+ }
23
+
17
24
  this.message = message;
18
25
  this.name = 'AxiosError';
19
26
  code && (this.code = code);
@@ -57,7 +64,9 @@ var descriptors = {};
57
64
  'ERR_DEPRECATED',
58
65
  'ERR_BAD_RESPONSE',
59
66
  'ERR_BAD_REQUEST',
60
- 'ERR_CANCELED'
67
+ 'ERR_CANCELED',
68
+ 'ERR_NOT_SUPPORT',
69
+ 'ERR_INVALID_URL'
61
70
  // eslint-disable-next-line func-names
62
71
  ].forEach(function(code) {
63
72
  descriptors[code] = {value: code};
@@ -76,6 +85,8 @@ AxiosError.from = function(error, code, config, request, response, customProps)
76
85
 
77
86
  AxiosError.call(axiosError, error.message, code, config, request, response);
78
87
 
88
+ axiosError.cause = error;
89
+
79
90
  axiosError.name = error.name;
80
91
 
81
92
  customProps && Object.assign(axiosError, customProps);
@@ -35,6 +35,15 @@ InterceptorManager.prototype.eject = function eject(id) {
35
35
  }
36
36
  };
37
37
 
38
+ /**
39
+ * Clear all interceptors from the stack
40
+ */
41
+ InterceptorManager.prototype.clear = function clear() {
42
+ if (this.handlers) {
43
+ this.handlers = [];
44
+ }
45
+ };
46
+
38
47
  /**
39
48
  * Iterate over all the registered interceptors
40
49
  *
@@ -5,6 +5,7 @@ var transformData = require('./transformData');
5
5
  var isCancel = require('../cancel/isCancel');
6
6
  var defaults = require('../defaults');
7
7
  var CanceledError = require('../cancel/CanceledError');
8
+ var normalizeHeaderName = require('../helpers/normalizeHeaderName');
8
9
 
9
10
  /**
10
11
  * Throws a `CanceledError` if cancellation has been requested.
@@ -36,9 +37,13 @@ module.exports = function dispatchRequest(config) {
36
37
  config,
37
38
  config.data,
38
39
  config.headers,
40
+ null,
39
41
  config.transformRequest
40
42
  );
41
43
 
44
+ normalizeHeaderName(config.headers, 'Accept');
45
+ normalizeHeaderName(config.headers, 'Content-Type');
46
+
42
47
  // Flatten headers
43
48
  config.headers = utils.merge(
44
49
  config.headers.common || {},
@@ -63,6 +68,7 @@ module.exports = function dispatchRequest(config) {
63
68
  config,
64
69
  response.data,
65
70
  response.headers,
71
+ response.status,
66
72
  config.transformResponse
67
73
  );
68
74
 
@@ -77,6 +83,7 @@ module.exports = function dispatchRequest(config) {
77
83
  config,
78
84
  reason.response.data,
79
85
  reason.response.headers,
86
+ reason.response.status,
80
87
  config.transformResponse
81
88
  );
82
89
  }
@@ -8,14 +8,15 @@ var defaults = require('../defaults');
8
8
  *
9
9
  * @param {Object|String} data The data to be transformed
10
10
  * @param {Array} headers The headers for the request or response
11
+ * @param {Number} status HTTP status code
11
12
  * @param {Array|Function} fns A single function or Array of functions
12
13
  * @returns {*} The resulting transformed data
13
14
  */
14
- module.exports = function transformData(data, headers, fns) {
15
+ module.exports = function transformData(data, headers, status, fns) {
15
16
  var context = this || defaults;
16
17
  /*eslint no-param-reassign:0*/
17
18
  utils.forEach(fns, function transform(fn) {
18
- data = fn.call(context, data, headers);
19
+ data = fn.call(context, data, headers, status);
19
20
  });
20
21
 
21
22
  return data;