axios 0.21.4 → 0.25.0

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.
package/index.d.ts CHANGED
@@ -1,9 +1,21 @@
1
- export interface AxiosTransformer {
2
- (data: any, headers?: any): any;
1
+ // TypeScript Version: 3.0
2
+
3
+ export type AxiosRequestHeaders = Record<string, string | number | boolean>;
4
+
5
+ export type AxiosResponseHeaders = Record<string, string> & {
6
+ "set-cookie"?: string[]
7
+ };
8
+
9
+ export interface AxiosRequestTransformer {
10
+ (data: any, headers?: AxiosRequestHeaders): any;
11
+ }
12
+
13
+ export interface AxiosResponseTransformer {
14
+ (data: any, headers?: AxiosResponseHeaders): any;
3
15
  }
4
16
 
5
17
  export interface AxiosAdapter {
6
- (config: AxiosRequestConfig): AxiosPromise<any>;
18
+ (config: AxiosRequestConfig): AxiosPromise;
7
19
  }
8
20
 
9
21
  export interface AxiosBasicCredentials {
@@ -16,7 +28,7 @@ export interface AxiosProxyConfig {
16
28
  port: number;
17
29
  auth?: {
18
30
  username: string;
19
- password:string;
31
+ password: string;
20
32
  };
21
33
  protocol?: string;
22
34
  }
@@ -31,7 +43,7 @@ export type Method =
31
43
  | 'patch' | 'PATCH'
32
44
  | 'purge' | 'PURGE'
33
45
  | 'link' | 'LINK'
34
- | 'unlink' | 'UNLINK'
46
+ | 'unlink' | 'UNLINK';
35
47
 
36
48
  export type ResponseType =
37
49
  | 'arraybuffer'
@@ -39,30 +51,45 @@ export type ResponseType =
39
51
  | 'document'
40
52
  | 'json'
41
53
  | 'text'
42
- | 'stream'
43
-
44
- export interface TransitionalOptions{
45
- silentJSONParsing: boolean;
46
- forcedJSONParsing: boolean;
47
- clarifyTimeoutError: boolean;
48
- }
49
-
50
- export interface AxiosRequestConfig {
54
+ | 'stream';
55
+
56
+ export type responseEncoding =
57
+ | 'ascii' | 'ASCII'
58
+ | 'ansi' | 'ANSI'
59
+ | 'binary' | 'BINARY'
60
+ | 'base64' | 'BASE64'
61
+ | 'base64url' | 'BASE64URL'
62
+ | 'hex' | 'HEX'
63
+ | 'latin1' | 'LATIN1'
64
+ | 'ucs-2' | 'UCS-2'
65
+ | 'ucs2' | 'UCS2'
66
+ | 'utf-8' | 'UTF-8'
67
+ | 'utf8' | 'UTF8'
68
+ | 'utf16le' | 'UTF16LE';
69
+
70
+ export interface TransitionalOptions {
71
+ silentJSONParsing?: boolean;
72
+ forcedJSONParsing?: boolean;
73
+ clarifyTimeoutError?: boolean;
74
+ }
75
+
76
+ export interface AxiosRequestConfig<D = any> {
51
77
  url?: string;
52
78
  method?: Method;
53
79
  baseURL?: string;
54
- transformRequest?: AxiosTransformer | AxiosTransformer[];
55
- transformResponse?: AxiosTransformer | AxiosTransformer[];
56
- headers?: any;
80
+ transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
81
+ transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
82
+ headers?: AxiosRequestHeaders;
57
83
  params?: any;
58
84
  paramsSerializer?: (params: any) => string;
59
- data?: any;
85
+ data?: D;
60
86
  timeout?: number;
61
87
  timeoutErrorMessage?: string;
62
88
  withCredentials?: boolean;
63
89
  adapter?: AxiosAdapter;
64
90
  auth?: AxiosBasicCredentials;
65
91
  responseType?: ResponseType;
92
+ responseEncoding?: responseEncoding | string;
66
93
  xsrfCookieName?: string;
67
94
  xsrfHeaderName?: string;
68
95
  onUploadProgress?: (progressEvent: any) => void;
@@ -77,23 +104,43 @@ export interface AxiosRequestConfig {
77
104
  proxy?: AxiosProxyConfig | false;
78
105
  cancelToken?: CancelToken;
79
106
  decompress?: boolean;
80
- transitional?: TransitionalOptions
107
+ transitional?: TransitionalOptions;
108
+ signal?: AbortSignal;
109
+ insecureHTTPParser?: boolean;
81
110
  }
82
111
 
83
- export interface AxiosResponse<T = any> {
112
+ export interface HeadersDefaults {
113
+ common: AxiosRequestHeaders;
114
+ delete: AxiosRequestHeaders;
115
+ get: AxiosRequestHeaders;
116
+ head: AxiosRequestHeaders;
117
+ post: AxiosRequestHeaders;
118
+ put: AxiosRequestHeaders;
119
+ patch: AxiosRequestHeaders;
120
+ options?: AxiosRequestHeaders;
121
+ purge?: AxiosRequestHeaders;
122
+ link?: AxiosRequestHeaders;
123
+ unlink?: AxiosRequestHeaders;
124
+ }
125
+
126
+ export interface AxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>, 'headers'> {
127
+ headers: HeadersDefaults;
128
+ }
129
+
130
+ export interface AxiosResponse<T = any, D = any> {
84
131
  data: T;
85
132
  status: number;
86
133
  statusText: string;
87
- headers: any;
88
- config: AxiosRequestConfig;
134
+ headers: AxiosResponseHeaders;
135
+ config: AxiosRequestConfig<D>;
89
136
  request?: any;
90
137
  }
91
138
 
92
- export interface AxiosError<T = any> extends Error {
93
- config: AxiosRequestConfig;
139
+ export interface AxiosError<T = any, D = any> extends Error {
140
+ config: AxiosRequestConfig<D>;
94
141
  code?: string;
95
142
  request?: any;
96
- response?: AxiosResponse<T>;
143
+ response?: AxiosResponse<T, D>;
97
144
  isAxiosError: boolean;
98
145
  toJSON: () => object;
99
146
  }
@@ -106,7 +153,7 @@ export interface CancelStatic {
106
153
  }
107
154
 
108
155
  export interface Cancel {
109
- message: string;
156
+ message: string | undefined;
110
157
  }
111
158
 
112
159
  export interface Canceler {
@@ -134,31 +181,37 @@ export interface AxiosInterceptorManager<V> {
134
181
  eject(id: number): void;
135
182
  }
136
183
 
137
- export interface AxiosInstance {
138
- (config: AxiosRequestConfig): AxiosPromise;
139
- (url: string, config?: AxiosRequestConfig): AxiosPromise;
140
- defaults: AxiosRequestConfig;
184
+ export class Axios {
185
+ constructor(config?: AxiosRequestConfig);
186
+ defaults: AxiosDefaults;
141
187
  interceptors: {
142
188
  request: AxiosInterceptorManager<AxiosRequestConfig>;
143
189
  response: AxiosInterceptorManager<AxiosResponse>;
144
190
  };
145
191
  getUri(config?: AxiosRequestConfig): string;
146
- request<T = any, R = AxiosResponse<T>> (config: AxiosRequestConfig): Promise<R>;
147
- get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
148
- delete<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
149
- head<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
150
- options<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
151
- post<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
152
- put<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
153
- patch<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
192
+ request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
193
+ get<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
194
+ delete<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
195
+ head<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
196
+ options<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
197
+ post<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
198
+ put<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
199
+ patch<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
200
+ }
201
+
202
+ export interface AxiosInstance extends Axios {
203
+ (config: AxiosRequestConfig): AxiosPromise;
204
+ (url: string, config?: AxiosRequestConfig): AxiosPromise;
154
205
  }
155
206
 
156
207
  export interface AxiosStatic extends AxiosInstance {
157
208
  create(config?: AxiosRequestConfig): AxiosInstance;
158
209
  Cancel: CancelStatic;
159
210
  CancelToken: CancelTokenStatic;
211
+ Axios: typeof Axios;
212
+ readonly VERSION: string;
160
213
  isCancel(value: any): boolean;
161
- all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
214
+ all<T>(values: Array<T | Promise<T>>): Promise<T[]>;
162
215
  spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
163
216
  isAxiosError(payload: any): payload is AxiosError;
164
217
  }
@@ -10,9 +10,11 @@ var httpFollow = require('follow-redirects').http;
10
10
  var httpsFollow = require('follow-redirects').https;
11
11
  var url = require('url');
12
12
  var zlib = require('zlib');
13
- var pkg = require('./../../package.json');
13
+ var VERSION = require('./../env/data').version;
14
14
  var createError = require('../core/createError');
15
15
  var enhanceError = require('../core/enhanceError');
16
+ var defaults = require('../defaults');
17
+ var Cancel = require('../cancel/Cancel');
16
18
 
17
19
  var isHttps = /https:?/;
18
20
 
@@ -44,27 +46,45 @@ function setProxy(options, proxy, location) {
44
46
  /*eslint consistent-return:0*/
45
47
  module.exports = function httpAdapter(config) {
46
48
  return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) {
49
+ var onCanceled;
50
+ function done() {
51
+ if (config.cancelToken) {
52
+ config.cancelToken.unsubscribe(onCanceled);
53
+ }
54
+
55
+ if (config.signal) {
56
+ config.signal.removeEventListener('abort', onCanceled);
57
+ }
58
+ }
47
59
  var resolve = function resolve(value) {
60
+ done();
48
61
  resolvePromise(value);
49
62
  };
63
+ var rejected = false;
50
64
  var reject = function reject(value) {
65
+ done();
66
+ rejected = true;
51
67
  rejectPromise(value);
52
68
  };
53
69
  var data = config.data;
54
70
  var headers = config.headers;
71
+ var headerNames = {};
72
+
73
+ Object.keys(headers).forEach(function storeLowerName(name) {
74
+ headerNames[name.toLowerCase()] = name;
75
+ });
55
76
 
56
77
  // Set User-Agent (required by some servers)
57
78
  // See https://github.com/axios/axios/issues/69
58
- if ('User-Agent' in headers || 'user-agent' in headers) {
79
+ if ('user-agent' in headerNames) {
59
80
  // User-Agent is specified; handle case where no UA header is desired
60
- if (!headers['User-Agent'] && !headers['user-agent']) {
61
- delete headers['User-Agent'];
62
- delete headers['user-agent'];
81
+ if (!headers[headerNames['user-agent']]) {
82
+ delete headers[headerNames['user-agent']];
63
83
  }
64
84
  // Otherwise, use specified value
65
85
  } else {
66
86
  // Only set header if it hasn't been set in config
67
- headers['User-Agent'] = 'axios/' + pkg.version;
87
+ headers['User-Agent'] = 'axios/' + VERSION;
68
88
  }
69
89
 
70
90
  if (data && !utils.isStream(data)) {
@@ -81,8 +101,14 @@ module.exports = function httpAdapter(config) {
81
101
  ));
82
102
  }
83
103
 
104
+ if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
105
+ return reject(createError('Request body larger than maxBodyLength limit', config));
106
+ }
107
+
84
108
  // Add Content-Length header if data exists
85
- headers['Content-Length'] = data.length;
109
+ if (!headerNames['content-length']) {
110
+ headers['Content-Length'] = data.length;
111
+ }
86
112
  }
87
113
 
88
114
  // HTTP basic authentication
@@ -105,8 +131,8 @@ module.exports = function httpAdapter(config) {
105
131
  auth = urlUsername + ':' + urlPassword;
106
132
  }
107
133
 
108
- if (auth) {
109
- delete headers.Authorization;
134
+ if (auth && headerNames.authorization) {
135
+ delete headers[headerNames.authorization];
110
136
  }
111
137
 
112
138
  var isHttpsRequest = isHttps.test(protocol);
@@ -198,6 +224,10 @@ module.exports = function httpAdapter(config) {
198
224
  options.maxBodyLength = config.maxBodyLength;
199
225
  }
200
226
 
227
+ if (config.insecureHTTPParser) {
228
+ options.insecureHTTPParser = config.insecureHTTPParser;
229
+ }
230
+
201
231
  // Create the request
202
232
  var req = transport.request(options, function handleResponse(res) {
203
233
  if (req.aborted) return;
@@ -245,27 +275,40 @@ module.exports = function httpAdapter(config) {
245
275
 
246
276
  // make sure the content length is not over the maxContentLength if specified
247
277
  if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
278
+ // stream.destoy() emit aborted event before calling reject() on Node.js v16
279
+ rejected = true;
248
280
  stream.destroy();
249
281
  reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
250
282
  config, null, lastRequest));
251
283
  }
252
284
  });
253
285
 
286
+ stream.on('aborted', function handlerStreamAborted() {
287
+ if (rejected) {
288
+ return;
289
+ }
290
+ stream.destroy();
291
+ reject(createError('error request aborted', config, 'ERR_REQUEST_ABORTED', lastRequest));
292
+ });
293
+
254
294
  stream.on('error', function handleStreamError(err) {
255
295
  if (req.aborted) return;
256
296
  reject(enhanceError(err, config, null, lastRequest));
257
297
  });
258
298
 
259
299
  stream.on('end', function handleStreamEnd() {
260
- var responseData = Buffer.concat(responseBuffer);
261
- if (config.responseType !== 'arraybuffer') {
262
- responseData = responseData.toString(config.responseEncoding);
263
- if (!config.responseEncoding || config.responseEncoding === 'utf8') {
264
- responseData = utils.stripBOM(responseData);
300
+ try {
301
+ var responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);
302
+ if (config.responseType !== 'arraybuffer') {
303
+ responseData = responseData.toString(config.responseEncoding);
304
+ if (!config.responseEncoding || config.responseEncoding === 'utf8') {
305
+ responseData = utils.stripBOM(responseData);
306
+ }
265
307
  }
308
+ response.data = responseData;
309
+ } catch (err) {
310
+ reject(enhanceError(err, config, err.code, response.request, response));
266
311
  }
267
-
268
- response.data = responseData;
269
312
  settle(resolve, reject, response);
270
313
  });
271
314
  }
@@ -277,6 +320,12 @@ module.exports = function httpAdapter(config) {
277
320
  reject(enhanceError(err, config, null, req));
278
321
  });
279
322
 
323
+ // set tcp keep alive to prevent drop connection by peer
324
+ req.on('socket', function handleRequestSocket(socket) {
325
+ // default interval of sending ack packet is 1 minute
326
+ socket.setKeepAlive(true, 1000 * 60);
327
+ });
328
+
280
329
  // Handle request timeout
281
330
  if (config.timeout) {
282
331
  // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
@@ -300,25 +349,33 @@ module.exports = function httpAdapter(config) {
300
349
  // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.
301
350
  req.setTimeout(timeout, function handleRequestTimeout() {
302
351
  req.abort();
352
+ var transitional = config.transitional || defaults.transitional;
303
353
  reject(createError(
304
354
  'timeout of ' + timeout + 'ms exceeded',
305
355
  config,
306
- config.transitional && config.transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED',
356
+ transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED',
307
357
  req
308
358
  ));
309
359
  });
310
360
  }
311
361
 
312
- if (config.cancelToken) {
362
+ if (config.cancelToken || config.signal) {
313
363
  // Handle cancellation
314
- config.cancelToken.promise.then(function onCanceled(cancel) {
364
+ // eslint-disable-next-line func-names
365
+ onCanceled = function(cancel) {
315
366
  if (req.aborted) return;
316
367
 
317
368
  req.abort();
318
- reject(cancel);
319
- });
369
+ reject(!cancel || (cancel && cancel.type) ? new Cancel('canceled') : cancel);
370
+ };
371
+
372
+ config.cancelToken && config.cancelToken.subscribe(onCanceled);
373
+ if (config.signal) {
374
+ config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled);
375
+ }
320
376
  }
321
377
 
378
+
322
379
  // Send the request
323
380
  if (utils.isStream(data)) {
324
381
  data.on('error', function handleStreamError(err) {
@@ -8,12 +8,24 @@ var buildFullPath = require('../core/buildFullPath');
8
8
  var parseHeaders = require('./../helpers/parseHeaders');
9
9
  var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
10
10
  var createError = require('../core/createError');
11
+ var defaults = require('../defaults');
12
+ var Cancel = require('../cancel/Cancel');
11
13
 
12
14
  module.exports = function xhrAdapter(config) {
13
15
  return new Promise(function dispatchXhrRequest(resolve, reject) {
14
16
  var requestData = config.data;
15
17
  var requestHeaders = config.headers;
16
18
  var responseType = config.responseType;
19
+ var onCanceled;
20
+ function done() {
21
+ if (config.cancelToken) {
22
+ config.cancelToken.unsubscribe(onCanceled);
23
+ }
24
+
25
+ if (config.signal) {
26
+ config.signal.removeEventListener('abort', onCanceled);
27
+ }
28
+ }
17
29
 
18
30
  if (utils.isFormData(requestData)) {
19
31
  delete requestHeaders['Content-Type']; // Let the browser set it
@@ -51,7 +63,13 @@ module.exports = function xhrAdapter(config) {
51
63
  request: request
52
64
  };
53
65
 
54
- settle(resolve, reject, response);
66
+ settle(function _resolve(value) {
67
+ resolve(value);
68
+ done();
69
+ }, function _reject(err) {
70
+ reject(err);
71
+ done();
72
+ }, response);
55
73
 
56
74
  // Clean up request
57
75
  request = null;
@@ -104,14 +122,15 @@ module.exports = function xhrAdapter(config) {
104
122
 
105
123
  // Handle timeout
106
124
  request.ontimeout = function handleTimeout() {
107
- var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';
125
+ var timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';
126
+ var transitional = config.transitional || defaults.transitional;
108
127
  if (config.timeoutErrorMessage) {
109
128
  timeoutErrorMessage = config.timeoutErrorMessage;
110
129
  }
111
130
  reject(createError(
112
131
  timeoutErrorMessage,
113
132
  config,
114
- config.transitional && config.transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED',
133
+ transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED',
115
134
  request));
116
135
 
117
136
  // Clean up request
@@ -165,18 +184,22 @@ module.exports = function xhrAdapter(config) {
165
184
  request.upload.addEventListener('progress', config.onUploadProgress);
166
185
  }
167
186
 
168
- if (config.cancelToken) {
187
+ if (config.cancelToken || config.signal) {
169
188
  // Handle cancellation
170
- config.cancelToken.promise.then(function onCanceled(cancel) {
189
+ // eslint-disable-next-line func-names
190
+ onCanceled = function(cancel) {
171
191
  if (!request) {
172
192
  return;
173
193
  }
174
-
194
+ reject(!cancel || (cancel && cancel.type) ? new Cancel('canceled') : cancel);
175
195
  request.abort();
176
- reject(cancel);
177
- // Clean up request
178
196
  request = null;
179
- });
197
+ };
198
+
199
+ config.cancelToken && config.cancelToken.subscribe(onCanceled);
200
+ if (config.signal) {
201
+ config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled);
202
+ }
180
203
  }
181
204
 
182
205
  if (!requestData) {
package/lib/axios.js CHANGED
@@ -22,6 +22,11 @@ function createInstance(defaultConfig) {
22
22
  // Copy context to instance
23
23
  utils.extend(instance, context);
24
24
 
25
+ // Factory for creating new instances
26
+ instance.create = function create(instanceConfig) {
27
+ return createInstance(mergeConfig(defaultConfig, instanceConfig));
28
+ };
29
+
25
30
  return instance;
26
31
  }
27
32
 
@@ -31,15 +36,11 @@ var axios = createInstance(defaults);
31
36
  // Expose Axios class to allow class inheritance
32
37
  axios.Axios = Axios;
33
38
 
34
- // Factory for creating new instances
35
- axios.create = function create(instanceConfig) {
36
- return createInstance(mergeConfig(axios.defaults, instanceConfig));
37
- };
38
-
39
39
  // Expose Cancel & CancelToken
40
40
  axios.Cancel = require('./cancel/Cancel');
41
41
  axios.CancelToken = require('./cancel/CancelToken');
42
42
  axios.isCancel = require('./cancel/isCancel');
43
+ axios.VERSION = require('./env/data').version;
43
44
 
44
45
  // Expose all/spread
45
46
  axios.all = function all(promises) {
@@ -14,11 +14,42 @@ function CancelToken(executor) {
14
14
  }
15
15
 
16
16
  var resolvePromise;
17
+
17
18
  this.promise = new Promise(function promiseExecutor(resolve) {
18
19
  resolvePromise = resolve;
19
20
  });
20
21
 
21
22
  var token = this;
23
+
24
+ // eslint-disable-next-line func-names
25
+ this.promise.then(function(cancel) {
26
+ if (!token._listeners) return;
27
+
28
+ var i;
29
+ var l = token._listeners.length;
30
+
31
+ for (i = 0; i < l; i++) {
32
+ token._listeners[i](cancel);
33
+ }
34
+ token._listeners = null;
35
+ });
36
+
37
+ // eslint-disable-next-line func-names
38
+ this.promise.then = function(onfulfilled) {
39
+ var _resolve;
40
+ // eslint-disable-next-line func-names
41
+ var promise = new Promise(function(resolve) {
42
+ token.subscribe(resolve);
43
+ _resolve = resolve;
44
+ }).then(onfulfilled);
45
+
46
+ promise.cancel = function reject() {
47
+ token.unsubscribe(_resolve);
48
+ };
49
+
50
+ return promise;
51
+ };
52
+
22
53
  executor(function cancel(message) {
23
54
  if (token.reason) {
24
55
  // Cancellation has already been requested
@@ -39,6 +70,37 @@ CancelToken.prototype.throwIfRequested = function throwIfRequested() {
39
70
  }
40
71
  };
41
72
 
73
+ /**
74
+ * Subscribe to the cancel signal
75
+ */
76
+
77
+ CancelToken.prototype.subscribe = function subscribe(listener) {
78
+ if (this.reason) {
79
+ listener(this.reason);
80
+ return;
81
+ }
82
+
83
+ if (this._listeners) {
84
+ this._listeners.push(listener);
85
+ } else {
86
+ this._listeners = [listener];
87
+ }
88
+ };
89
+
90
+ /**
91
+ * Unsubscribe from the cancel signal
92
+ */
93
+
94
+ CancelToken.prototype.unsubscribe = function unsubscribe(listener) {
95
+ if (!this._listeners) {
96
+ return;
97
+ }
98
+ var index = this._listeners.indexOf(listener);
99
+ if (index !== -1) {
100
+ this._listeners.splice(index, 1);
101
+ }
102
+ };
103
+
42
104
  /**
43
105
  * Returns an object that contains a new `CancelToken` and a function that, when called,
44
106
  * cancels the `CancelToken`.
package/lib/core/Axios.js CHANGED
@@ -26,14 +26,18 @@ function Axios(instanceConfig) {
26
26
  *
27
27
  * @param {Object} config The config specific for this request (merged with this.defaults)
28
28
  */
29
- Axios.prototype.request = function request(config) {
29
+ Axios.prototype.request = function request(configOrUrl, config) {
30
30
  /*eslint no-param-reassign:0*/
31
31
  // Allow for axios('example/url'[, config]) a la fetch API
32
- if (typeof config === 'string') {
33
- config = arguments[1] || {};
34
- config.url = arguments[0];
35
- } else {
32
+ if (typeof configOrUrl === 'string') {
36
33
  config = config || {};
34
+ config.url = configOrUrl;
35
+ } else {
36
+ config = configOrUrl || {};
37
+ }
38
+
39
+ if (!config.url) {
40
+ throw new Error('Provided config url is not valid');
37
41
  }
38
42
 
39
43
  config = mergeConfig(this.defaults, config);
@@ -51,9 +55,9 @@ Axios.prototype.request = function request(config) {
51
55
 
52
56
  if (transitional !== undefined) {
53
57
  validator.assertOptions(transitional, {
54
- silentJSONParsing: validators.transitional(validators.boolean, '1.0.0'),
55
- forcedJSONParsing: validators.transitional(validators.boolean, '1.0.0'),
56
- clarifyTimeoutError: validators.transitional(validators.boolean, '1.0.0')
58
+ silentJSONParsing: validators.transitional(validators.boolean),
59
+ forcedJSONParsing: validators.transitional(validators.boolean),
60
+ clarifyTimeoutError: validators.transitional(validators.boolean)
57
61
  }, false);
58
62
  }
59
63
 
@@ -118,6 +122,9 @@ Axios.prototype.request = function request(config) {
118
122
  };
119
123
 
120
124
  Axios.prototype.getUri = function getUri(config) {
125
+ if (!config.url) {
126
+ throw new Error('Provided config url is not valid');
127
+ }
121
128
  config = mergeConfig(this.defaults, config);
122
129
  return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, '');
123
130
  };
@@ -4,6 +4,7 @@ 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 Cancel = require('../cancel/Cancel');
7
8
 
8
9
  /**
9
10
  * Throws a `Cancel` if cancellation has been requested.
@@ -12,6 +13,10 @@ function throwIfCancellationRequested(config) {
12
13
  if (config.cancelToken) {
13
14
  config.cancelToken.throwIfRequested();
14
15
  }
16
+
17
+ if (config.signal && config.signal.aborted) {
18
+ throw new Cancel('canceled');
19
+ }
15
20
  }
16
21
 
17
22
  /**
@@ -35,7 +35,8 @@ module.exports = function enhanceError(error, config, code, request, response) {
35
35
  stack: this.stack,
36
36
  // Axios
37
37
  config: this.config,
38
- code: this.code
38
+ code: this.code,
39
+ status: this.response && this.response.status ? this.response.status : null
39
40
  };
40
41
  };
41
42
  return error;