axios 1.12.1 → 1.13.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.
@@ -1,9 +1,10 @@
1
- /*! Axios v1.12.1 Copyright (c) 2025 Matt Zabriskie and contributors */
1
+ /*! Axios v1.13.0 Copyright (c) 2025 Matt Zabriskie and contributors */
2
2
  'use strict';
3
3
 
4
4
  const FormData$1 = require('form-data');
5
5
  const crypto = require('crypto');
6
6
  const url = require('url');
7
+ const http2 = require('http2');
7
8
  const proxyFromEnv = require('proxy-from-env');
8
9
  const http = require('http');
9
10
  const https = require('https');
@@ -26,6 +27,13 @@ const followRedirects__default = /*#__PURE__*/_interopDefaultLegacy(followRedire
26
27
  const zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
27
28
  const stream__default = /*#__PURE__*/_interopDefaultLegacy(stream);
28
29
 
30
+ /**
31
+ * Create a bound version of a function with a specified `this` context
32
+ *
33
+ * @param {Function} fn - The function to bind
34
+ * @param {*} thisArg - The value to be passed as the `this` parameter
35
+ * @returns {Function} A new function that will call the original function with the specified `this` context
36
+ */
29
37
  function bind(fn, thisArg) {
30
38
  return function wrap() {
31
39
  return fn.apply(thisArg, arguments);
@@ -381,10 +389,8 @@ function merge(/* obj1, obj2, obj3, ... */) {
381
389
  result[targetKey] = merge({}, val);
382
390
  } else if (isArray(val)) {
383
391
  result[targetKey] = val.slice();
384
- } else {
385
- if (!skipUndefined || !isUndefined(val)) {
386
- result[targetKey] = val;
387
- }
392
+ } else if (!skipUndefined || !isUndefined(val)) {
393
+ result[targetKey] = val;
388
394
  }
389
395
  };
390
396
 
@@ -1277,7 +1283,7 @@ class InterceptorManager {
1277
1283
  *
1278
1284
  * @param {Number} id The ID that was returned by `use`
1279
1285
  *
1280
- * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise
1286
+ * @returns {void}
1281
1287
  */
1282
1288
  eject(id) {
1283
1289
  if (this.handlers[id]) {
@@ -2152,7 +2158,7 @@ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
2152
2158
  return requestedURL;
2153
2159
  }
2154
2160
 
2155
- const VERSION = "1.12.1";
2161
+ const VERSION = "1.13.0";
2156
2162
 
2157
2163
  function parseProtocol(url) {
2158
2164
  const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url);
@@ -2729,6 +2735,13 @@ const brotliOptions = {
2729
2735
  finishFlush: zlib__default["default"].constants.BROTLI_OPERATION_FLUSH
2730
2736
  };
2731
2737
 
2738
+ const {
2739
+ HTTP2_HEADER_SCHEME,
2740
+ HTTP2_HEADER_METHOD,
2741
+ HTTP2_HEADER_PATH,
2742
+ HTTP2_HEADER_STATUS
2743
+ } = http2.constants;
2744
+
2732
2745
  const isBrotliSupported = utils$1.isFunction(zlib__default["default"].createBrotliDecompress);
2733
2746
 
2734
2747
  const {http: httpFollow, https: httpsFollow} = followRedirects__default["default"];
@@ -2748,6 +2761,100 @@ const flushOnFinish = (stream, [throttled, flush]) => {
2748
2761
  return throttled;
2749
2762
  };
2750
2763
 
2764
+ class Http2Sessions {
2765
+ constructor() {
2766
+ this.sessions = Object.create(null);
2767
+ }
2768
+
2769
+ getSession(authority, options) {
2770
+ options = Object.assign({
2771
+ sessionTimeout: 1000
2772
+ }, options);
2773
+
2774
+ let authoritySessions;
2775
+
2776
+ if ((authoritySessions = this.sessions[authority])) {
2777
+ let len = authoritySessions.length;
2778
+
2779
+ for (let i = 0; i < len; i++) {
2780
+ const [sessionHandle, sessionOptions] = authoritySessions[i];
2781
+ if (!sessionHandle.destroyed && !sessionHandle.closed && util__default["default"].isDeepStrictEqual(sessionOptions, options)) {
2782
+ return sessionHandle;
2783
+ }
2784
+ }
2785
+ }
2786
+
2787
+ const session = http2.connect(authority, options);
2788
+
2789
+ let removed;
2790
+
2791
+ const removeSession = () => {
2792
+ if (removed) {
2793
+ return;
2794
+ }
2795
+
2796
+ removed = true;
2797
+
2798
+ let entries = authoritySessions, len = entries.length, i = len;
2799
+
2800
+ while (i--) {
2801
+ if (entries[i][0] === session) {
2802
+ entries.splice(i, 1);
2803
+ if (len === 1) {
2804
+ delete this.sessions[authority];
2805
+ return;
2806
+ }
2807
+ }
2808
+ }
2809
+ };
2810
+
2811
+ const originalRequestFn = session.request;
2812
+
2813
+ const {sessionTimeout} = options;
2814
+
2815
+ if(sessionTimeout != null) {
2816
+
2817
+ let timer;
2818
+ let streamsCount = 0;
2819
+
2820
+ session.request = function () {
2821
+ const stream = originalRequestFn.apply(this, arguments);
2822
+
2823
+ streamsCount++;
2824
+
2825
+ if (timer) {
2826
+ clearTimeout(timer);
2827
+ timer = null;
2828
+ }
2829
+
2830
+ stream.once('close', () => {
2831
+ if (!--streamsCount) {
2832
+ timer = setTimeout(() => {
2833
+ timer = null;
2834
+ removeSession();
2835
+ }, sessionTimeout);
2836
+ }
2837
+ });
2838
+
2839
+ return stream;
2840
+ };
2841
+ }
2842
+
2843
+ session.once('close', removeSession);
2844
+
2845
+ let entries = this.sessions[authority], entry = [
2846
+ session,
2847
+ options
2848
+ ];
2849
+
2850
+ entries ? this.sessions[authority].push(entry) : authoritySessions = this.sessions[authority] = [entry];
2851
+
2852
+ return session;
2853
+ }
2854
+ }
2855
+
2856
+ const http2Sessions = new Http2Sessions();
2857
+
2751
2858
 
2752
2859
  /**
2753
2860
  * If the proxy or config beforeRedirects functions are defined, call them with the options
@@ -2860,16 +2967,68 @@ const resolveFamily = ({address, family}) => {
2860
2967
 
2861
2968
  const buildAddressEntry = (address, family) => resolveFamily(utils$1.isObject(address) ? address : {address, family});
2862
2969
 
2970
+ const http2Transport = {
2971
+ request(options, cb) {
2972
+ const authority = options.protocol + '//' + options.hostname + ':' + (options.port || 80);
2973
+
2974
+ const {http2Options, headers} = options;
2975
+
2976
+ const session = http2Sessions.getSession(authority, http2Options);
2977
+
2978
+ const http2Headers = {
2979
+ [HTTP2_HEADER_SCHEME]: options.protocol.replace(':', ''),
2980
+ [HTTP2_HEADER_METHOD]: options.method,
2981
+ [HTTP2_HEADER_PATH]: options.path,
2982
+ };
2983
+
2984
+ utils$1.forEach(headers, (header, name) => {
2985
+ name.charAt(0) !== ':' && (http2Headers[name] = header);
2986
+ });
2987
+
2988
+ const req = session.request(http2Headers);
2989
+
2990
+ req.once('response', (responseHeaders) => {
2991
+ const response = req; //duplex
2992
+
2993
+ responseHeaders = Object.assign({}, responseHeaders);
2994
+
2995
+ const status = responseHeaders[HTTP2_HEADER_STATUS];
2996
+
2997
+ delete responseHeaders[HTTP2_HEADER_STATUS];
2998
+
2999
+ response.headers = responseHeaders;
3000
+
3001
+ response.statusCode = +status;
3002
+
3003
+ cb(response);
3004
+ });
3005
+
3006
+ return req;
3007
+ }
3008
+ };
3009
+
2863
3010
  /*eslint consistent-return:0*/
2864
3011
  const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
2865
3012
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
2866
- let {data, lookup, family} = config;
3013
+ let {data, lookup, family, httpVersion = 1, http2Options} = config;
2867
3014
  const {responseType, responseEncoding} = config;
2868
3015
  const method = config.method.toUpperCase();
2869
3016
  let isDone;
2870
3017
  let rejected = false;
2871
3018
  let req;
2872
3019
 
3020
+ httpVersion = +httpVersion;
3021
+
3022
+ if (Number.isNaN(httpVersion)) {
3023
+ throw TypeError(`Invalid protocol version: '${config.httpVersion}' is not a number`);
3024
+ }
3025
+
3026
+ if (httpVersion !== 1 && httpVersion !== 2) {
3027
+ throw TypeError(`Unsupported protocol version '${httpVersion}'`);
3028
+ }
3029
+
3030
+ const isHttp2 = httpVersion === 2;
3031
+
2873
3032
  if (lookup) {
2874
3033
  const _lookup = callbackify$1(lookup, (value) => utils$1.isArray(value) ? value : [value]);
2875
3034
  // hotfix to support opt.all option which is required for node 20.x
@@ -2886,8 +3045,17 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
2886
3045
  };
2887
3046
  }
2888
3047
 
2889
- // temporary internal emitter until the AxiosRequest class will be implemented
2890
- const emitter = new events.EventEmitter();
3048
+ const abortEmitter = new events.EventEmitter();
3049
+
3050
+ function abort(reason) {
3051
+ try {
3052
+ abortEmitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
3053
+ } catch(err) {
3054
+ console.warn('emit error', err);
3055
+ }
3056
+ }
3057
+
3058
+ abortEmitter.once('abort', reject);
2891
3059
 
2892
3060
  const onFinished = () => {
2893
3061
  if (config.cancelToken) {
@@ -2898,29 +3066,40 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
2898
3066
  config.signal.removeEventListener('abort', abort);
2899
3067
  }
2900
3068
 
2901
- emitter.removeAllListeners();
3069
+ abortEmitter.removeAllListeners();
2902
3070
  };
2903
3071
 
2904
- onDone((value, isRejected) => {
3072
+ if (config.cancelToken || config.signal) {
3073
+ config.cancelToken && config.cancelToken.subscribe(abort);
3074
+ if (config.signal) {
3075
+ config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort);
3076
+ }
3077
+ }
3078
+
3079
+ onDone((response, isRejected) => {
2905
3080
  isDone = true;
3081
+
2906
3082
  if (isRejected) {
2907
3083
  rejected = true;
2908
3084
  onFinished();
3085
+ return;
3086
+ }
3087
+
3088
+ const {data} = response;
3089
+
3090
+ if (data instanceof stream__default["default"].Readable || data instanceof stream__default["default"].Duplex) {
3091
+ const offListeners = stream__default["default"].finished(data, () => {
3092
+ offListeners();
3093
+ onFinished();
3094
+ });
3095
+ } else {
3096
+ onFinished();
2909
3097
  }
2910
3098
  });
2911
3099
 
2912
- function abort(reason) {
2913
- emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
2914
- }
2915
3100
 
2916
- emitter.once('abort', reject);
2917
3101
 
2918
- if (config.cancelToken || config.signal) {
2919
- config.cancelToken && config.cancelToken.subscribe(abort);
2920
- if (config.signal) {
2921
- config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort);
2922
- }
2923
- }
3102
+
2924
3103
 
2925
3104
  // Parse url
2926
3105
  const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
@@ -3126,7 +3305,8 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3126
3305
  protocol,
3127
3306
  family,
3128
3307
  beforeRedirect: dispatchBeforeRedirect,
3129
- beforeRedirects: {}
3308
+ beforeRedirects: {},
3309
+ http2Options
3130
3310
  };
3131
3311
 
3132
3312
  // cacheable-lookup integration hotfix
@@ -3143,18 +3323,23 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3143
3323
  let transport;
3144
3324
  const isHttpsRequest = isHttps.test(options.protocol);
3145
3325
  options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
3146
- if (config.transport) {
3147
- transport = config.transport;
3148
- } else if (config.maxRedirects === 0) {
3149
- transport = isHttpsRequest ? https__default["default"] : http__default["default"];
3326
+
3327
+ if (isHttp2) {
3328
+ transport = http2Transport;
3150
3329
  } else {
3151
- if (config.maxRedirects) {
3152
- options.maxRedirects = config.maxRedirects;
3153
- }
3154
- if (config.beforeRedirect) {
3155
- options.beforeRedirects.config = config.beforeRedirect;
3330
+ if (config.transport) {
3331
+ transport = config.transport;
3332
+ } else if (config.maxRedirects === 0) {
3333
+ transport = isHttpsRequest ? https__default["default"] : http__default["default"];
3334
+ } else {
3335
+ if (config.maxRedirects) {
3336
+ options.maxRedirects = config.maxRedirects;
3337
+ }
3338
+ if (config.beforeRedirect) {
3339
+ options.beforeRedirects.config = config.beforeRedirect;
3340
+ }
3341
+ transport = isHttpsRequest ? httpsFollow : httpFollow;
3156
3342
  }
3157
- transport = isHttpsRequest ? httpsFollow : httpFollow;
3158
3343
  }
3159
3344
 
3160
3345
  if (config.maxBodyLength > -1) {
@@ -3174,7 +3359,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3174
3359
 
3175
3360
  const streams = [res];
3176
3361
 
3177
- const responseLength = +res.headers['content-length'];
3362
+ const responseLength = utils$1.toFiniteNumber(res.headers['content-length']);
3178
3363
 
3179
3364
  if (onDownloadProgress || maxDownloadRate) {
3180
3365
  const transformStream = new AxiosTransformStream$1({
@@ -3237,10 +3422,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3237
3422
 
3238
3423
  responseStream = streams.length > 1 ? stream__default["default"].pipeline(streams, utils$1.noop) : streams[0];
3239
3424
 
3240
- const offListeners = stream__default["default"].finished(responseStream, () => {
3241
- offListeners();
3242
- onFinished();
3243
- });
3425
+
3244
3426
 
3245
3427
  const response = {
3246
3428
  status: res.statusCode,
@@ -3252,7 +3434,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3252
3434
 
3253
3435
  if (responseType === 'stream') {
3254
3436
  response.data = responseStream;
3255
- settle(resolve, reject, response);
3437
+ settle(resolve, abort, response);
3256
3438
  } else {
3257
3439
  const responseBuffer = [];
3258
3440
  let totalResponseBytes = 0;
@@ -3266,7 +3448,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3266
3448
  // stream.destroy() emit aborted event before calling reject() on Node.js v16
3267
3449
  rejected = true;
3268
3450
  responseStream.destroy();
3269
- reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
3451
+ abort(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
3270
3452
  AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
3271
3453
  }
3272
3454
  });
@@ -3308,7 +3490,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3308
3490
  });
3309
3491
  }
3310
3492
 
3311
- emitter.once('abort', err => {
3493
+ abortEmitter.once('abort', err => {
3312
3494
  if (!responseStream.destroyed) {
3313
3495
  responseStream.emit('error', err);
3314
3496
  responseStream.destroy();
@@ -3316,9 +3498,12 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3316
3498
  });
3317
3499
  });
3318
3500
 
3319
- emitter.once('abort', err => {
3320
- reject(err);
3321
- req.destroy(err);
3501
+ abortEmitter.once('abort', err => {
3502
+ if (req.close) {
3503
+ req.close();
3504
+ } else {
3505
+ req.destroy(err);
3506
+ }
3322
3507
  });
3323
3508
 
3324
3509
  // Handle errors
@@ -3340,7 +3525,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3340
3525
  const timeout = parseInt(config.timeout, 10);
3341
3526
 
3342
3527
  if (Number.isNaN(timeout)) {
3343
- reject(new AxiosError(
3528
+ abort(new AxiosError(
3344
3529
  'error trying to parse `config.timeout` to int',
3345
3530
  AxiosError.ERR_BAD_OPTION_VALUE,
3346
3531
  config,
@@ -3362,13 +3547,12 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3362
3547
  if (config.timeoutErrorMessage) {
3363
3548
  timeoutErrorMessage = config.timeoutErrorMessage;
3364
3549
  }
3365
- reject(new AxiosError(
3550
+ abort(new AxiosError(
3366
3551
  timeoutErrorMessage,
3367
3552
  transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
3368
3553
  config,
3369
3554
  req
3370
3555
  ));
3371
- abort();
3372
3556
  });
3373
3557
  }
3374
3558
 
@@ -3395,7 +3579,8 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3395
3579
 
3396
3580
  data.pipe(req);
3397
3581
  } else {
3398
- req.end(data);
3582
+ data && req.write(data);
3583
+ req.end();
3399
3584
  }
3400
3585
  });
3401
3586
  };
@@ -3417,27 +3602,38 @@ const cookies = platform.hasStandardBrowserEnv ?
3417
3602
 
3418
3603
  // Standard browser envs support document.cookie
3419
3604
  {
3420
- write(name, value, expires, path, domain, secure) {
3421
- const cookie = [name + '=' + encodeURIComponent(value)];
3422
-
3423
- utils$1.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());
3424
-
3425
- utils$1.isString(path) && cookie.push('path=' + path);
3605
+ write(name, value, expires, path, domain, secure, sameSite) {
3606
+ if (typeof document === 'undefined') return;
3426
3607
 
3427
- utils$1.isString(domain) && cookie.push('domain=' + domain);
3608
+ const cookie = [`${name}=${encodeURIComponent(value)}`];
3428
3609
 
3429
- secure === true && cookie.push('secure');
3610
+ if (utils$1.isNumber(expires)) {
3611
+ cookie.push(`expires=${new Date(expires).toUTCString()}`);
3612
+ }
3613
+ if (utils$1.isString(path)) {
3614
+ cookie.push(`path=${path}`);
3615
+ }
3616
+ if (utils$1.isString(domain)) {
3617
+ cookie.push(`domain=${domain}`);
3618
+ }
3619
+ if (secure === true) {
3620
+ cookie.push('secure');
3621
+ }
3622
+ if (utils$1.isString(sameSite)) {
3623
+ cookie.push(`SameSite=${sameSite}`);
3624
+ }
3430
3625
 
3431
3626
  document.cookie = cookie.join('; ');
3432
3627
  },
3433
3628
 
3434
3629
  read(name) {
3435
- const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
3436
- return (match ? decodeURIComponent(match[3]) : null);
3630
+ if (typeof document === 'undefined') return null;
3631
+ const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)'));
3632
+ return match ? decodeURIComponent(match[1]) : null;
3437
3633
  },
3438
3634
 
3439
3635
  remove(name) {
3440
- this.write(name, '', Date.now() - 86400000);
3636
+ this.write(name, '', Date.now() - 86400000, '/');
3441
3637
  }
3442
3638
  }
3443
3639
 
@@ -3480,11 +3676,11 @@ function mergeConfig(config1, config2) {
3480
3676
  }
3481
3677
 
3482
3678
  // eslint-disable-next-line consistent-return
3483
- function mergeDeepProperties(a, b, prop , caseless) {
3679
+ function mergeDeepProperties(a, b, prop, caseless) {
3484
3680
  if (!utils$1.isUndefined(b)) {
3485
- return getMergedValue(a, b, prop , caseless);
3681
+ return getMergedValue(a, b, prop, caseless);
3486
3682
  } else if (!utils$1.isUndefined(a)) {
3487
- return getMergedValue(undefined, a, prop , caseless);
3683
+ return getMergedValue(undefined, a, prop, caseless);
3488
3684
  }
3489
3685
  }
3490
3686
 
@@ -3542,7 +3738,7 @@ function mergeConfig(config1, config2) {
3542
3738
  socketPath: defaultToConfig2,
3543
3739
  responseEncoding: defaultToConfig2,
3544
3740
  validateStatus: mergeDirectKeys,
3545
- headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)
3741
+ headers: (a, b, prop) => mergeDeepProperties(headersToObject(a), headersToObject(b), prop, true)
3546
3742
  };
3547
3743
 
3548
3744
  utils$1.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {
@@ -3932,9 +4128,9 @@ const DEFAULT_CHUNK_SIZE = 64 * 1024;
3932
4128
 
3933
4129
  const {isFunction} = utils$1;
3934
4130
 
3935
- const globalFetchAPI = (({fetch, Request, Response}) => ({
3936
- fetch, Request, Response
3937
- }))(utils$1.global);
4131
+ const globalFetchAPI = (({Request, Response}) => ({
4132
+ Request, Response
4133
+ }))(utils$1.global);
3938
4134
 
3939
4135
  const {
3940
4136
  ReadableStream: ReadableStream$1, TextEncoder: TextEncoder$1
@@ -3950,8 +4146,12 @@ const test = (fn, ...args) => {
3950
4146
  };
3951
4147
 
3952
4148
  const factory = (env) => {
3953
- const {fetch, Request, Response} = Object.assign({}, globalFetchAPI, env);
3954
- const isFetchSupported = isFunction(fetch);
4149
+ env = utils$1.merge.call({
4150
+ skipUndefined: true
4151
+ }, globalFetchAPI, env);
4152
+
4153
+ const {fetch: envFetch, Request, Response} = env;
4154
+ const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';
3955
4155
  const isRequestSupported = isFunction(Request);
3956
4156
  const isResponseSupported = isFunction(Response);
3957
4157
 
@@ -4054,6 +4254,8 @@ const factory = (env) => {
4054
4254
  fetchOptions
4055
4255
  } = resolveConfig(config);
4056
4256
 
4257
+ let _fetch = envFetch || fetch;
4258
+
4057
4259
  responseType = responseType ? (responseType + '').toLowerCase() : 'text';
4058
4260
 
4059
4261
  let composedSignal = composeSignals$1([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
@@ -4113,7 +4315,7 @@ const factory = (env) => {
4113
4315
 
4114
4316
  request = isRequestSupported && new Request(url, resolvedOptions);
4115
4317
 
4116
- let response = await (isRequestSupported ? fetch(request, fetchOptions) : fetch(url, resolvedOptions));
4318
+ let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));
4117
4319
 
4118
4320
  const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');
4119
4321
 
@@ -4176,12 +4378,8 @@ const factory = (env) => {
4176
4378
  const seedCache = new Map();
4177
4379
 
4178
4380
  const getFetch = (config) => {
4179
- let env = utils$1.merge.call({
4180
- skipUndefined: true
4181
- }, globalFetchAPI, config ? config.env : null);
4182
-
4381
+ let env = (config && config.env) || {};
4183
4382
  const {fetch, Request, Response} = env;
4184
-
4185
4383
  const seeds = [
4186
4384
  Request, Response, fetch
4187
4385
  ];
@@ -4203,6 +4401,15 @@ const getFetch = (config) => {
4203
4401
 
4204
4402
  getFetch();
4205
4403
 
4404
+ /**
4405
+ * Known adapters mapping.
4406
+ * Provides environment-specific adapters for Axios:
4407
+ * - `http` for Node.js
4408
+ * - `xhr` for browsers
4409
+ * - `fetch` for fetch API-based requests
4410
+ *
4411
+ * @type {Object<string, Function|Object>}
4412
+ */
4206
4413
  const knownAdapters = {
4207
4414
  http: httpAdapter,
4208
4415
  xhr: xhrAdapter,
@@ -4211,71 +4418,107 @@ const knownAdapters = {
4211
4418
  }
4212
4419
  };
4213
4420
 
4421
+ // Assign adapter names for easier debugging and identification
4214
4422
  utils$1.forEach(knownAdapters, (fn, value) => {
4215
4423
  if (fn) {
4216
4424
  try {
4217
- Object.defineProperty(fn, 'name', {value});
4425
+ Object.defineProperty(fn, 'name', { value });
4218
4426
  } catch (e) {
4219
4427
  // eslint-disable-next-line no-empty
4220
4428
  }
4221
- Object.defineProperty(fn, 'adapterName', {value});
4429
+ Object.defineProperty(fn, 'adapterName', { value });
4222
4430
  }
4223
4431
  });
4224
4432
 
4433
+ /**
4434
+ * Render a rejection reason string for unknown or unsupported adapters
4435
+ *
4436
+ * @param {string} reason
4437
+ * @returns {string}
4438
+ */
4225
4439
  const renderReason = (reason) => `- ${reason}`;
4226
4440
 
4441
+ /**
4442
+ * Check if the adapter is resolved (function, null, or false)
4443
+ *
4444
+ * @param {Function|null|false} adapter
4445
+ * @returns {boolean}
4446
+ */
4227
4447
  const isResolvedHandle = (adapter) => utils$1.isFunction(adapter) || adapter === null || adapter === false;
4228
4448
 
4229
- const adapters = {
4230
- getAdapter: (adapters, config) => {
4231
- adapters = utils$1.isArray(adapters) ? adapters : [adapters];
4232
-
4233
- const {length} = adapters;
4234
- let nameOrAdapter;
4235
- let adapter;
4449
+ /**
4450
+ * Get the first suitable adapter from the provided list.
4451
+ * Tries each adapter in order until a supported one is found.
4452
+ * Throws an AxiosError if no adapter is suitable.
4453
+ *
4454
+ * @param {Array<string|Function>|string|Function} adapters - Adapter(s) by name or function.
4455
+ * @param {Object} config - Axios request configuration
4456
+ * @throws {AxiosError} If no suitable adapter is available
4457
+ * @returns {Function} The resolved adapter function
4458
+ */
4459
+ function getAdapter(adapters, config) {
4460
+ adapters = utils$1.isArray(adapters) ? adapters : [adapters];
4236
4461
 
4237
- const rejectedReasons = {};
4462
+ const { length } = adapters;
4463
+ let nameOrAdapter;
4464
+ let adapter;
4238
4465
 
4239
- for (let i = 0; i < length; i++) {
4240
- nameOrAdapter = adapters[i];
4241
- let id;
4466
+ const rejectedReasons = {};
4242
4467
 
4243
- adapter = nameOrAdapter;
4468
+ for (let i = 0; i < length; i++) {
4469
+ nameOrAdapter = adapters[i];
4470
+ let id;
4244
4471
 
4245
- if (!isResolvedHandle(nameOrAdapter)) {
4246
- adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
4472
+ adapter = nameOrAdapter;
4247
4473
 
4248
- if (adapter === undefined) {
4249
- throw new AxiosError(`Unknown adapter '${id}'`);
4250
- }
4251
- }
4474
+ if (!isResolvedHandle(nameOrAdapter)) {
4475
+ adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
4252
4476
 
4253
- if (adapter && (utils$1.isFunction(adapter) || (adapter = adapter.get(config)))) {
4254
- break;
4477
+ if (adapter === undefined) {
4478
+ throw new AxiosError(`Unknown adapter '${id}'`);
4255
4479
  }
4480
+ }
4256
4481
 
4257
- rejectedReasons[id || '#' + i] = adapter;
4482
+ if (adapter && (utils$1.isFunction(adapter) || (adapter = adapter.get(config)))) {
4483
+ break;
4258
4484
  }
4259
4485
 
4260
- if (!adapter) {
4486
+ rejectedReasons[id || '#' + i] = adapter;
4487
+ }
4261
4488
 
4262
- const reasons = Object.entries(rejectedReasons)
4263
- .map(([id, state]) => `adapter ${id} ` +
4264
- (state === false ? 'is not supported by the environment' : 'is not available in the build')
4265
- );
4489
+ if (!adapter) {
4490
+ const reasons = Object.entries(rejectedReasons)
4491
+ .map(([id, state]) => `adapter ${id} ` +
4492
+ (state === false ? 'is not supported by the environment' : 'is not available in the build')
4493
+ );
4266
4494
 
4267
- let s = length ?
4268
- (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) :
4269
- 'as no adapter specified';
4495
+ let s = length ?
4496
+ (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) :
4497
+ 'as no adapter specified';
4270
4498
 
4271
- throw new AxiosError(
4272
- `There is no suitable adapter to dispatch the request ` + s,
4273
- 'ERR_NOT_SUPPORT'
4274
- );
4275
- }
4499
+ throw new AxiosError(
4500
+ `There is no suitable adapter to dispatch the request ` + s,
4501
+ 'ERR_NOT_SUPPORT'
4502
+ );
4503
+ }
4276
4504
 
4277
- return adapter;
4278
- },
4505
+ return adapter;
4506
+ }
4507
+
4508
+ /**
4509
+ * Exports Axios adapters and utility to resolve an adapter
4510
+ */
4511
+ const adapters = {
4512
+ /**
4513
+ * Resolve an adapter from a list of adapter names or functions.
4514
+ * @type {Function}
4515
+ */
4516
+ getAdapter,
4517
+
4518
+ /**
4519
+ * Exposes all known adapters
4520
+ * @type {Object<string, Function|Object>}
4521
+ */
4279
4522
  adapters: knownAdapters
4280
4523
  };
4281
4524
 
@@ -4606,8 +4849,6 @@ class Axios {
4606
4849
 
4607
4850
  let newConfig = config;
4608
4851
 
4609
- i = 0;
4610
-
4611
4852
  while (i < len) {
4612
4853
  const onFulfilled = requestInterceptorChain[i++];
4613
4854
  const onRejected = requestInterceptorChain[i++];
@@ -4911,6 +5152,12 @@ const HttpStatusCode = {
4911
5152
  LoopDetected: 508,
4912
5153
  NotExtended: 510,
4913
5154
  NetworkAuthenticationRequired: 511,
5155
+ WebServerIsDown: 521,
5156
+ ConnectionTimedOut: 522,
5157
+ OriginIsUnreachable: 523,
5158
+ TimeoutOccurred: 524,
5159
+ SslHandshakeFailed: 525,
5160
+ InvalidSslCertificate: 526,
4914
5161
  };
4915
5162
 
4916
5163
  Object.entries(HttpStatusCode).forEach(([key, value]) => {