axios 1.10.0 → 1.12.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.cts CHANGED
@@ -6,7 +6,7 @@ type MethodsHeaders = Partial<{
6
6
  [Key in axios.Method as Lowercase<Key>]: AxiosHeaders;
7
7
  } & {common: AxiosHeaders}>;
8
8
 
9
- type AxiosHeaderMatcher = (this: AxiosHeaders, value: string, name: string, headers: RawAxiosHeaders) => boolean;
9
+ type AxiosHeaderMatcher = string | RegExp | ((this: AxiosHeaders, value: string, name: string) => boolean);
10
10
 
11
11
  type AxiosHeaderParser = (this: AxiosHeaders, value: axios.AxiosHeaderValue, header: string) => any;
12
12
 
@@ -16,6 +16,8 @@ type ContentType = axios.AxiosHeaderValue | 'text/html' | 'text/plain' | 'multip
16
16
 
17
17
  type CommonResponseHeadersList = 'Server' | 'Content-Type' | 'Content-Length' | 'Cache-Control'| 'Content-Encoding';
18
18
 
19
+ type BrowserProgressEvent = any;
20
+
19
21
  declare class AxiosHeaders {
20
22
  constructor(
21
23
  headers?: RawAxiosHeaders | AxiosHeaders | string
@@ -77,6 +79,8 @@ declare class AxiosHeaders {
77
79
  getAuthorization(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue;
78
80
  hasAuthorization(matcher?: AxiosHeaderMatcher): boolean;
79
81
 
82
+ getSetCookie(): string[];
83
+
80
84
  [Symbol.iterator](): IterableIterator<[string, axios.AxiosHeaderValue]>;
81
85
  }
82
86
 
@@ -96,7 +100,16 @@ declare class AxiosError<T = unknown, D = any> extends Error {
96
100
  isAxiosError: boolean;
97
101
  status?: number;
98
102
  toJSON: () => object;
99
- cause?: Error;
103
+ cause?: unknown;
104
+ event?: BrowserProgressEvent;
105
+ static from<T = unknown, D = any>(
106
+ error: Error | unknown,
107
+ code?: string,
108
+ config?: axios.InternalAxiosRequestConfig<D>,
109
+ request?: any,
110
+ response?: axios.AxiosResponse<T, D>,
111
+ customProps?: object,
112
+ ): AxiosError<T, D>;
100
113
  static readonly ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS";
101
114
  static readonly ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE";
102
115
  static readonly ERR_BAD_OPTION = "ERR_BAD_OPTION";
@@ -342,8 +355,6 @@ declare namespace axios {
342
355
 
343
356
  type MaxDownloadRate = number;
344
357
 
345
- type BrowserProgressEvent = any;
346
-
347
358
  interface AxiosProgressEvent {
348
359
  loaded: number;
349
360
  total?: number;
@@ -412,6 +423,9 @@ declare namespace axios {
412
423
  insecureHTTPParser?: boolean;
413
424
  env?: {
414
425
  FormData?: new (...args: any[]) => object;
426
+ fetch?: (input: URL | Request | string, init?: RequestInit) => Promise<Response>;
427
+ Request?: new (input: (RequestInfo | URL), init?: RequestInit) => Request;
428
+ Response?: new (body?: (BodyInit | null), init?: ResponseInit) => Response;
415
429
  };
416
430
  formSerializer?: FormSerializerOptions;
417
431
  family?: AddressFamily;
@@ -424,7 +438,7 @@ declare namespace axios {
424
438
  // Alias
425
439
  type RawAxiosRequestConfig<D = any> = AxiosRequestConfig<D>;
426
440
 
427
- interface InternalAxiosRequestConfig<D = any> extends AxiosRequestConfig {
441
+ interface InternalAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {
428
442
  headers: AxiosRequestHeaders;
429
443
  }
430
444
 
@@ -450,11 +464,11 @@ declare namespace axios {
450
464
  headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial<HeadersDefaults>;
451
465
  }
452
466
 
453
- interface AxiosResponse<T = any, D = any> {
467
+ interface AxiosResponse<T = any, D = any, H = {}> {
454
468
  data: T;
455
469
  status: number;
456
470
  statusText: string;
457
- headers: RawAxiosResponseHeaders | AxiosResponseHeaders;
471
+ headers: H & RawAxiosResponseHeaders | AxiosResponseHeaders;
458
472
  config: InternalAxiosRequestConfig<D>;
459
473
  request?: any;
460
474
  }
@@ -542,6 +556,7 @@ declare namespace axios {
542
556
  formToJSON(form: GenericFormData|GenericHTMLFormElement): object;
543
557
  getAdapter(adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined): AxiosAdapter;
544
558
  AxiosHeaders: typeof AxiosHeaders;
559
+ mergeConfig<D = any>(config1: AxiosRequestConfig<D>, config2: AxiosRequestConfig<D>): AxiosRequestConfig<D>;
545
560
  }
546
561
  }
547
562
 
package/index.d.ts CHANGED
@@ -355,12 +355,16 @@ export interface AxiosRequestConfig<D = any> {
355
355
  insecureHTTPParser?: boolean;
356
356
  env?: {
357
357
  FormData?: new (...args: any[]) => object;
358
+ fetch?: (input: URL | Request | string, init?: RequestInit) => Promise<Response>;
359
+ Request?: new (input: (RequestInfo | URL), init?: RequestInit) => Request;
360
+ Response?: new (body?: (BodyInit | null), init?: ResponseInit) => Response;
358
361
  };
359
362
  formSerializer?: FormSerializerOptions;
360
363
  family?: AddressFamily;
361
364
  lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
362
365
  ((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
363
366
  withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);
367
+ parseReviver?: (this: any, key: string, value: any) => any;
364
368
  fetchOptions?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'> | Record<string, any>;
365
369
  }
366
370
 
@@ -393,11 +397,11 @@ export interface CreateAxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>
393
397
  headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial<HeadersDefaults>;
394
398
  }
395
399
 
396
- export interface AxiosResponse<T = any, D = any> {
400
+ export interface AxiosResponse<T = any, D = any, H = {}> {
397
401
  data: T;
398
402
  status: number;
399
403
  statusText: string;
400
- headers: RawAxiosResponseHeaders | AxiosResponseHeaders;
404
+ headers: H & RawAxiosResponseHeaders | AxiosResponseHeaders;
401
405
  config: InternalAxiosRequestConfig<D>;
402
406
  request?: any;
403
407
  }
@@ -418,7 +422,8 @@ export class AxiosError<T = unknown, D = any> extends Error {
418
422
  isAxiosError: boolean;
419
423
  status?: number;
420
424
  toJSON: () => object;
421
- cause?: Error;
425
+ cause?: unknown;
426
+ event?: BrowserProgressEvent;
422
427
  static from<T = unknown, D = any>(
423
428
  error: Error | unknown,
424
429
  code?: string,
@@ -442,6 +447,7 @@ export class AxiosError<T = unknown, D = any> extends Error {
442
447
  }
443
448
 
444
449
  export class CanceledError<T> extends AxiosError<T> {
450
+ readonly name: "CanceledError";
445
451
  }
446
452
 
447
453
  export type AxiosPromise<T = any> = Promise<AxiosResponse<T>>;
@@ -542,7 +548,7 @@ export function isAxiosError<T = any, D = any>(payload: any): payload is AxiosEr
542
548
 
543
549
  export function spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
544
550
 
545
- export function isCancel(value: any): value is Cancel;
551
+ export function isCancel<T = any>(value: any): value is CanceledError<T>;
546
552
 
547
553
  export function all<T>(values: Array<T | Promise<T>>): Promise<T[]>;
548
554
 
@@ -1,13 +1,15 @@
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
+ import * as fetchAdapter from './fetch.js';
5
5
  import AxiosError from "../core/AxiosError.js";
6
6
 
7
7
  const knownAdapters = {
8
8
  http: httpAdapter,
9
9
  xhr: xhrAdapter,
10
- fetch: fetchAdapter
10
+ fetch: {
11
+ get: fetchAdapter.getFetch,
12
+ }
11
13
  }
12
14
 
13
15
  utils.forEach(knownAdapters, (fn, value) => {
@@ -26,7 +28,7 @@ const renderReason = (reason) => `- ${reason}`;
26
28
  const isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;
27
29
 
28
30
  export default {
29
- getAdapter: (adapters) => {
31
+ getAdapter: (adapters, config) => {
30
32
  adapters = utils.isArray(adapters) ? adapters : [adapters];
31
33
 
32
34
  const {length} = adapters;
@@ -49,7 +51,7 @@ export default {
49
51
  }
50
52
  }
51
53
 
52
- if (adapter) {
54
+ if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {
53
55
  break;
54
56
  }
55
57
 
@@ -8,14 +8,18 @@ import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../h
8
8
  import resolveConfig from "../helpers/resolveConfig.js";
9
9
  import settle from "../core/settle.js";
10
10
 
11
- const isFetchSupported = typeof fetch === 'function' && typeof Request === 'function' && typeof Response === 'function';
12
- const isReadableStreamSupported = isFetchSupported && typeof ReadableStream === 'function';
11
+ const DEFAULT_CHUNK_SIZE = 64 * 1024;
12
+
13
+ const {isFunction} = utils;
14
+
15
+ const globalFetchAPI = (({fetch, Request, Response}) => ({
16
+ fetch, Request, Response
17
+ }))(utils.global);
18
+
19
+ const {
20
+ ReadableStream, TextEncoder
21
+ } = utils.global;
13
22
 
14
- // used only inside the fetch adapter
15
- const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?
16
- ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :
17
- async (str) => new Uint8Array(await new Response(str).arrayBuffer())
18
- );
19
23
 
20
24
  const test = (fn, ...args) => {
21
25
  try {
@@ -25,205 +29,258 @@ const test = (fn, ...args) => {
25
29
  }
26
30
  }
27
31
 
28
- const supportsRequestStream = isReadableStreamSupported && test(() => {
29
- let duplexAccessed = false;
32
+ const factory = (env) => {
33
+ const {fetch, Request, Response} = Object.assign({}, globalFetchAPI, env);
34
+ const isFetchSupported = isFunction(fetch);
35
+ const isRequestSupported = isFunction(Request);
36
+ const isResponseSupported = isFunction(Response);
30
37
 
31
- const hasContentType = new Request(platform.origin, {
32
- body: new ReadableStream(),
33
- method: 'POST',
34
- get duplex() {
35
- duplexAccessed = true;
36
- return 'half';
37
- },
38
- }).headers.has('Content-Type');
38
+ if (!isFetchSupported) {
39
+ return false;
40
+ }
39
41
 
40
- return duplexAccessed && !hasContentType;
41
- });
42
+ const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);
42
43
 
43
- const DEFAULT_CHUNK_SIZE = 64 * 1024;
44
+ const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?
45
+ ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :
46
+ async (str) => new Uint8Array(await new Request(str).arrayBuffer())
47
+ );
44
48
 
45
- const supportsResponseStream = isReadableStreamSupported &&
46
- test(() => utils.isReadableStream(new Response('').body));
49
+ const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
50
+ let duplexAccessed = false;
47
51
 
52
+ const hasContentType = new Request(platform.origin, {
53
+ body: new ReadableStream(),
54
+ method: 'POST',
55
+ get duplex() {
56
+ duplexAccessed = true;
57
+ return 'half';
58
+ },
59
+ }).headers.has('Content-Type');
48
60
 
49
- const resolvers = {
50
- stream: supportsResponseStream && ((res) => res.body)
51
- };
61
+ return duplexAccessed && !hasContentType;
62
+ });
63
+
64
+ const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&
65
+ test(() => utils.isReadableStream(new Response('').body));
66
+
67
+ const resolvers = {
68
+ stream: supportsResponseStream && ((res) => res.body)
69
+ };
70
+
71
+ isFetchSupported && ((() => {
72
+ ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {
73
+ !resolvers[type] && (resolvers[type] = (res, config) => {
74
+ let method = res && res[type];
75
+
76
+ if (method) {
77
+ return method.call(res);
78
+ }
52
79
 
53
- isFetchSupported && (((res) => {
54
- ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {
55
- !resolvers[type] && (resolvers[type] = utils.isFunction(res[type]) ? (res) => res[type]() :
56
- (_, config) => {
57
80
  throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);
58
81
  })
59
- });
60
- })(new Response));
82
+ });
83
+ })());
61
84
 
62
- const getBodyLength = async (body) => {
63
- if (body == null) {
64
- return 0;
65
- }
85
+ const getBodyLength = async (body) => {
86
+ if (body == null) {
87
+ return 0;
88
+ }
66
89
 
67
- if(utils.isBlob(body)) {
68
- return body.size;
69
- }
90
+ if (utils.isBlob(body)) {
91
+ return body.size;
92
+ }
70
93
 
71
- if(utils.isSpecCompliantForm(body)) {
72
- const _request = new Request(platform.origin, {
73
- method: 'POST',
74
- body,
75
- });
76
- return (await _request.arrayBuffer()).byteLength;
77
- }
94
+ if (utils.isSpecCompliantForm(body)) {
95
+ const _request = new Request(platform.origin, {
96
+ method: 'POST',
97
+ body,
98
+ });
99
+ return (await _request.arrayBuffer()).byteLength;
100
+ }
78
101
 
79
- if(utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {
80
- return body.byteLength;
81
- }
102
+ if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {
103
+ return body.byteLength;
104
+ }
82
105
 
83
- if(utils.isURLSearchParams(body)) {
84
- body = body + '';
85
- }
106
+ if (utils.isURLSearchParams(body)) {
107
+ body = body + '';
108
+ }
86
109
 
87
- if(utils.isString(body)) {
88
- return (await encodeText(body)).byteLength;
110
+ if (utils.isString(body)) {
111
+ return (await encodeText(body)).byteLength;
112
+ }
89
113
  }
90
- }
91
114
 
92
- const resolveBodyLength = async (headers, body) => {
93
- const length = utils.toFiniteNumber(headers.getContentLength());
115
+ const resolveBodyLength = async (headers, body) => {
116
+ const length = utils.toFiniteNumber(headers.getContentLength());
94
117
 
95
- return length == null ? getBodyLength(body) : length;
96
- }
118
+ return length == null ? getBodyLength(body) : length;
119
+ }
97
120
 
98
- export default isFetchSupported && (async (config) => {
99
- let {
100
- url,
101
- method,
102
- data,
103
- signal,
104
- cancelToken,
105
- timeout,
106
- onDownloadProgress,
107
- onUploadProgress,
108
- responseType,
109
- headers,
110
- withCredentials = 'same-origin',
111
- fetchOptions
112
- } = resolveConfig(config);
113
-
114
- responseType = responseType ? (responseType + '').toLowerCase() : 'text';
115
-
116
- let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
117
-
118
- let request;
119
-
120
- const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
121
+ return async (config) => {
122
+ let {
123
+ url,
124
+ method,
125
+ data,
126
+ signal,
127
+ cancelToken,
128
+ timeout,
129
+ onDownloadProgress,
130
+ onUploadProgress,
131
+ responseType,
132
+ headers,
133
+ withCredentials = 'same-origin',
134
+ fetchOptions
135
+ } = resolveConfig(config);
136
+
137
+ responseType = responseType ? (responseType + '').toLowerCase() : 'text';
138
+
139
+ let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
140
+
141
+ let request = null;
142
+
143
+ const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
121
144
  composedSignal.unsubscribe();
122
- });
145
+ });
123
146
 
124
- let requestContentLength;
147
+ let requestContentLength;
125
148
 
126
- try {
127
- if (
128
- onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&
129
- (requestContentLength = await resolveBodyLength(headers, data)) !== 0
130
- ) {
131
- let _request = new Request(url, {
132
- method: 'POST',
133
- body: data,
134
- duplex: "half"
135
- });
149
+ try {
150
+ if (
151
+ onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&
152
+ (requestContentLength = await resolveBodyLength(headers, data)) !== 0
153
+ ) {
154
+ let _request = new Request(url, {
155
+ method: 'POST',
156
+ body: data,
157
+ duplex: "half"
158
+ });
136
159
 
137
- let contentTypeHeader;
160
+ let contentTypeHeader;
138
161
 
139
- if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
140
- headers.setContentType(contentTypeHeader)
141
- }
162
+ if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
163
+ headers.setContentType(contentTypeHeader)
164
+ }
142
165
 
143
- if (_request.body) {
144
- const [onProgress, flush] = progressEventDecorator(
145
- requestContentLength,
146
- progressEventReducer(asyncDecorator(onUploadProgress))
147
- );
166
+ if (_request.body) {
167
+ const [onProgress, flush] = progressEventDecorator(
168
+ requestContentLength,
169
+ progressEventReducer(asyncDecorator(onUploadProgress))
170
+ );
148
171
 
149
- data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
172
+ data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
173
+ }
150
174
  }
151
- }
152
175
 
153
- if (!utils.isString(withCredentials)) {
154
- withCredentials = withCredentials ? 'include' : 'omit';
155
- }
176
+ if (!utils.isString(withCredentials)) {
177
+ withCredentials = withCredentials ? 'include' : 'omit';
178
+ }
156
179
 
157
- // Cloudflare Workers throws when credentials are defined
158
- // see https://github.com/cloudflare/workerd/issues/902
159
- const isCredentialsSupported = "credentials" in Request.prototype;
160
- request = new Request(url, {
161
- ...fetchOptions,
162
- signal: composedSignal,
163
- method: method.toUpperCase(),
164
- headers: headers.normalize().toJSON(),
165
- body: data,
166
- duplex: "half",
167
- credentials: isCredentialsSupported ? withCredentials : undefined
168
- });
180
+ // Cloudflare Workers throws when credentials are defined
181
+ // see https://github.com/cloudflare/workerd/issues/902
182
+ const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype;
169
183
 
170
- let response = await fetch(request, fetchOptions);
184
+ const resolvedOptions = {
185
+ ...fetchOptions,
186
+ signal: composedSignal,
187
+ method: method.toUpperCase(),
188
+ headers: headers.normalize().toJSON(),
189
+ body: data,
190
+ duplex: "half",
191
+ credentials: isCredentialsSupported ? withCredentials : undefined
192
+ };
171
193
 
172
- const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');
194
+ request = isRequestSupported && new Request(url, resolvedOptions);
173
195
 
174
- if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {
175
- const options = {};
196
+ let response = await (isRequestSupported ? fetch(request, fetchOptions) : fetch(url, resolvedOptions));
176
197
 
177
- ['status', 'statusText', 'headers'].forEach(prop => {
178
- options[prop] = response[prop];
179
- });
198
+ const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');
180
199
 
181
- const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
200
+ if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {
201
+ const options = {};
182
202
 
183
- const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
184
- responseContentLength,
185
- progressEventReducer(asyncDecorator(onDownloadProgress), true)
186
- ) || [];
203
+ ['status', 'statusText', 'headers'].forEach(prop => {
204
+ options[prop] = response[prop];
205
+ });
187
206
 
188
- response = new Response(
189
- trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
190
- flush && flush();
191
- unsubscribe && unsubscribe();
192
- }),
193
- options
194
- );
195
- }
207
+ const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
208
+
209
+ const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
210
+ responseContentLength,
211
+ progressEventReducer(asyncDecorator(onDownloadProgress), true)
212
+ ) || [];
196
213
 
197
- responseType = responseType || 'text';
214
+ response = new Response(
215
+ trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
216
+ flush && flush();
217
+ unsubscribe && unsubscribe();
218
+ }),
219
+ options
220
+ );
221
+ }
222
+
223
+ responseType = responseType || 'text';
198
224
 
199
- let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);
225
+ let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);
200
226
 
201
- !isStreamResponse && unsubscribe && unsubscribe();
227
+ !isStreamResponse && unsubscribe && unsubscribe();
202
228
 
203
- return await new Promise((resolve, reject) => {
204
- settle(resolve, reject, {
205
- data: responseData,
206
- headers: AxiosHeaders.from(response.headers),
207
- status: response.status,
208
- statusText: response.statusText,
209
- config,
210
- request
229
+ return await new Promise((resolve, reject) => {
230
+ settle(resolve, reject, {
231
+ data: responseData,
232
+ headers: AxiosHeaders.from(response.headers),
233
+ status: response.status,
234
+ statusText: response.statusText,
235
+ config,
236
+ request
237
+ })
211
238
  })
212
- })
213
- } catch (err) {
214
- unsubscribe && unsubscribe();
215
-
216
- if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
217
- throw Object.assign(
218
- new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),
219
- {
220
- cause: err.cause || err
221
- }
222
- )
239
+ } catch (err) {
240
+ unsubscribe && unsubscribe();
241
+
242
+ if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
243
+ throw Object.assign(
244
+ new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),
245
+ {
246
+ cause: err.cause || err
247
+ }
248
+ )
249
+ }
250
+
251
+ throw AxiosError.from(err, err && err.code, config, request);
223
252
  }
253
+ }
254
+ }
255
+
256
+ const seedCache = new Map();
224
257
 
225
- throw AxiosError.from(err, err && err.code, config, request);
258
+ export const getFetch = (config) => {
259
+ let env = utils.merge.call({
260
+ skipUndefined: true
261
+ }, globalFetchAPI, config ? config.env : null);
262
+
263
+ const {fetch, Request, Response} = env;
264
+
265
+ const seeds = [
266
+ Request, Response, fetch
267
+ ];
268
+
269
+ let len = seeds.length, i = len,
270
+ seed, target, map = seedCache;
271
+
272
+ while (i--) {
273
+ seed = seeds[i];
274
+ target = map.get(seed);
275
+
276
+ target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))
277
+
278
+ map = target;
226
279
  }
227
- });
228
280
 
281
+ return target;
282
+ };
283
+
284
+ const adapter = getFetch();
229
285
 
286
+ export default adapter;
@@ -25,6 +25,7 @@ import readBlob from "../helpers/readBlob.js";
25
25
  import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';
26
26
  import callbackify from "../helpers/callbackify.js";
27
27
  import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../helpers/progressEventReducer.js";
28
+ import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js';
28
29
 
29
30
  const zlibOptions = {
30
31
  flush: zlib.constants.Z_SYNC_FLUSH,
@@ -46,6 +47,7 @@ const supportedProtocols = platform.protocols.map(protocol => {
46
47
  return protocol + ':';
47
48
  });
48
49
 
50
+
49
51
  const flushOnFinish = (stream, [throttled, flush]) => {
50
52
  stream
51
53
  .on('end', flush)
@@ -54,6 +56,7 @@ const flushOnFinish = (stream, [throttled, flush]) => {
54
56
  return throttled;
55
57
  }
56
58
 
59
+
57
60
  /**
58
61
  * If the proxy or config beforeRedirects functions are defined, call them with the options
59
62
  * object.
@@ -233,6 +236,21 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
233
236
  const protocol = parsed.protocol || supportedProtocols[0];
234
237
 
235
238
  if (protocol === 'data:') {
239
+ // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
240
+ if (config.maxContentLength > -1) {
241
+ // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.
242
+ const dataUrl = String(config.url || fullPath || '');
243
+ const estimated = estimateDataURLDecodedBytes(dataUrl);
244
+
245
+ if (estimated > config.maxContentLength) {
246
+ return reject(new AxiosError(
247
+ 'maxContentLength size of ' + config.maxContentLength + ' exceeded',
248
+ AxiosError.ERR_BAD_RESPONSE,
249
+ config
250
+ ));
251
+ }
252
+ }
253
+
236
254
  let convertedData;
237
255
 
238
256
  if (method !== 'GET') {