faster-axios 0.0.1-security → 1.17.3

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 faster-axios might be problematic. Click here for more details.

Files changed (78) hide show
  1. package/CHANGELOG.md +1747 -0
  2. package/LICENSE +7 -0
  3. package/MIGRATION_GUIDE.md +877 -0
  4. package/README.md +2426 -5
  5. package/index.d.cts +715 -0
  6. package/index.d.ts +734 -0
  7. package/index.js +45 -0
  8. package/lib/adapters/README.md +36 -0
  9. package/lib/adapters/adapters.js +132 -0
  10. package/lib/adapters/fetch.js +473 -0
  11. package/lib/adapters/http.js +1312 -0
  12. package/lib/adapters/xhr.js +227 -0
  13. package/lib/axios.js +89 -0
  14. package/lib/cancel/CancelToken.js +135 -0
  15. package/lib/cancel/CanceledError.js +22 -0
  16. package/lib/cancel/isCancel.js +5 -0
  17. package/lib/core/Axios.js +281 -0
  18. package/lib/core/AxiosError.js +176 -0
  19. package/lib/core/AxiosHeaders.js +348 -0
  20. package/lib/core/InterceptorManager.js +72 -0
  21. package/lib/core/README.md +8 -0
  22. package/lib/core/analytics.js +0 -0
  23. package/lib/core/buildFullPath.js +22 -0
  24. package/lib/core/dispatchRequest.js +89 -0
  25. package/lib/core/eval.js +41 -0
  26. package/lib/core/mergeConfig.js +124 -0
  27. package/lib/core/settle.js +27 -0
  28. package/lib/core/transformData.js +28 -0
  29. package/lib/defaults/index.js +177 -0
  30. package/lib/defaults/transitional.js +8 -0
  31. package/lib/env/README.md +3 -0
  32. package/lib/env/classes/FormData.js +2 -0
  33. package/lib/env/data.js +1 -0
  34. package/lib/helpers/AxiosTransformStream.js +156 -0
  35. package/lib/helpers/AxiosURLSearchParams.js +61 -0
  36. package/lib/helpers/HttpStatusCode.js +77 -0
  37. package/lib/helpers/README.md +7 -0
  38. package/lib/helpers/ZlibHeaderTransformStream.js +29 -0
  39. package/lib/helpers/bind.js +14 -0
  40. package/lib/helpers/buildURL.js +66 -0
  41. package/lib/helpers/callbackify.js +18 -0
  42. package/lib/helpers/combineURLs.js +15 -0
  43. package/lib/helpers/composeSignals.js +57 -0
  44. package/lib/helpers/cookies.js +60 -0
  45. package/lib/helpers/deprecatedMethod.js +31 -0
  46. package/lib/helpers/estimateDataURLDecodedBytes.js +100 -0
  47. package/lib/helpers/formDataToJSON.js +97 -0
  48. package/lib/helpers/formDataToStream.js +119 -0
  49. package/lib/helpers/fromDataURI.js +66 -0
  50. package/lib/helpers/isAbsoluteURL.js +19 -0
  51. package/lib/helpers/isAxiosError.js +14 -0
  52. package/lib/helpers/isURLSameOrigin.js +16 -0
  53. package/lib/helpers/null.js +2 -0
  54. package/lib/helpers/parseHeaders.js +69 -0
  55. package/lib/helpers/parseProtocol.js +6 -0
  56. package/lib/helpers/progressEventReducer.js +54 -0
  57. package/lib/helpers/readBlob.js +15 -0
  58. package/lib/helpers/resolveConfig.js +106 -0
  59. package/lib/helpers/sanitizeHeaderValue.js +60 -0
  60. package/lib/helpers/shouldBypassProxy.js +178 -0
  61. package/lib/helpers/speedometer.js +55 -0
  62. package/lib/helpers/spread.js +28 -0
  63. package/lib/helpers/throttle.js +44 -0
  64. package/lib/helpers/toFormData.js +249 -0
  65. package/lib/helpers/toURLEncodedForm.js +19 -0
  66. package/lib/helpers/trackStream.js +89 -0
  67. package/lib/helpers/validator.js +112 -0
  68. package/lib/platform/browser/classes/Blob.js +3 -0
  69. package/lib/platform/browser/classes/FormData.js +3 -0
  70. package/lib/platform/browser/classes/URLSearchParams.js +4 -0
  71. package/lib/platform/browser/index.js +13 -0
  72. package/lib/platform/common/utils.js +52 -0
  73. package/lib/platform/index.js +7 -0
  74. package/lib/platform/node/classes/FormData.js +3 -0
  75. package/lib/platform/node/classes/URLSearchParams.js +4 -0
  76. package/lib/platform/node/index.js +37 -0
  77. package/lib/utils.js +932 -0
  78. package/package.json +185 -6
package/index.js ADDED
@@ -0,0 +1,45 @@
1
+ import axios from './lib/axios.js';
2
+
3
+ // This module is intended to unwrap Axios default export as named.
4
+ // Keep top-level export same with static properties
5
+ // so that it can keep same with es module or cjs
6
+ const {
7
+ Axios,
8
+ AxiosError,
9
+ CanceledError,
10
+ isCancel,
11
+ CancelToken,
12
+ VERSION,
13
+ all,
14
+ Cancel,
15
+ isAxiosError,
16
+ spread,
17
+ toFormData,
18
+ AxiosHeaders,
19
+ HttpStatusCode,
20
+ formToJSON,
21
+ getAdapter,
22
+ mergeConfig,
23
+ create,
24
+ } = axios;
25
+
26
+ export {
27
+ axios as default,
28
+ create,
29
+ Axios,
30
+ AxiosError,
31
+ CanceledError,
32
+ isCancel,
33
+ CancelToken,
34
+ VERSION,
35
+ all,
36
+ Cancel,
37
+ isAxiosError,
38
+ spread,
39
+ toFormData,
40
+ AxiosHeaders,
41
+ HttpStatusCode,
42
+ formToJSON,
43
+ getAdapter,
44
+ mergeConfig,
45
+ };
@@ -0,0 +1,36 @@
1
+ # axios // adapters
2
+
3
+ The modules under `adapters/` are modules that handle dispatching a request and settling a returned `Promise` once a response is received.
4
+
5
+ ## Example
6
+
7
+ ```js
8
+ var settle = require('../core/settle');
9
+
10
+ module.exports = function myAdapter(config) {
11
+ // At this point:
12
+ // - config has been merged with defaults
13
+ // - request transformers have already run
14
+ // - request interceptors have already run
15
+
16
+ // Make the request using config provided
17
+ // Upon response settle the Promise
18
+
19
+ return new Promise(function (resolve, reject) {
20
+ var response = {
21
+ data: responseData,
22
+ status: request.status,
23
+ statusText: request.statusText,
24
+ headers: responseHeaders,
25
+ config: config,
26
+ request: request,
27
+ };
28
+
29
+ settle(resolve, reject, response);
30
+
31
+ // From here:
32
+ // - response transformers will run
33
+ // - response interceptors will run
34
+ });
35
+ };
36
+ ```
@@ -0,0 +1,132 @@
1
+ import utils from '../utils.js';
2
+ import httpAdapter from './http.js';
3
+ import xhrAdapter from './xhr.js';
4
+ import * as fetchAdapter from './fetch.js';
5
+ import AxiosError from '../core/AxiosError.js';
6
+
7
+ /**
8
+ * Known adapters mapping.
9
+ * Provides environment-specific adapters for Axios:
10
+ * - `http` for Node.js
11
+ * - `xhr` for browsers
12
+ * - `fetch` for fetch API-based requests
13
+ *
14
+ * @type {Object<string, Function|Object>}
15
+ */
16
+ const knownAdapters = {
17
+ http: httpAdapter,
18
+ xhr: xhrAdapter,
19
+ fetch: {
20
+ get: fetchAdapter.getFetch,
21
+ },
22
+ };
23
+
24
+ // Assign adapter names for easier debugging and identification
25
+ utils.forEach(knownAdapters, (fn, value) => {
26
+ if (fn) {
27
+ try {
28
+ // Null-proto descriptors so a polluted Object.prototype.get cannot turn
29
+ // these data descriptors into accessor descriptors on the way in.
30
+ Object.defineProperty(fn, 'name', { __proto__: null, value });
31
+ } catch (e) {
32
+ // eslint-disable-next-line no-empty
33
+ }
34
+ Object.defineProperty(fn, 'adapterName', { __proto__: null, value });
35
+ }
36
+ });
37
+
38
+ /**
39
+ * Render a rejection reason string for unknown or unsupported adapters
40
+ *
41
+ * @param {string} reason
42
+ * @returns {string}
43
+ */
44
+ const renderReason = (reason) => `- ${reason}`;
45
+
46
+ /**
47
+ * Check if the adapter is resolved (function, null, or false)
48
+ *
49
+ * @param {Function|null|false} adapter
50
+ * @returns {boolean}
51
+ */
52
+ const isResolvedHandle = (adapter) =>
53
+ utils.isFunction(adapter) || adapter === null || adapter === false;
54
+
55
+ /**
56
+ * Get the first suitable adapter from the provided list.
57
+ * Tries each adapter in order until a supported one is found.
58
+ * Throws an AxiosError if no adapter is suitable.
59
+ *
60
+ * @param {Array<string|Function>|string|Function} adapters - Adapter(s) by name or function.
61
+ * @param {Object} config - Axios request configuration
62
+ * @throws {AxiosError} If no suitable adapter is available
63
+ * @returns {Function} The resolved adapter function
64
+ */
65
+ function getAdapter(adapters, config) {
66
+ adapters = utils.isArray(adapters) ? adapters : [adapters];
67
+
68
+ const { length } = adapters;
69
+ let nameOrAdapter;
70
+ let adapter;
71
+
72
+ const rejectedReasons = {};
73
+
74
+ for (let i = 0; i < length; i++) {
75
+ nameOrAdapter = adapters[i];
76
+ let id;
77
+
78
+ adapter = nameOrAdapter;
79
+
80
+ if (!isResolvedHandle(nameOrAdapter)) {
81
+ adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
82
+
83
+ if (adapter === undefined) {
84
+ throw new AxiosError(`Unknown adapter '${id}'`);
85
+ }
86
+ }
87
+
88
+ if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {
89
+ break;
90
+ }
91
+
92
+ rejectedReasons[id || '#' + i] = adapter;
93
+ }
94
+
95
+ if (!adapter) {
96
+ const reasons = Object.entries(rejectedReasons).map(
97
+ ([id, state]) =>
98
+ `adapter ${id} ` +
99
+ (state === false ? 'is not supported by the environment' : 'is not available in the build')
100
+ );
101
+
102
+ let s = length
103
+ ? reasons.length > 1
104
+ ? 'since :\n' + reasons.map(renderReason).join('\n')
105
+ : ' ' + renderReason(reasons[0])
106
+ : 'as no adapter specified';
107
+
108
+ throw new AxiosError(
109
+ `There is no suitable adapter to dispatch the request ` + s,
110
+ 'ERR_NOT_SUPPORT'
111
+ );
112
+ }
113
+
114
+ return adapter;
115
+ }
116
+
117
+ /**
118
+ * Exports Axios adapters and utility to resolve an adapter
119
+ */
120
+ export default {
121
+ /**
122
+ * Resolve an adapter from a list of adapter names or functions.
123
+ * @type {Function}
124
+ */
125
+ getAdapter,
126
+
127
+ /**
128
+ * Exposes all known adapters
129
+ * @type {Object<string, Function|Object>}
130
+ */
131
+ adapters: knownAdapters,
132
+ };
@@ -0,0 +1,473 @@
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 {
8
+ progressEventReducer,
9
+ progressEventDecorator,
10
+ asyncDecorator,
11
+ } from '../helpers/progressEventReducer.js';
12
+ import resolveConfig from '../helpers/resolveConfig.js';
13
+ import settle from '../core/settle.js';
14
+ import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js';
15
+ import { VERSION } from '../env/data.js';
16
+ import { toByteStringHeaderObject } from '../helpers/sanitizeHeaderValue.js';
17
+
18
+ const DEFAULT_CHUNK_SIZE = 64 * 1024;
19
+
20
+ const { isFunction } = utils;
21
+
22
+ const test = (fn, ...args) => {
23
+ try {
24
+ return !!fn(...args);
25
+ } catch (e) {
26
+ return false;
27
+ }
28
+ };
29
+
30
+ const factory = (env) => {
31
+ const globalObject =
32
+ utils.global !== undefined && utils.global !== null
33
+ ? utils.global
34
+ : globalThis;
35
+ const { ReadableStream, TextEncoder } = globalObject;
36
+
37
+ env = utils.merge.call(
38
+ {
39
+ skipUndefined: true,
40
+ },
41
+ {
42
+ Request: globalObject.Request,
43
+ Response: globalObject.Response,
44
+ },
45
+ env
46
+ );
47
+
48
+ const { fetch: envFetch, Request, Response } = env;
49
+ const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';
50
+ const isRequestSupported = isFunction(Request);
51
+ const isResponseSupported = isFunction(Response);
52
+
53
+ if (!isFetchSupported) {
54
+ return false;
55
+ }
56
+
57
+ const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);
58
+
59
+ const encodeText =
60
+ isFetchSupported &&
61
+ (typeof TextEncoder === 'function'
62
+ ? (
63
+ (encoder) => (str) =>
64
+ encoder.encode(str)
65
+ )(new TextEncoder())
66
+ : async (str) => new Uint8Array(await new Request(str).arrayBuffer()));
67
+
68
+ const supportsRequestStream =
69
+ isRequestSupported &&
70
+ isReadableStreamSupported &&
71
+ test(() => {
72
+ let duplexAccessed = false;
73
+
74
+ const request = new Request(platform.origin, {
75
+ body: new ReadableStream(),
76
+ method: 'POST',
77
+ get duplex() {
78
+ duplexAccessed = true;
79
+ return 'half';
80
+ },
81
+ });
82
+
83
+ const hasContentType = request.headers.has('Content-Type');
84
+
85
+ if (request.body != null) {
86
+ request.body.cancel();
87
+ }
88
+
89
+ return duplexAccessed && !hasContentType;
90
+ });
91
+
92
+ const supportsResponseStream =
93
+ isResponseSupported &&
94
+ isReadableStreamSupported &&
95
+ test(() => utils.isReadableStream(new Response('').body));
96
+
97
+ const resolvers = {
98
+ stream: supportsResponseStream && ((res) => res.body),
99
+ };
100
+
101
+ isFetchSupported &&
102
+ (() => {
103
+ ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach((type) => {
104
+ !resolvers[type] &&
105
+ (resolvers[type] = (res, config) => {
106
+ let method = res && res[type];
107
+
108
+ if (method) {
109
+ return method.call(res);
110
+ }
111
+
112
+ throw new AxiosError(
113
+ `Response type '${type}' is not supported`,
114
+ AxiosError.ERR_NOT_SUPPORT,
115
+ config
116
+ );
117
+ });
118
+ });
119
+ })();
120
+
121
+ const getBodyLength = async (body) => {
122
+ if (body == null) {
123
+ return 0;
124
+ }
125
+
126
+ if (utils.isBlob(body)) {
127
+ return body.size;
128
+ }
129
+
130
+ if (utils.isSpecCompliantForm(body)) {
131
+ const _request = new Request(platform.origin, {
132
+ method: 'POST',
133
+ body,
134
+ });
135
+ return (await _request.arrayBuffer()).byteLength;
136
+ }
137
+
138
+ if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {
139
+ return body.byteLength;
140
+ }
141
+
142
+ if (utils.isURLSearchParams(body)) {
143
+ body = body + '';
144
+ }
145
+
146
+ if (utils.isString(body)) {
147
+ return (await encodeText(body)).byteLength;
148
+ }
149
+ };
150
+
151
+ const resolveBodyLength = async (headers, body) => {
152
+ const length = utils.toFiniteNumber(headers.getContentLength());
153
+
154
+ return length == null ? getBodyLength(body) : length;
155
+ };
156
+
157
+ return async (config) => {
158
+ let {
159
+ url,
160
+ method,
161
+ data,
162
+ signal,
163
+ cancelToken,
164
+ timeout,
165
+ onDownloadProgress,
166
+ onUploadProgress,
167
+ responseType,
168
+ headers,
169
+ withCredentials = 'same-origin',
170
+ fetchOptions,
171
+ maxContentLength,
172
+ maxBodyLength,
173
+ } = resolveConfig(config);
174
+
175
+ const hasMaxContentLength = utils.isNumber(maxContentLength) && maxContentLength > -1;
176
+ const hasMaxBodyLength = utils.isNumber(maxBodyLength) && maxBodyLength > -1;
177
+
178
+ let _fetch = envFetch || fetch;
179
+
180
+ responseType = responseType ? (responseType + '').toLowerCase() : 'text';
181
+
182
+ let composedSignal = composeSignals(
183
+ [signal, cancelToken && cancelToken.toAbortSignal()],
184
+ timeout
185
+ );
186
+
187
+ let request = null;
188
+
189
+ const unsubscribe =
190
+ composedSignal &&
191
+ composedSignal.unsubscribe &&
192
+ (() => {
193
+ composedSignal.unsubscribe();
194
+ });
195
+
196
+ let requestContentLength;
197
+
198
+ try {
199
+ // Enforce maxContentLength for data: URLs up-front so we never materialize
200
+ // an oversized payload. The HTTP adapter applies the same check (see http.js
201
+ // "if (protocol === 'data:')" branch).
202
+ if (hasMaxContentLength && typeof url === 'string' && url.startsWith('data:')) {
203
+ const estimated = estimateDataURLDecodedBytes(url);
204
+ if (estimated > maxContentLength) {
205
+ throw new AxiosError(
206
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
207
+ AxiosError.ERR_BAD_RESPONSE,
208
+ config,
209
+ request
210
+ );
211
+ }
212
+ }
213
+
214
+ // Enforce maxBodyLength against the outbound request body before dispatch.
215
+ // Mirrors http.js behavior (ERR_BAD_REQUEST / 'Request body larger than
216
+ // maxBodyLength limit'). Skip when the body length cannot be determined
217
+ // (e.g. a live ReadableStream supplied by the caller).
218
+ if (hasMaxBodyLength && method !== 'get' && method !== 'head') {
219
+ const outboundLength = await resolveBodyLength(headers, data);
220
+ if (
221
+ typeof outboundLength === 'number' &&
222
+ isFinite(outboundLength) &&
223
+ outboundLength > maxBodyLength
224
+ ) {
225
+ throw new AxiosError(
226
+ 'Request body larger than maxBodyLength limit',
227
+ AxiosError.ERR_BAD_REQUEST,
228
+ config,
229
+ request
230
+ );
231
+ }
232
+ }
233
+
234
+ if (
235
+ onUploadProgress &&
236
+ supportsRequestStream &&
237
+ method !== 'get' &&
238
+ method !== 'head' &&
239
+ (requestContentLength = await resolveBodyLength(headers, data)) !== 0
240
+ ) {
241
+ let _request = new Request(url, {
242
+ method: 'POST',
243
+ body: data,
244
+ duplex: 'half',
245
+ });
246
+
247
+ let contentTypeHeader;
248
+
249
+ if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
250
+ headers.setContentType(contentTypeHeader);
251
+ }
252
+
253
+ if (_request.body) {
254
+ const [onProgress, flush] = progressEventDecorator(
255
+ requestContentLength,
256
+ progressEventReducer(asyncDecorator(onUploadProgress))
257
+ );
258
+
259
+ data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
260
+ }
261
+ }
262
+
263
+ if (!utils.isString(withCredentials)) {
264
+ withCredentials = withCredentials ? 'include' : 'omit';
265
+ }
266
+
267
+ // Cloudflare Workers throws when credentials are defined
268
+ // see https://github.com/cloudflare/workerd/issues/902
269
+ const isCredentialsSupported = isRequestSupported && 'credentials' in Request.prototype;
270
+
271
+ // If data is FormData and Content-Type is multipart/form-data without boundary,
272
+ // delete it so fetch can set it correctly with the boundary
273
+ if (utils.isFormData(data)) {
274
+ const contentType = headers.getContentType();
275
+ if (
276
+ contentType &&
277
+ /^multipart\/form-data/i.test(contentType) &&
278
+ !/boundary=/i.test(contentType)
279
+ ) {
280
+ headers.delete('content-type');
281
+ }
282
+ }
283
+
284
+ // Set User-Agent header if not already set (fetch defaults to 'node' in Node.js)
285
+ headers.set('User-Agent', 'axios/' + VERSION, false);
286
+
287
+ const resolvedOptions = {
288
+ ...fetchOptions,
289
+ signal: composedSignal,
290
+ method: method.toUpperCase(),
291
+ headers: toByteStringHeaderObject(headers.normalize()),
292
+ body: data,
293
+ duplex: 'half',
294
+ credentials: isCredentialsSupported ? withCredentials : undefined,
295
+ };
296
+
297
+ request = isRequestSupported && new Request(url, resolvedOptions);
298
+
299
+ let response = await (isRequestSupported
300
+ ? _fetch(request, fetchOptions)
301
+ : _fetch(url, resolvedOptions));
302
+
303
+ // Cheap pre-check: if the server honestly declares a content-length that
304
+ // already exceeds the cap, reject before we start streaming.
305
+ if (hasMaxContentLength) {
306
+ const declaredLength = utils.toFiniteNumber(response.headers.get('content-length'));
307
+ if (declaredLength != null && declaredLength > maxContentLength) {
308
+ throw new AxiosError(
309
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
310
+ AxiosError.ERR_BAD_RESPONSE,
311
+ config,
312
+ request
313
+ );
314
+ }
315
+ }
316
+
317
+ const isStreamResponse =
318
+ supportsResponseStream && (responseType === 'stream' || responseType === 'response');
319
+
320
+ if (
321
+ supportsResponseStream &&
322
+ response.body &&
323
+ (onDownloadProgress || hasMaxContentLength || (isStreamResponse && unsubscribe))
324
+ ) {
325
+ const options = {};
326
+
327
+ ['status', 'statusText', 'headers'].forEach((prop) => {
328
+ options[prop] = response[prop];
329
+ });
330
+
331
+ const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
332
+
333
+ const [onProgress, flush] =
334
+ (onDownloadProgress &&
335
+ progressEventDecorator(
336
+ responseContentLength,
337
+ progressEventReducer(asyncDecorator(onDownloadProgress), true)
338
+ )) ||
339
+ [];
340
+
341
+ let bytesRead = 0;
342
+ const onChunkProgress = (loadedBytes) => {
343
+ if (hasMaxContentLength) {
344
+ bytesRead = loadedBytes;
345
+ if (bytesRead > maxContentLength) {
346
+ throw new AxiosError(
347
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
348
+ AxiosError.ERR_BAD_RESPONSE,
349
+ config,
350
+ request
351
+ );
352
+ }
353
+ }
354
+ onProgress && onProgress(loadedBytes);
355
+ };
356
+
357
+ response = new Response(
358
+ trackStream(response.body, DEFAULT_CHUNK_SIZE, onChunkProgress, () => {
359
+ flush && flush();
360
+ unsubscribe && unsubscribe();
361
+ }),
362
+ options
363
+ );
364
+ }
365
+
366
+ responseType = responseType || 'text';
367
+
368
+ let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](
369
+ response,
370
+ config
371
+ );
372
+
373
+ // Fallback enforcement for environments without ReadableStream support
374
+ // (legacy runtimes). Detect materialized size from typed output; skip
375
+ // streams/Response passthrough since the user will read those themselves.
376
+ if (hasMaxContentLength && !supportsResponseStream && !isStreamResponse) {
377
+ let materializedSize;
378
+ if (responseData != null) {
379
+ if (typeof responseData.byteLength === 'number') {
380
+ materializedSize = responseData.byteLength;
381
+ } else if (typeof responseData.size === 'number') {
382
+ materializedSize = responseData.size;
383
+ } else if (typeof responseData === 'string') {
384
+ materializedSize =
385
+ typeof TextEncoder === 'function'
386
+ ? new TextEncoder().encode(responseData).byteLength
387
+ : responseData.length;
388
+ }
389
+ }
390
+ if (typeof materializedSize === 'number' && materializedSize > maxContentLength) {
391
+ throw new AxiosError(
392
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
393
+ AxiosError.ERR_BAD_RESPONSE,
394
+ config,
395
+ request
396
+ );
397
+ }
398
+ }
399
+
400
+ !isStreamResponse && unsubscribe && unsubscribe();
401
+
402
+ return await new Promise((resolve, reject) => {
403
+ settle(resolve, reject, {
404
+ data: responseData,
405
+ headers: AxiosHeaders.from(response.headers),
406
+ status: response.status,
407
+ statusText: response.statusText,
408
+ config,
409
+ request,
410
+ });
411
+ });
412
+ } catch (err) {
413
+ unsubscribe && unsubscribe();
414
+
415
+ // Safari can surface fetch aborts as a DOMException-like object whose
416
+ // branded getters throw. Prefer our composed signal reason before reading
417
+ // the caught error, preserving timeout vs cancellation semantics.
418
+ if (composedSignal && composedSignal.aborted && composedSignal.reason instanceof AxiosError) {
419
+ const canceledError = composedSignal.reason;
420
+ canceledError.config = config;
421
+ request && (canceledError.request = request);
422
+ err !== canceledError && (canceledError.cause = err);
423
+ throw canceledError;
424
+ }
425
+
426
+ if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
427
+ throw Object.assign(
428
+ new AxiosError(
429
+ 'Network Error',
430
+ AxiosError.ERR_NETWORK,
431
+ config,
432
+ request,
433
+ err && err.response
434
+ ),
435
+ {
436
+ cause: err.cause || err,
437
+ }
438
+ );
439
+ }
440
+
441
+ throw AxiosError.from(err, err && err.code, config, request, err && err.response);
442
+ }
443
+ };
444
+ };
445
+
446
+ const seedCache = new Map();
447
+
448
+ export const getFetch = (config) => {
449
+ let env = (config && config.env) || {};
450
+ const { fetch, Request, Response } = env;
451
+ const seeds = [Request, Response, fetch];
452
+
453
+ let len = seeds.length,
454
+ i = len,
455
+ seed,
456
+ target,
457
+ map = seedCache;
458
+
459
+ while (i--) {
460
+ seed = seeds[i];
461
+ target = map.get(seed);
462
+
463
+ target === undefined && map.set(seed, (target = i ? new Map() : factory(env)));
464
+
465
+ map = target;
466
+ }
467
+
468
+ return target;
469
+ };
470
+
471
+ const adapter = getFetch();
472
+
473
+ export default adapter;