axios 1.6.7 → 1.7.0-beta.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.
Potentially problematic release.
This version of axios might be problematic. Click here for more details.
- package/CHANGELOG.md +31 -0
- package/README.md +35 -16
- package/dist/axios.js +1271 -580
- package/dist/axios.js.map +1 -1
- package/dist/axios.min.js +1 -1
- package/dist/axios.min.js.map +1 -1
- package/dist/browser/axios.cjs +651 -302
- package/dist/browser/axios.cjs.map +1 -1
- package/dist/esm/axios.js +651 -302
- package/dist/esm/axios.js.map +1 -1
- package/dist/esm/axios.min.js +1 -1
- package/dist/esm/axios.min.js.map +1 -1
- package/dist/node/axios.cjs +562 -243
- package/dist/node/axios.cjs.map +1 -1
- package/index.d.cts +5 -2
- package/index.d.ts +5 -2
- package/lib/adapters/adapters.js +3 -1
- package/lib/adapters/fetch.js +197 -0
- package/lib/adapters/http.js +1 -1
- package/lib/adapters/xhr.js +31 -101
- package/lib/core/AxiosHeaders.js +4 -0
- package/lib/core/mergeConfig.js +1 -1
- package/lib/defaults/index.js +7 -2
- package/lib/env/data.js +1 -1
- package/lib/helpers/AxiosTransformStream.js +9 -8
- package/lib/helpers/composeSignals.js +46 -0
- package/lib/helpers/progressEventReducer.js +32 -0
- package/lib/helpers/resolveConfig.js +57 -0
- package/lib/helpers/throttle.js +5 -3
- package/lib/helpers/trackStream.js +56 -0
- package/lib/platform/common/utils.js +4 -1
- package/lib/utils.js +7 -2
- package/package.json +26 -25
package/index.d.cts
CHANGED
@@ -268,7 +268,8 @@ declare namespace axios {
|
|
268
268
|
| 'document'
|
269
269
|
| 'json'
|
270
270
|
| 'text'
|
271
|
-
| 'stream'
|
271
|
+
| 'stream'
|
272
|
+
| 'formdata';
|
272
273
|
|
273
274
|
type responseEncoding =
|
274
275
|
| 'ascii' | 'ASCII'
|
@@ -353,11 +354,12 @@ declare namespace axios {
|
|
353
354
|
upload?: boolean;
|
354
355
|
download?: boolean;
|
355
356
|
event?: BrowserProgressEvent;
|
357
|
+
lengthComputable: boolean;
|
356
358
|
}
|
357
359
|
|
358
360
|
type Milliseconds = number;
|
359
361
|
|
360
|
-
type AxiosAdapterName = 'xhr' | 'http' | string;
|
362
|
+
type AxiosAdapterName = 'fetch' | 'xhr' | 'http' | string;
|
361
363
|
|
362
364
|
type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName;
|
363
365
|
|
@@ -415,6 +417,7 @@ declare namespace axios {
|
|
415
417
|
lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
|
416
418
|
((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
|
417
419
|
withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);
|
420
|
+
fetchOptions?: Record<string, any>;
|
418
421
|
}
|
419
422
|
|
420
423
|
// Alias
|
package/index.d.ts
CHANGED
@@ -209,7 +209,8 @@ export type ResponseType =
|
|
209
209
|
| 'document'
|
210
210
|
| 'json'
|
211
211
|
| 'text'
|
212
|
-
| 'stream'
|
212
|
+
| 'stream'
|
213
|
+
| 'formdata';
|
213
214
|
|
214
215
|
export type responseEncoding =
|
215
216
|
| 'ascii' | 'ASCII'
|
@@ -294,11 +295,12 @@ export interface AxiosProgressEvent {
|
|
294
295
|
upload?: boolean;
|
295
296
|
download?: boolean;
|
296
297
|
event?: BrowserProgressEvent;
|
298
|
+
lengthComputable: boolean;
|
297
299
|
}
|
298
300
|
|
299
301
|
type Milliseconds = number;
|
300
302
|
|
301
|
-
type AxiosAdapterName = 'xhr' | 'http' | string;
|
303
|
+
type AxiosAdapterName = 'fetch' | 'xhr' | 'http' | string;
|
302
304
|
|
303
305
|
type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName;
|
304
306
|
|
@@ -356,6 +358,7 @@ export interface AxiosRequestConfig<D = any> {
|
|
356
358
|
lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
|
357
359
|
((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
|
358
360
|
withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);
|
361
|
+
fetchOptions?: Record<string, any>;
|
359
362
|
}
|
360
363
|
|
361
364
|
// Alias
|
package/lib/adapters/adapters.js
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
import utils from '../utils.js';
|
2
2
|
import httpAdapter from './http.js';
|
3
3
|
import xhrAdapter from './xhr.js';
|
4
|
+
import fetchAdapter from './fetch.js';
|
4
5
|
import AxiosError from "../core/AxiosError.js";
|
5
6
|
|
6
7
|
const knownAdapters = {
|
7
8
|
http: httpAdapter,
|
8
|
-
xhr: xhrAdapter
|
9
|
+
xhr: xhrAdapter,
|
10
|
+
fetch: fetchAdapter
|
9
11
|
}
|
10
12
|
|
11
13
|
utils.forEach(knownAdapters, (fn, value) => {
|
@@ -0,0 +1,197 @@
|
|
1
|
+
import platform from "../platform/index.js";
|
2
|
+
import utils from "../utils.js";
|
3
|
+
import AxiosError from "../core/AxiosError.js";
|
4
|
+
import composeSignals from "../helpers/composeSignals.js";
|
5
|
+
import {trackStream} from "../helpers/trackStream.js";
|
6
|
+
import AxiosHeaders from "../core/AxiosHeaders.js";
|
7
|
+
import progressEventReducer from "../helpers/progressEventReducer.js";
|
8
|
+
import resolveConfig from "../helpers/resolveConfig.js";
|
9
|
+
import settle from "../core/settle.js";
|
10
|
+
|
11
|
+
const fetchProgressDecorator = (total, fn) => {
|
12
|
+
const lengthComputable = total != null;
|
13
|
+
return (loaded) => setTimeout(() => fn({
|
14
|
+
lengthComputable,
|
15
|
+
total,
|
16
|
+
loaded
|
17
|
+
}));
|
18
|
+
}
|
19
|
+
|
20
|
+
const isFetchSupported = typeof fetch !== 'undefined';
|
21
|
+
|
22
|
+
const supportsRequestStreams = isFetchSupported && (() => {
|
23
|
+
let duplexAccessed = false;
|
24
|
+
|
25
|
+
const hasContentType = new Request(platform.origin, {
|
26
|
+
body: new ReadableStream(),
|
27
|
+
method: 'POST',
|
28
|
+
get duplex() {
|
29
|
+
duplexAccessed = true;
|
30
|
+
return 'half';
|
31
|
+
},
|
32
|
+
}).headers.has('Content-Type');
|
33
|
+
|
34
|
+
return duplexAccessed && !hasContentType;
|
35
|
+
})();
|
36
|
+
|
37
|
+
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
38
|
+
|
39
|
+
const resolvers = {
|
40
|
+
stream: (res) => res.body
|
41
|
+
};
|
42
|
+
|
43
|
+
isFetchSupported && ['text', 'arrayBuffer', 'blob', 'formData'].forEach(type => [
|
44
|
+
resolvers[type] = utils.isFunction(Response.prototype[type]) ? (res) => res[type]() : (_, config) => {
|
45
|
+
throw new AxiosError(`Response type ${type} is not supported`, AxiosError.ERR_NOT_SUPPORT, config);
|
46
|
+
}
|
47
|
+
])
|
48
|
+
|
49
|
+
const getBodyLength = async (body) => {
|
50
|
+
if(utils.isBlob(body)) {
|
51
|
+
return body.size;
|
52
|
+
}
|
53
|
+
|
54
|
+
if(utils.isSpecCompliantForm(body)) {
|
55
|
+
return (await new Request(body).arrayBuffer()).byteLength;
|
56
|
+
}
|
57
|
+
|
58
|
+
if(utils.isArrayBufferView(body)) {
|
59
|
+
return body.byteLength;
|
60
|
+
}
|
61
|
+
|
62
|
+
if(utils.isURLSearchParams(body)) {
|
63
|
+
body = body + '';
|
64
|
+
}
|
65
|
+
|
66
|
+
if(utils.isString(body)) {
|
67
|
+
return (await new TextEncoder().encode(body)).byteLength;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
const resolveBodyLength = async (headers, body) => {
|
72
|
+
const length = utils.toFiniteNumber(headers.getContentLength());
|
73
|
+
|
74
|
+
return length == null ? getBodyLength(body) : length;
|
75
|
+
}
|
76
|
+
|
77
|
+
export default async (config) => {
|
78
|
+
let {
|
79
|
+
url,
|
80
|
+
method,
|
81
|
+
data,
|
82
|
+
signal,
|
83
|
+
cancelToken,
|
84
|
+
timeout,
|
85
|
+
onDownloadProgress,
|
86
|
+
onUploadProgress,
|
87
|
+
responseType,
|
88
|
+
headers,
|
89
|
+
withCredentials = 'same-origin',
|
90
|
+
fetchOptions
|
91
|
+
} = resolveConfig(config);
|
92
|
+
|
93
|
+
responseType = responseType ? (responseType + '').toLowerCase() : 'text';
|
94
|
+
|
95
|
+
let [composedSignal, stopTimeout] = (signal || cancelToken || timeout) ?
|
96
|
+
composeSignals([signal, cancelToken], timeout) : [];
|
97
|
+
|
98
|
+
let finished, request;
|
99
|
+
|
100
|
+
const onFinish = () => {
|
101
|
+
!finished && setTimeout(() => {
|
102
|
+
composedSignal && composedSignal.unsubscribe();
|
103
|
+
});
|
104
|
+
|
105
|
+
finished = true;
|
106
|
+
}
|
107
|
+
|
108
|
+
try {
|
109
|
+
if (onUploadProgress && supportsRequestStreams && method !== 'get' && method !== 'head') {
|
110
|
+
let requestContentLength = await resolveBodyLength(headers, data);
|
111
|
+
|
112
|
+
let _request = new Request(url, {
|
113
|
+
method,
|
114
|
+
body: data,
|
115
|
+
duplex: "half"
|
116
|
+
});
|
117
|
+
|
118
|
+
let contentTypeHeader;
|
119
|
+
|
120
|
+
if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
|
121
|
+
headers.setContentType(contentTypeHeader)
|
122
|
+
}
|
123
|
+
|
124
|
+
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, fetchProgressDecorator(
|
125
|
+
requestContentLength,
|
126
|
+
progressEventReducer(onUploadProgress)
|
127
|
+
));
|
128
|
+
}
|
129
|
+
|
130
|
+
if (!utils.isString(withCredentials)) {
|
131
|
+
withCredentials = withCredentials ? 'cors' : 'omit';
|
132
|
+
}
|
133
|
+
|
134
|
+
request = new Request(url, {
|
135
|
+
...fetchOptions,
|
136
|
+
signal: composedSignal,
|
137
|
+
method,
|
138
|
+
headers: headers.normalize().toJSON(),
|
139
|
+
body: data,
|
140
|
+
duplex: "half",
|
141
|
+
withCredentials
|
142
|
+
});
|
143
|
+
|
144
|
+
let response = await fetch(request);
|
145
|
+
|
146
|
+
const isStreamResponse = responseType === 'stream' || responseType === 'response';
|
147
|
+
|
148
|
+
if (onDownloadProgress || isStreamResponse) {
|
149
|
+
const options = {};
|
150
|
+
|
151
|
+
Object.getOwnPropertyNames(response).forEach(prop => {
|
152
|
+
options[prop] = response[prop];
|
153
|
+
});
|
154
|
+
|
155
|
+
const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
|
156
|
+
|
157
|
+
response = new Response(
|
158
|
+
trackStream(response.body, DEFAULT_CHUNK_SIZE, onDownloadProgress && fetchProgressDecorator(
|
159
|
+
responseContentLength,
|
160
|
+
progressEventReducer(onDownloadProgress, true)
|
161
|
+
), isStreamResponse && onFinish),
|
162
|
+
options
|
163
|
+
);
|
164
|
+
}
|
165
|
+
|
166
|
+
responseType = responseType || 'text';
|
167
|
+
|
168
|
+
let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);
|
169
|
+
|
170
|
+
!isStreamResponse && onFinish();
|
171
|
+
|
172
|
+
stopTimeout && stopTimeout();
|
173
|
+
|
174
|
+
return await new Promise((resolve, reject) => {
|
175
|
+
settle(resolve, reject, {
|
176
|
+
data: responseData,
|
177
|
+
headers: AxiosHeaders.from(response.headers),
|
178
|
+
status: response.status,
|
179
|
+
statusText: response.statusText,
|
180
|
+
config,
|
181
|
+
request
|
182
|
+
})
|
183
|
+
})
|
184
|
+
} catch (err) {
|
185
|
+
onFinish();
|
186
|
+
|
187
|
+
let {code} = err;
|
188
|
+
|
189
|
+
if (err.name === 'NetworkError') {
|
190
|
+
code = AxiosError.ERR_NETWORK;
|
191
|
+
}
|
192
|
+
|
193
|
+
throw AxiosError.from(err, code, config, request);
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
|
package/lib/adapters/http.js
CHANGED
@@ -19,7 +19,7 @@ import fromDataURI from '../helpers/fromDataURI.js';
|
|
19
19
|
import stream from 'stream';
|
20
20
|
import AxiosHeaders from '../core/AxiosHeaders.js';
|
21
21
|
import AxiosTransformStream from '../helpers/AxiosTransformStream.js';
|
22
|
-
import EventEmitter from 'events';
|
22
|
+
import {EventEmitter} from 'events';
|
23
23
|
import formDataToStream from "../helpers/formDataToStream.js";
|
24
24
|
import readBlob from "../helpers/readBlob.js";
|
25
25
|
import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';
|
package/lib/adapters/xhr.js
CHANGED
@@ -1,93 +1,39 @@
|
|
1
|
-
'use strict';
|
2
|
-
|
3
1
|
import utils from './../utils.js';
|
4
2
|
import settle from './../core/settle.js';
|
5
|
-
import cookies from './../helpers/cookies.js';
|
6
|
-
import buildURL from './../helpers/buildURL.js';
|
7
|
-
import buildFullPath from '../core/buildFullPath.js';
|
8
|
-
import isURLSameOrigin from './../helpers/isURLSameOrigin.js';
|
9
3
|
import transitionalDefaults from '../defaults/transitional.js';
|
10
4
|
import AxiosError from '../core/AxiosError.js';
|
11
5
|
import CanceledError from '../cancel/CanceledError.js';
|
12
6
|
import parseProtocol from '../helpers/parseProtocol.js';
|
13
7
|
import platform from '../platform/index.js';
|
14
8
|
import AxiosHeaders from '../core/AxiosHeaders.js';
|
15
|
-
import
|
16
|
-
|
17
|
-
function progressEventReducer(listener, isDownloadStream) {
|
18
|
-
let bytesNotified = 0;
|
19
|
-
const _speedometer = speedometer(50, 250);
|
20
|
-
|
21
|
-
return e => {
|
22
|
-
const loaded = e.loaded;
|
23
|
-
const total = e.lengthComputable ? e.total : undefined;
|
24
|
-
const progressBytes = loaded - bytesNotified;
|
25
|
-
const rate = _speedometer(progressBytes);
|
26
|
-
const inRange = loaded <= total;
|
27
|
-
|
28
|
-
bytesNotified = loaded;
|
29
|
-
|
30
|
-
const data = {
|
31
|
-
loaded,
|
32
|
-
total,
|
33
|
-
progress: total ? (loaded / total) : undefined,
|
34
|
-
bytes: progressBytes,
|
35
|
-
rate: rate ? rate : undefined,
|
36
|
-
estimated: rate && total && inRange ? (total - loaded) / rate : undefined,
|
37
|
-
event: e
|
38
|
-
};
|
39
|
-
|
40
|
-
data[isDownloadStream ? 'download' : 'upload'] = true;
|
41
|
-
|
42
|
-
listener(data);
|
43
|
-
};
|
44
|
-
}
|
9
|
+
import progressEventReducer from '../helpers/progressEventReducer.js';
|
10
|
+
import resolveConfig from "../helpers/resolveConfig.js";
|
45
11
|
|
46
12
|
const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';
|
47
13
|
|
48
14
|
export default isXHRAdapterSupported && function (config) {
|
49
15
|
return new Promise(function dispatchXhrRequest(resolve, reject) {
|
50
|
-
|
51
|
-
|
52
|
-
|
16
|
+
const _config = resolveConfig(config);
|
17
|
+
let requestData = _config.data;
|
18
|
+
const requestHeaders = AxiosHeaders.from(_config.headers).normalize();
|
19
|
+
let {responseType} = _config;
|
53
20
|
let onCanceled;
|
54
21
|
function done() {
|
55
|
-
if (
|
56
|
-
|
22
|
+
if (_config.cancelToken) {
|
23
|
+
_config.cancelToken.unsubscribe(onCanceled);
|
57
24
|
}
|
58
25
|
|
59
|
-
if (
|
60
|
-
|
61
|
-
}
|
62
|
-
}
|
63
|
-
|
64
|
-
let contentType;
|
65
|
-
|
66
|
-
if (utils.isFormData(requestData)) {
|
67
|
-
if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {
|
68
|
-
requestHeaders.setContentType(false); // Let the browser set it
|
69
|
-
} else if ((contentType = requestHeaders.getContentType()) !== false) {
|
70
|
-
// fix semicolon duplication issue for ReactNative FormData implementation
|
71
|
-
const [type, ...tokens] = contentType ? contentType.split(';').map(token => token.trim()).filter(Boolean) : [];
|
72
|
-
requestHeaders.setContentType([type || 'multipart/form-data', ...tokens].join('; '));
|
26
|
+
if (_config.signal) {
|
27
|
+
_config.signal.removeEventListener('abort', onCanceled);
|
73
28
|
}
|
74
29
|
}
|
75
30
|
|
76
31
|
let request = new XMLHttpRequest();
|
77
32
|
|
78
|
-
|
79
|
-
if (config.auth) {
|
80
|
-
const username = config.auth.username || '';
|
81
|
-
const password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';
|
82
|
-
requestHeaders.set('Authorization', 'Basic ' + btoa(username + ':' + password));
|
83
|
-
}
|
84
|
-
|
85
|
-
const fullPath = buildFullPath(config.baseURL, config.url);
|
86
|
-
|
87
|
-
request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
|
33
|
+
request.open(_config.method.toUpperCase(), _config.url, true);
|
88
34
|
|
89
35
|
// Set the request timeout in MS
|
90
|
-
request.timeout =
|
36
|
+
request.timeout = _config.timeout;
|
91
37
|
|
92
38
|
function onloadend() {
|
93
39
|
if (!request) {
|
@@ -149,7 +95,7 @@ export default isXHRAdapterSupported && function (config) {
|
|
149
95
|
return;
|
150
96
|
}
|
151
97
|
|
152
|
-
reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED,
|
98
|
+
reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, _config, request));
|
153
99
|
|
154
100
|
// Clean up request
|
155
101
|
request = null;
|
@@ -159,7 +105,7 @@ export default isXHRAdapterSupported && function (config) {
|
|
159
105
|
request.onerror = function handleError() {
|
160
106
|
// Real errors are hidden from us by the browser
|
161
107
|
// onerror should only fire if it's a network error
|
162
|
-
reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK,
|
108
|
+
reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, _config, request));
|
163
109
|
|
164
110
|
// Clean up request
|
165
111
|
request = null;
|
@@ -167,37 +113,21 @@ export default isXHRAdapterSupported && function (config) {
|
|
167
113
|
|
168
114
|
// Handle timeout
|
169
115
|
request.ontimeout = function handleTimeout() {
|
170
|
-
let timeoutErrorMessage =
|
171
|
-
const transitional =
|
172
|
-
if (
|
173
|
-
timeoutErrorMessage =
|
116
|
+
let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';
|
117
|
+
const transitional = _config.transitional || transitionalDefaults;
|
118
|
+
if (_config.timeoutErrorMessage) {
|
119
|
+
timeoutErrorMessage = _config.timeoutErrorMessage;
|
174
120
|
}
|
175
121
|
reject(new AxiosError(
|
176
122
|
timeoutErrorMessage,
|
177
123
|
transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
|
178
|
-
|
124
|
+
_config,
|
179
125
|
request));
|
180
126
|
|
181
127
|
// Clean up request
|
182
128
|
request = null;
|
183
129
|
};
|
184
130
|
|
185
|
-
// Add xsrf header
|
186
|
-
// This is only done if running in a standard browser environment.
|
187
|
-
// Specifically not if we're in a web worker, or react-native.
|
188
|
-
if(platform.hasStandardBrowserEnv) {
|
189
|
-
withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(config));
|
190
|
-
|
191
|
-
if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(fullPath))) {
|
192
|
-
// Add xsrf header
|
193
|
-
const xsrfValue = config.xsrfHeaderName && config.xsrfCookieName && cookies.read(config.xsrfCookieName);
|
194
|
-
|
195
|
-
if (xsrfValue) {
|
196
|
-
requestHeaders.set(config.xsrfHeaderName, xsrfValue);
|
197
|
-
}
|
198
|
-
}
|
199
|
-
}
|
200
|
-
|
201
131
|
// Remove Content-Type if data is undefined
|
202
132
|
requestData === undefined && requestHeaders.setContentType(null);
|
203
133
|
|
@@ -209,26 +139,26 @@ export default isXHRAdapterSupported && function (config) {
|
|
209
139
|
}
|
210
140
|
|
211
141
|
// Add withCredentials to request if needed
|
212
|
-
if (!utils.isUndefined(
|
213
|
-
request.withCredentials = !!
|
142
|
+
if (!utils.isUndefined(_config.withCredentials)) {
|
143
|
+
request.withCredentials = !!_config.withCredentials;
|
214
144
|
}
|
215
145
|
|
216
146
|
// Add responseType to request if needed
|
217
147
|
if (responseType && responseType !== 'json') {
|
218
|
-
request.responseType =
|
148
|
+
request.responseType = _config.responseType;
|
219
149
|
}
|
220
150
|
|
221
151
|
// Handle progress if needed
|
222
|
-
if (typeof
|
223
|
-
request.addEventListener('progress', progressEventReducer(
|
152
|
+
if (typeof _config.onDownloadProgress === 'function') {
|
153
|
+
request.addEventListener('progress', progressEventReducer(_config.onDownloadProgress, true));
|
224
154
|
}
|
225
155
|
|
226
156
|
// Not all browsers support upload events
|
227
|
-
if (typeof
|
228
|
-
request.upload.addEventListener('progress', progressEventReducer(
|
157
|
+
if (typeof _config.onUploadProgress === 'function' && request.upload) {
|
158
|
+
request.upload.addEventListener('progress', progressEventReducer(_config.onUploadProgress));
|
229
159
|
}
|
230
160
|
|
231
|
-
if (
|
161
|
+
if (_config.cancelToken || _config.signal) {
|
232
162
|
// Handle cancellation
|
233
163
|
// eslint-disable-next-line func-names
|
234
164
|
onCanceled = cancel => {
|
@@ -240,13 +170,13 @@ export default isXHRAdapterSupported && function (config) {
|
|
240
170
|
request = null;
|
241
171
|
};
|
242
172
|
|
243
|
-
|
244
|
-
if (
|
245
|
-
|
173
|
+
_config.cancelToken && _config.cancelToken.subscribe(onCanceled);
|
174
|
+
if (_config.signal) {
|
175
|
+
_config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);
|
246
176
|
}
|
247
177
|
}
|
248
178
|
|
249
|
-
const protocol = parseProtocol(
|
179
|
+
const protocol = parseProtocol(_config.url);
|
250
180
|
|
251
181
|
if (protocol && platform.protocols.indexOf(protocol) === -1) {
|
252
182
|
reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));
|
package/lib/core/AxiosHeaders.js
CHANGED
@@ -100,6 +100,10 @@ class AxiosHeaders {
|
|
100
100
|
setHeaders(header, valueOrRewrite)
|
101
101
|
} else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
|
102
102
|
setHeaders(parseHeaders(header), valueOrRewrite);
|
103
|
+
} else if (utils.isHeaders(header)) {
|
104
|
+
for (const [key, value] of header.entries()) {
|
105
|
+
setHeader(value, key, rewrite);
|
106
|
+
}
|
103
107
|
} else {
|
104
108
|
header != null && setHeader(valueOrRewrite, header, rewrite);
|
105
109
|
}
|
package/lib/core/mergeConfig.js
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
import utils from '../utils.js';
|
4
4
|
import AxiosHeaders from "./AxiosHeaders.js";
|
5
5
|
|
6
|
-
const headersToObject = (thing) => thing instanceof AxiosHeaders ? thing
|
6
|
+
const headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;
|
7
7
|
|
8
8
|
/**
|
9
9
|
* Config-specific merge-function which creates a new config-object
|
package/lib/defaults/index.js
CHANGED
@@ -37,7 +37,7 @@ const defaults = {
|
|
37
37
|
|
38
38
|
transitional: transitionalDefaults,
|
39
39
|
|
40
|
-
adapter: ['xhr', 'http'],
|
40
|
+
adapter: ['xhr', 'http', 'fetch'],
|
41
41
|
|
42
42
|
transformRequest: [function transformRequest(data, headers) {
|
43
43
|
const contentType = headers.getContentType() || '';
|
@@ -58,7 +58,8 @@ const defaults = {
|
|
58
58
|
utils.isBuffer(data) ||
|
59
59
|
utils.isStream(data) ||
|
60
60
|
utils.isFile(data) ||
|
61
|
-
utils.isBlob(data)
|
61
|
+
utils.isBlob(data) ||
|
62
|
+
utils.isReadableStream(data)
|
62
63
|
) {
|
63
64
|
return data;
|
64
65
|
}
|
@@ -101,6 +102,10 @@ const defaults = {
|
|
101
102
|
const forcedJSONParsing = transitional && transitional.forcedJSONParsing;
|
102
103
|
const JSONRequested = this.responseType === 'json';
|
103
104
|
|
105
|
+
if (utils.isResponse(data) || utils.isReadableStream(data)) {
|
106
|
+
return data;
|
107
|
+
}
|
108
|
+
|
104
109
|
if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {
|
105
110
|
const silentJSONParsing = transitional && transitional.silentJSONParsing;
|
106
111
|
const strictJSONParsing = !silentJSONParsing && JSONRequested;
|
package/lib/env/data.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const VERSION = "1.
|
1
|
+
export const VERSION = "1.7.0-beta.0";
|
@@ -65,19 +65,20 @@ class AxiosTransformStream extends stream.Transform{
|
|
65
65
|
|
66
66
|
process.nextTick(() => {
|
67
67
|
self.emit('progress', {
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
(totalBytes - bytesTransferred) / rate : undefined
|
68
|
+
loaded: bytesTransferred,
|
69
|
+
total: totalBytes,
|
70
|
+
progress: totalBytes ? (bytesTransferred / totalBytes) : undefined,
|
71
|
+
bytes: progressBytes,
|
72
|
+
rate: rate ? rate : undefined,
|
73
|
+
estimated: rate && totalBytes && bytesTransferred <= totalBytes ?
|
74
|
+
(totalBytes - bytesTransferred) / rate : undefined,
|
75
|
+
lengthComputable: totalBytes != null
|
75
76
|
});
|
76
77
|
});
|
77
78
|
}, internals.ticksRate);
|
78
79
|
|
79
80
|
const onFinish = () => {
|
80
|
-
internals.updateProgress(true);
|
81
|
+
internals.updateProgress.call(true);
|
81
82
|
};
|
82
83
|
|
83
84
|
this.once('end', onFinish);
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import CanceledError from "../cancel/CanceledError.js";
|
2
|
+
import AxiosError from "../core/AxiosError.js";
|
3
|
+
|
4
|
+
const composeSignals = (signals, timeout) => {
|
5
|
+
let controller = new AbortController();
|
6
|
+
|
7
|
+
let aborted;
|
8
|
+
|
9
|
+
const onabort = function (cancel) {
|
10
|
+
if (!aborted) {
|
11
|
+
aborted = true;
|
12
|
+
unsubscribe();
|
13
|
+
const err = cancel instanceof Error ? cancel : this.reason;
|
14
|
+
controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
let timer = timeout && setTimeout(() => {
|
19
|
+
onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))
|
20
|
+
}, timeout)
|
21
|
+
|
22
|
+
const unsubscribe = () => {
|
23
|
+
if (signals) {
|
24
|
+
timer && clearTimeout(timer);
|
25
|
+
timer = null;
|
26
|
+
signals.forEach(signal => {
|
27
|
+
signal &&
|
28
|
+
(signal.removeEventListener ? signal.removeEventListener('abort', onabort) : signal.unsubscribe(onabort));
|
29
|
+
});
|
30
|
+
signals = null;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
signals.forEach((signal) => signal && signal.addEventListener && signal.addEventListener('abort', onabort));
|
35
|
+
|
36
|
+
const {signal} = controller;
|
37
|
+
|
38
|
+
signal.unsubscribe = unsubscribe;
|
39
|
+
|
40
|
+
return [signal, () => {
|
41
|
+
timer && clearTimeout(timer);
|
42
|
+
timer = null;
|
43
|
+
}];
|
44
|
+
}
|
45
|
+
|
46
|
+
export default composeSignals;
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import speedometer from "./speedometer.js";
|
2
|
+
import throttle from "./throttle.js";
|
3
|
+
|
4
|
+
export default (listener, isDownloadStream, freq = 3) => {
|
5
|
+
let bytesNotified = 0;
|
6
|
+
const _speedometer = speedometer(50, 250);
|
7
|
+
|
8
|
+
return throttle(e => {
|
9
|
+
const loaded = e.loaded;
|
10
|
+
const total = e.lengthComputable ? e.total : undefined;
|
11
|
+
const progressBytes = loaded - bytesNotified;
|
12
|
+
const rate = _speedometer(progressBytes);
|
13
|
+
const inRange = loaded <= total;
|
14
|
+
|
15
|
+
bytesNotified = loaded;
|
16
|
+
|
17
|
+
const data = {
|
18
|
+
loaded,
|
19
|
+
total,
|
20
|
+
progress: total ? (loaded / total) : undefined,
|
21
|
+
bytes: progressBytes,
|
22
|
+
rate: rate ? rate : undefined,
|
23
|
+
estimated: rate && total && inRange ? (total - loaded) / rate : undefined,
|
24
|
+
event: e,
|
25
|
+
lengthComputable: total != null
|
26
|
+
};
|
27
|
+
|
28
|
+
data[isDownloadStream ? 'download' : 'upload'] = true;
|
29
|
+
|
30
|
+
listener(data);
|
31
|
+
}, freq);
|
32
|
+
}
|