@openclaw/slack 2026.6.11 → 2026.6.34

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.
Files changed (102) hide show
  1. package/dist/account-inspect-api.js +1 -1
  2. package/dist/{account-inspect-DOtQbKkB.js → account-inspect-ldU97llt.js} +1 -1
  3. package/dist/{accounts-BPCiCe8y.js → accounts-C9Z3J3lT.js} +8 -1
  4. package/dist/accounts.runtime-4Xez0y2c.js +2 -0
  5. package/dist/{action-runtime-DfJK7zS0.js → action-runtime-z9j2PYiO.js} +4 -4
  6. package/dist/action-runtime.runtime-BuOQERTf.js +2 -0
  7. package/dist/{actions-OhnDIN4l.js → actions-CCTO1mVi.js} +3 -3
  8. package/dist/{actions.runtime-DkFXr3-k.js → actions.runtime-BaBCJbO3.js} +1 -1
  9. package/dist/api.js +12 -12
  10. package/dist/{approval-handler.runtime-CsFrthnF.js → approval-handler.runtime-Cw1Im48B.js} +2 -2
  11. package/dist/{channel-COCbJwom.js → channel-DLPyf4p_.js} +23 -17
  12. package/dist/channel-plugin-api.js +1 -1
  13. package/dist/{channel.setup-DYQGnKPK.js → channel.setup-RewyjVhG.js} +3 -3
  14. package/dist/{directory-config-DDVHDmrN.js → directory-config-NDOJRlhK.js} +1 -1
  15. package/dist/directory-contract-api.js +1 -1
  16. package/dist/{directory-live-DzOkmJVV.js → directory-live-CeVhaEVq.js} +1 -1
  17. package/dist/{interactive-replies-D-22gTp3.js → interactive-replies-BBZN1A9T.js} +1 -1
  18. package/dist/interactive-replies-api.js +1 -1
  19. package/dist/{message-tool-api--zYyTqrR.js → message-tool-api-OXkQLOkR.js} +2 -2
  20. package/dist/message-tool-api.js +1 -1
  21. package/dist/{monitor-Cy-0xYgF.js → monitor-CoF156tn.js} +3 -3
  22. package/dist/{outbound-adapter-CzX4D5K_.js → outbound-adapter-DqEIkSaa.js} +3 -3
  23. package/dist/{pipeline.runtime-5R4HgM_7.js → pipeline.runtime-Lp1AVrkR.js} +74 -59
  24. package/dist/{policy-Bi92bs5t.js → policy-hyhJMisM.js} +1 -1
  25. package/dist/{probe-BRsYAcGR.js → probe-PFduhlzL.js} +8 -2
  26. package/dist/{provider-7YKru1TZ.js → provider-CQvIQMod.js} +49 -31
  27. package/dist/{relay-source-42fP7Ktr.js → relay-source-Bv6k-bAg.js} +1 -1
  28. package/dist/{replies-Dlxge48k.js → replies-DM1Qi_1b.js} +3 -3
  29. package/dist/{reply-blocks-BT_sNsDQ.js → reply-blocks-0ofUZd6K.js} +1 -1
  30. package/dist/runtime-api.js +9 -9
  31. package/dist/{send-CRoD-UQw.js → send-CrC49d83.js} +3 -3
  32. package/dist/send.runtime-B_nPiIPk.js +2 -0
  33. package/dist/{setup-core-BCGzyZhx.js → setup-core-DPMX-Z6o.js} +2 -2
  34. package/dist/setup-plugin-api.js +1 -1
  35. package/dist/{setup-surface-D4GE34e2.js → setup-surface-BCB7d1mL.js} +3 -3
  36. package/dist/{shared-BtJS2bUx.js → shared-CQ2R9FGA.js} +4 -4
  37. package/dist/{slash-dispatch.runtime-D1qKAWNN.js → slash-dispatch.runtime-CCP3os2O.js} +1 -1
  38. package/node_modules/agent-base/README.md +145 -0
  39. package/node_modules/agent-base/dist/src/index.d.ts +78 -0
  40. package/node_modules/agent-base/dist/src/index.js +203 -0
  41. package/node_modules/agent-base/dist/src/index.js.map +1 -0
  42. package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
  43. package/node_modules/agent-base/dist/src/promisify.js +18 -0
  44. package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
  45. package/node_modules/agent-base/package.json +64 -0
  46. package/node_modules/agent-base/src/index.ts +345 -0
  47. package/node_modules/agent-base/src/promisify.ts +33 -0
  48. package/node_modules/axios/CHANGELOG.md +165 -1
  49. package/node_modules/axios/README.md +310 -247
  50. package/node_modules/axios/dist/axios.js +533 -197
  51. package/node_modules/axios/dist/axios.min.js +3 -3
  52. package/node_modules/axios/dist/axios.min.js.map +1 -1
  53. package/node_modules/axios/dist/browser/axios.cjs +564 -161
  54. package/node_modules/axios/dist/esm/axios.js +564 -161
  55. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  56. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  57. package/node_modules/axios/dist/node/axios.cjs +839 -281
  58. package/node_modules/axios/index.d.cts +11 -4
  59. package/node_modules/axios/index.d.ts +7 -2
  60. package/node_modules/axios/lib/adapters/fetch.js +196 -37
  61. package/node_modules/axios/lib/adapters/http.js +328 -185
  62. package/node_modules/axios/lib/adapters/xhr.js +2 -1
  63. package/node_modules/axios/lib/core/Axios.js +4 -2
  64. package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
  65. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  66. package/node_modules/axios/lib/core/mergeConfig.js +34 -0
  67. package/node_modules/axios/lib/defaults/transitional.js +2 -0
  68. package/node_modules/axios/lib/env/data.js +1 -1
  69. package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
  70. package/node_modules/axios/lib/helpers/buildURL.js +6 -4
  71. package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
  72. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  73. package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
  74. package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
  75. package/node_modules/axios/lib/helpers/fromDataURI.js +18 -5
  76. package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
  77. package/node_modules/axios/lib/helpers/resolveConfig.js +17 -9
  78. package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
  79. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  80. package/node_modules/axios/lib/helpers/toFormData.js +41 -11
  81. package/node_modules/axios/lib/utils.js +105 -19
  82. package/node_modules/axios/package.json +31 -13
  83. package/node_modules/https-proxy-agent/README.md +137 -0
  84. package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
  85. package/node_modules/https-proxy-agent/dist/agent.js +177 -0
  86. package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
  87. package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
  88. package/node_modules/https-proxy-agent/dist/index.js +14 -0
  89. package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
  90. package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
  91. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
  92. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
  93. package/node_modules/https-proxy-agent/package.json +56 -0
  94. package/npm-shrinkwrap.json +32 -6
  95. package/package.json +4 -4
  96. package/dist/accounts.runtime-CgWgzjLX.js +0 -2
  97. package/dist/action-runtime.runtime-CIYPRrNy.js +0 -2
  98. package/dist/send.runtime-C_y65BU0.js +0 -2
  99. package/node_modules/axios/dist/axios.js.map +0 -1
  100. package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
  101. package/node_modules/axios/dist/esm/axios.js.map +0 -1
  102. package/node_modules/axios/dist/node/axios.cjs.map +0 -1
@@ -1,9 +1,10 @@
1
- /*! Axios v1.16.0 Copyright (c) 2026 Matt Zabriskie and contributors */
1
+ /*! Axios v1.18.0 Copyright (c) 2026 Matt Zabriskie and contributors */
2
2
  'use strict';
3
3
 
4
4
  var FormData$1 = require('form-data');
5
5
  var crypto = require('crypto');
6
6
  var url = require('url');
7
+ var HttpsProxyAgent = require('https-proxy-agent');
7
8
  var http = require('http');
8
9
  var https = require('https');
9
10
  var http2 = require('http2');
@@ -39,6 +40,52 @@ const {
39
40
  iterator,
40
41
  toStringTag
41
42
  } = Symbol;
43
+
44
+ /* Creating a function that will check if an object has a property. */
45
+ const hasOwnProperty = (({
46
+ hasOwnProperty
47
+ }) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);
48
+
49
+ /**
50
+ * Walk the prototype chain (excluding the shared Object.prototype) looking for
51
+ * an own `prop`. This distinguishes genuine own/inherited members — including
52
+ * class accessors and template prototypes — from members injected via
53
+ * Object.prototype pollution (e.g. `Object.prototype.username = '...'`), which
54
+ * live on Object.prototype itself and are therefore never matched.
55
+ *
56
+ * @param {*} thing The value whose chain to inspect
57
+ * @param {string|symbol} prop The property key to look for
58
+ *
59
+ * @returns {boolean} True when `prop` is owned below Object.prototype
60
+ */
61
+ const hasOwnInPrototypeChain = (thing, prop) => {
62
+ let obj = thing;
63
+ const seen = [];
64
+ while (obj != null && obj !== Object.prototype) {
65
+ if (seen.indexOf(obj) !== -1) {
66
+ return false;
67
+ }
68
+ seen.push(obj);
69
+ if (hasOwnProperty(obj, prop)) {
70
+ return true;
71
+ }
72
+ obj = getPrototypeOf(obj);
73
+ }
74
+ return false;
75
+ };
76
+
77
+ /**
78
+ * Read `obj[prop]` only when it is safe from Object.prototype pollution. Own
79
+ * properties and members inherited from a non-Object.prototype source (a class
80
+ * instance or template object) are honored; a value reachable only through a
81
+ * polluted Object.prototype is ignored and `undefined` is returned.
82
+ *
83
+ * @param {*} obj The source object
84
+ * @param {string|symbol} prop The property key to read
85
+ *
86
+ * @returns {*} The resolved value, or undefined when unsafe/absent
87
+ */
88
+ const getSafeProp = (obj, prop) => obj != null && hasOwnInPrototypeChain(obj, prop) ? obj[prop] : undefined;
42
89
  const kindOf = (cache => thing => {
43
90
  const str = toString.call(thing);
44
91
  return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
@@ -157,11 +204,15 @@ const isBoolean = thing => thing === true || thing === false;
157
204
  * @returns {boolean} True if value is a plain Object, otherwise false
158
205
  */
159
206
  const isPlainObject = val => {
160
- if (kindOf(val) !== 'object') {
207
+ if (!isObject(val)) {
161
208
  return false;
162
209
  }
163
210
  const prototype = getPrototypeOf(val);
164
- return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);
211
+ return (prototype === null || prototype === Object.prototype || getPrototypeOf(prototype) === null) &&
212
+ // Treat any genuine (non-Object.prototype-polluted) Symbol.toStringTag or
213
+ // Symbol.iterator as evidence the value is a tagged/iterable type rather
214
+ // than a plain object, while ignoring keys injected onto Object.prototype.
215
+ !hasOwnInPrototypeChain(val, toStringTag) && !hasOwnInPrototypeChain(val, iterator);
165
216
  };
166
217
 
167
218
  /**
@@ -416,7 +467,10 @@ function merge(...objs) {
416
467
  if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
417
468
  return;
418
469
  }
419
- const targetKey = caseless && findKey(result, key) || key;
470
+
471
+ // findKey lowercases the key, so caseless lookup only applies to strings —
472
+ // symbol keys are identity-matched.
473
+ const targetKey = caseless && typeof key === 'string' && findKey(result, key) || key;
420
474
  // Read via own-prop only — a bare `result[targetKey]` walks the prototype
421
475
  // chain, so a polluted Object.prototype value could surface here and get
422
476
  // copied into the merged result.
@@ -432,7 +486,21 @@ function merge(...objs) {
432
486
  }
433
487
  };
434
488
  for (let i = 0, l = objs.length; i < l; i++) {
435
- objs[i] && forEach(objs[i], assignValue);
489
+ const source = objs[i];
490
+ if (!source || isBuffer(source)) {
491
+ continue;
492
+ }
493
+ forEach(source, assignValue);
494
+ if (typeof source !== 'object' || isArray(source)) {
495
+ continue;
496
+ }
497
+ const symbols = Object.getOwnPropertySymbols(source);
498
+ for (let j = 0; j < symbols.length; j++) {
499
+ const symbol = symbols[j];
500
+ if (propertyIsEnumerable.call(source, symbol)) {
501
+ assignValue(source[symbol], symbol);
502
+ }
503
+ }
436
504
  }
437
505
  return result;
438
506
  }
@@ -644,11 +712,9 @@ const toCamelCase = str => {
644
712
  return p1.toUpperCase() + p2;
645
713
  });
646
714
  };
647
-
648
- /* Creating a function that will check if an object has a property. */
649
- const hasOwnProperty = (({
650
- hasOwnProperty
651
- }) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);
715
+ const {
716
+ propertyIsEnumerable
717
+ } = Object.prototype;
652
718
 
653
719
  /**
654
720
  * Determine if a value is a RegExp object
@@ -737,10 +803,10 @@ function isSpecCompliantForm(thing) {
737
803
  * @returns {Object} The JSON-compatible object.
738
804
  */
739
805
  const toJSONObject = obj => {
740
- const stack = new Array(10);
741
- const visit = (source, i) => {
806
+ const visited = new WeakSet();
807
+ const visit = source => {
742
808
  if (isObject(source)) {
743
- if (stack.indexOf(source) >= 0) {
809
+ if (visited.has(source)) {
744
810
  return;
745
811
  }
746
812
 
@@ -749,19 +815,20 @@ const toJSONObject = obj => {
749
815
  return source;
750
816
  }
751
817
  if (!('toJSON' in source)) {
752
- stack[i] = source;
818
+ // add-on descent / delete-on-ascent: preserves path semantics, so DAG nodes serialise at every occurrence (see #7230).
819
+ visited.add(source);
753
820
  const target = isArray(source) ? [] : {};
754
821
  forEach(source, (value, key) => {
755
- const reducedValue = visit(value, i + 1);
822
+ const reducedValue = visit(value);
756
823
  !isUndefined(reducedValue) && (target[key] = reducedValue);
757
824
  });
758
- stack[i] = undefined;
825
+ visited.delete(source);
759
826
  return target;
760
827
  }
761
828
  }
762
829
  return source;
763
830
  };
764
- return visit(obj, 0);
831
+ return visit(obj);
765
832
  };
766
833
 
767
834
  /**
@@ -822,6 +889,19 @@ const asap = typeof queueMicrotask !== 'undefined' ? queueMicrotask.bind(_global
822
889
  // *********************
823
890
 
824
891
  const isIterable = thing => thing != null && isFunction$1(thing[iterator]);
892
+
893
+ /**
894
+ * Determine if a value is iterable via an iterator that is NOT sourced solely
895
+ * from a polluted Object.prototype. Use this instead of `isIterable` whenever
896
+ * the iterable comes from untrusted input (e.g. user-supplied header sources),
897
+ * so `Object.prototype[Symbol.iterator] = ...` cannot turn an ordinary object
898
+ * into an attacker-controlled entries iterator.
899
+ *
900
+ * @param {*} thing The value to test
901
+ *
902
+ * @returns {boolean} True if value has a non-polluted iterator
903
+ */
904
+ const isSafeIterable = thing => thing != null && hasOwnInPrototypeChain(thing, iterator) && isIterable(thing);
825
905
  var utils$1 = {
826
906
  isArray,
827
907
  isArrayBuffer,
@@ -867,6 +947,8 @@ var utils$1 = {
867
947
  hasOwnProperty,
868
948
  hasOwnProp: hasOwnProperty,
869
949
  // an alias to avoid ESLint no-prototype-builtins detection
950
+ hasOwnInPrototypeChain,
951
+ getSafeProp,
870
952
  reduceDescriptors,
871
953
  freezeMethods,
872
954
  toObjectSet,
@@ -882,7 +964,8 @@ var utils$1 = {
882
964
  isThenable,
883
965
  setImmediate: _setImmediate,
884
966
  asap,
885
- isIterable
967
+ isIterable,
968
+ isSafeIterable
886
969
  };
887
970
 
888
971
  // RawAxiosHeaders whose duplicates are ignored by node
@@ -928,8 +1011,6 @@ var parseHeaders = rawHeaders => {
928
1011
  return parsed;
929
1012
  };
930
1013
 
931
- const $internals = Symbol('internals');
932
- const INVALID_HEADER_VALUE_CHARS_RE = /[^\x09\x20-\x7E\x80-\xFF]/g;
933
1014
  function trimSPorHTAB(str) {
934
1015
  let start = 0;
935
1016
  let end = str.length;
@@ -949,12 +1030,32 @@ function trimSPorHTAB(str) {
949
1030
  }
950
1031
  return start === 0 && end === str.length ? str : str.slice(start, end);
951
1032
  }
1033
+
1034
+ // The control-code ranges are intentional: header sanitization strips C0/DEL bytes.
1035
+ // eslint-disable-next-line no-control-regex
1036
+ const INVALID_UNICODE_HEADER_VALUE_CHARS = new RegExp('[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+', 'g');
1037
+ // eslint-disable-next-line no-control-regex
1038
+ const INVALID_BYTE_STRING_HEADER_VALUE_CHARS = new RegExp('[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+', 'g');
1039
+ function sanitizeValue(value, invalidChars) {
1040
+ if (utils$1.isArray(value)) {
1041
+ return value.map(item => sanitizeValue(item, invalidChars));
1042
+ }
1043
+ return trimSPorHTAB(String(value).replace(invalidChars, ''));
1044
+ }
1045
+ const sanitizeHeaderValue = value => sanitizeValue(value, INVALID_UNICODE_HEADER_VALUE_CHARS);
1046
+ const sanitizeByteStringHeaderValue = value => sanitizeValue(value, INVALID_BYTE_STRING_HEADER_VALUE_CHARS);
1047
+ function toByteStringHeaderObject(headers) {
1048
+ const byteStringHeaders = Object.create(null);
1049
+ utils$1.forEach(headers.toJSON(), (value, header) => {
1050
+ byteStringHeaders[header] = sanitizeByteStringHeaderValue(value);
1051
+ });
1052
+ return byteStringHeaders;
1053
+ }
1054
+
1055
+ const $internals = Symbol('internals');
952
1056
  function normalizeHeader(header) {
953
1057
  return header && String(header).trim().toLowerCase();
954
1058
  }
955
- function sanitizeHeaderValue(str) {
956
- return trimSPorHTAB(str.replace(INVALID_HEADER_VALUE_CHARS_RE, ''));
957
- }
958
1059
  function normalizeValue(value) {
959
1060
  if (value === false || value == null) {
960
1061
  return value;
@@ -1014,7 +1115,7 @@ class AxiosHeaders {
1014
1115
  function setHeader(_value, _header, _rewrite) {
1015
1116
  const lHeader = normalizeHeader(_header);
1016
1117
  if (!lHeader) {
1017
- throw new Error('header name must be a non-empty string');
1118
+ return;
1018
1119
  }
1019
1120
  const key = utils$1.findKey(self, lHeader);
1020
1121
  if (!key || self[key] === undefined || _rewrite === true || _rewrite === undefined && self[key] !== false) {
@@ -1026,15 +1127,21 @@ class AxiosHeaders {
1026
1127
  setHeaders(header, valueOrRewrite);
1027
1128
  } else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
1028
1129
  setHeaders(parseHeaders(header), valueOrRewrite);
1029
- } else if (utils$1.isObject(header) && utils$1.isIterable(header)) {
1030
- let obj = {},
1130
+ } else if (utils$1.isObject(header) && utils$1.isSafeIterable(header)) {
1131
+ let obj = Object.create(null),
1031
1132
  dest,
1032
1133
  key;
1033
1134
  for (const entry of header) {
1034
1135
  if (!utils$1.isArray(entry)) {
1035
- throw TypeError('Object iterator must return a key-value pair');
1136
+ throw new TypeError('Object iterator must return a key-value pair');
1137
+ }
1138
+ key = entry[0];
1139
+ if (utils$1.hasOwnProp(obj, key)) {
1140
+ dest = obj[key];
1141
+ obj[key] = utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]];
1142
+ } else {
1143
+ obj[key] = entry[1];
1036
1144
  }
1037
- obj[key = entry[0]] = (dest = obj[key]) ? utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]] : entry[1];
1038
1145
  }
1039
1146
  setHeaders(obj, valueOrRewrite);
1040
1147
  } else {
@@ -1337,6 +1444,10 @@ AxiosError.ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT';
1337
1444
  AxiosError.ERR_INVALID_URL = 'ERR_INVALID_URL';
1338
1445
  AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED';
1339
1446
 
1447
+ // Default nesting limit shared with the inverse transform (formDataToJSON) so
1448
+ // the FormData <-> JSON round-trip stays symmetric.
1449
+ const DEFAULT_FORM_DATA_MAX_DEPTH = 100;
1450
+
1340
1451
  /**
1341
1452
  * Determines if the given thing is a array or js object.
1342
1453
  *
@@ -1437,8 +1548,9 @@ function toFormData(obj, formData, options) {
1437
1548
  const dots = options.dots;
1438
1549
  const indexes = options.indexes;
1439
1550
  const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;
1440
- const maxDepth = options.maxDepth === undefined ? 100 : options.maxDepth;
1551
+ const maxDepth = options.maxDepth === undefined ? DEFAULT_FORM_DATA_MAX_DEPTH : options.maxDepth;
1441
1552
  const useBlob = _Blob && utils$1.isSpecCompliantForm(formData);
1553
+ const stack = [];
1442
1554
  if (!utils$1.isFunction(visitor)) {
1443
1555
  throw new TypeError('visitor must be a function');
1444
1556
  }
@@ -1458,6 +1570,28 @@ function toFormData(obj, formData, options) {
1458
1570
  }
1459
1571
  return value;
1460
1572
  }
1573
+ function throwIfMaxDepthExceeded(depth) {
1574
+ if (depth > maxDepth) {
1575
+ throw new AxiosError('Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
1576
+ }
1577
+ }
1578
+ function stringifyWithDepthLimit(value, depth) {
1579
+ if (maxDepth === Infinity) {
1580
+ return JSON.stringify(value);
1581
+ }
1582
+ const ancestors = [];
1583
+ return JSON.stringify(value, function limitDepth(_key, currentValue) {
1584
+ if (!utils$1.isObject(currentValue)) {
1585
+ return currentValue;
1586
+ }
1587
+ while (ancestors.length && ancestors[ancestors.length - 1] !== this) {
1588
+ ancestors.pop();
1589
+ }
1590
+ ancestors.push(currentValue);
1591
+ throwIfMaxDepthExceeded(depth + ancestors.length - 1);
1592
+ return currentValue;
1593
+ });
1594
+ }
1461
1595
 
1462
1596
  /**
1463
1597
  * Default visitor.
@@ -1480,7 +1614,7 @@ function toFormData(obj, formData, options) {
1480
1614
  // eslint-disable-next-line no-param-reassign
1481
1615
  key = metaTokens ? key : key.slice(0, -2);
1482
1616
  // eslint-disable-next-line no-param-reassign
1483
- value = JSON.stringify(value);
1617
+ value = stringifyWithDepthLimit(value, 1);
1484
1618
  } else if (utils$1.isArray(value) && isFlatArray(value) || (utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value))) {
1485
1619
  // eslint-disable-next-line no-param-reassign
1486
1620
  key = removeBrackets(key);
@@ -1498,7 +1632,6 @@ function toFormData(obj, formData, options) {
1498
1632
  formData.append(renderKey(path, key, dots), convertValue(value));
1499
1633
  return false;
1500
1634
  }
1501
- const stack = [];
1502
1635
  const exposedHelpers = Object.assign(predicates, {
1503
1636
  defaultVisitor,
1504
1637
  convertValue,
@@ -1506,11 +1639,9 @@ function toFormData(obj, formData, options) {
1506
1639
  });
1507
1640
  function build(value, path, depth = 0) {
1508
1641
  if (utils$1.isUndefined(value)) return;
1509
- if (depth > maxDepth) {
1510
- throw new AxiosError('Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
1511
- }
1642
+ throwIfMaxDepthExceeded(depth);
1512
1643
  if (stack.indexOf(value) !== -1) {
1513
- throw Error('Circular reference detected in ' + path.join('.'));
1644
+ throw new Error('Circular reference detected in ' + path.join('.'));
1514
1645
  }
1515
1646
  stack.push(value);
1516
1647
  utils$1.forEach(value, function each(el, key) {
@@ -1600,11 +1731,15 @@ function buildURL(url, params, options) {
1600
1731
  if (!params) {
1601
1732
  return url;
1602
1733
  }
1603
- const _encode = options && options.encode || encode;
1604
1734
  const _options = utils$1.isFunction(options) ? {
1605
1735
  serialize: options
1606
1736
  } : options;
1607
- const serializeFn = _options && _options.serialize;
1737
+
1738
+ // Read serializer options pollution-safely: own properties and methods on a
1739
+ // class/template prototype are honored, but values injected onto a polluted
1740
+ // Object.prototype are ignored.
1741
+ const _encode = utils$1.getSafeProp(_options, 'encode') || encode;
1742
+ const serializeFn = utils$1.getSafeProp(_options, 'serialize');
1608
1743
  let serializedParams;
1609
1744
  if (serializeFn) {
1610
1745
  serializedParams = serializeFn(params, _options);
@@ -1692,7 +1827,9 @@ var transitionalDefaults = {
1692
1827
  silentJSONParsing: true,
1693
1828
  forcedJSONParsing: true,
1694
1829
  clarifyTimeoutError: false,
1695
- legacyInterceptorReqResOrdering: true
1830
+ legacyInterceptorReqResOrdering: true,
1831
+ advertiseZstdAcceptEncoding: false,
1832
+ validateStatusUndefinedResolves: true
1696
1833
  };
1697
1834
 
1698
1835
  var URLSearchParams = url.URLSearchParams;
@@ -1793,6 +1930,13 @@ function toURLEncodedForm(data, options) {
1793
1930
  });
1794
1931
  }
1795
1932
 
1933
+ const MAX_DEPTH = DEFAULT_FORM_DATA_MAX_DEPTH;
1934
+ function throwIfDepthExceeded(index) {
1935
+ if (index > MAX_DEPTH) {
1936
+ throw new AxiosError('FormData field is too deeply nested (' + index + ' levels). Max depth: ' + MAX_DEPTH, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
1937
+ }
1938
+ }
1939
+
1796
1940
  /**
1797
1941
  * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']
1798
1942
  *
@@ -1805,9 +1949,14 @@ function parsePropPath(name) {
1805
1949
  // foo.x.y.z
1806
1950
  // foo-x-y-z
1807
1951
  // foo x y z
1808
- return utils$1.matchAll(/\w+|\[(\w*)]/g, name).map(match => {
1809
- return match[0] === '[]' ? '' : match[1] || match[0];
1810
- });
1952
+ const path = [];
1953
+ const pattern = /\w+|\[(\w*)]/g;
1954
+ let match;
1955
+ while ((match = pattern.exec(name)) !== null) {
1956
+ throwIfDepthExceeded(path.length);
1957
+ path.push(match[0] === '[]' ? '' : match[1] || match[0]);
1958
+ }
1959
+ return path;
1811
1960
  }
1812
1961
 
1813
1962
  /**
@@ -1839,6 +1988,7 @@ function arrayToObject(arr) {
1839
1988
  */
1840
1989
  function formDataToJSON(formData) {
1841
1990
  function buildPath(path, value, target, index) {
1991
+ throwIfDepthExceeded(index);
1842
1992
  let name = path[index++];
1843
1993
  if (name === '__proto__') return true;
1844
1994
  const isNumericKey = Number.isFinite(+name);
@@ -1852,7 +2002,7 @@ function formDataToJSON(formData) {
1852
2002
  }
1853
2003
  return !isNumericKey;
1854
2004
  }
1855
- if (!target[name] || !utils$1.isObject(target[name])) {
2005
+ if (!utils$1.hasOwnProp(target, name) || !utils$1.isObject(target[name])) {
1856
2006
  target[name] = [];
1857
2007
  }
1858
2008
  const result = buildPath(path, value, target[name], index);
@@ -2079,6 +2229,24 @@ function combineURLs(baseURL, relativeURL) {
2079
2229
  return relativeURL ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;
2080
2230
  }
2081
2231
 
2232
+ const malformedHttpProtocol = /^https?:(?!\/\/)/i;
2233
+ const httpProtocolControlCharacters = /[\t\n\r]/g;
2234
+ function stripLeadingC0ControlOrSpace(url) {
2235
+ let i = 0;
2236
+ while (i < url.length && url.charCodeAt(i) <= 0x20) {
2237
+ i++;
2238
+ }
2239
+ return url.slice(i);
2240
+ }
2241
+ function normalizeURLForProtocolCheck(url) {
2242
+ return stripLeadingC0ControlOrSpace(url).replace(httpProtocolControlCharacters, '');
2243
+ }
2244
+ function assertValidHttpProtocolURL(url, config) {
2245
+ if (typeof url === 'string' && malformedHttpProtocol.test(normalizeURLForProtocolCheck(url))) {
2246
+ throw new AxiosError('Invalid URL: missing "//" after protocol', AxiosError.ERR_INVALID_URL, config);
2247
+ }
2248
+ }
2249
+
2082
2250
  /**
2083
2251
  * Creates a new URL by combining the baseURL with the requestedURL,
2084
2252
  * only when the requestedURL is not already an absolute URL.
@@ -2089,9 +2257,11 @@ function combineURLs(baseURL, relativeURL) {
2089
2257
  *
2090
2258
  * @returns {string} The combined full path
2091
2259
  */
2092
- function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
2260
+ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls, config) {
2261
+ assertValidHttpProtocolURL(requestedURL, config);
2093
2262
  let isRelativeUrl = !isAbsoluteURL(requestedURL);
2094
2263
  if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) {
2264
+ assertValidHttpProtocolURL(baseURL, config);
2095
2265
  return combineURLs(baseURL, requestedURL);
2096
2266
  }
2097
2267
  return requestedURL;
@@ -2193,14 +2363,16 @@ function getEnv(key) {
2193
2363
  return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
2194
2364
  }
2195
2365
 
2196
- const VERSION = "1.16.0";
2366
+ const VERSION = "1.18.0";
2197
2367
 
2198
2368
  function parseProtocol(url) {
2199
2369
  const match = /^([-+\w]{1,25}):(?:\/\/)?/.exec(url);
2200
2370
  return match && match[1] || '';
2201
2371
  }
2202
2372
 
2203
- const DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;
2373
+ // RFC 2397: data:[<mediatype>][;base64],<data>
2374
+ // mediatype = type/subtype followed by optional ;name=value parameters
2375
+ const DATA_URL_PATTERN = /^([^,;]+\/[^,;]+)?((?:;[^,;=]+=[^,;]+)*)(;base64)?,([\s\S]*)$/;
2204
2376
 
2205
2377
  /**
2206
2378
  * Parse data uri to a Buffer or Blob
@@ -2224,10 +2396,20 @@ function fromDataURI(uri, asBlob, options) {
2224
2396
  if (!match) {
2225
2397
  throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL);
2226
2398
  }
2227
- const mime = match[1];
2228
- const isBase64 = match[2];
2229
- const body = match[3];
2230
- const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8');
2399
+ const type = match[1];
2400
+ const params = match[2];
2401
+ const encoding = match[3] ? 'base64' : 'utf8';
2402
+ const body = match[4];
2403
+
2404
+ // RFC 2397 section 3: default mediatype is text/plain;charset=US-ASCII
2405
+ // Bare `data:,` leaves mime undefined; Blob normalises that to "" per spec.
2406
+ let mime;
2407
+ if (type) {
2408
+ mime = params ? type + params : type;
2409
+ } else if (params) {
2410
+ mime = 'text/plain' + params;
2411
+ }
2412
+ const buffer = Buffer.from(decodeURIComponent(body), encoding);
2231
2413
  if (asBlob) {
2232
2414
  if (!_Blob) {
2233
2415
  throw new AxiosError('Blob is not supported', AxiosError.ERR_NOT_SUPPORT);
@@ -2420,10 +2602,10 @@ const formDataToStream = (form, headersHandler, options) => {
2420
2602
  boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET)
2421
2603
  } = options || {};
2422
2604
  if (!utils$1.isFormData(form)) {
2423
- throw TypeError('FormData instance required');
2605
+ throw new TypeError('FormData instance required');
2424
2606
  }
2425
2607
  if (boundary.length < 1 || boundary.length > 70) {
2426
- throw Error('boundary must be 1-70 characters long');
2608
+ throw new Error('boundary must be 1-70 characters long');
2427
2609
  }
2428
2610
  const boundaryBytes = textEncoder.encode('--' + boundary + CRLF);
2429
2611
  const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF);
@@ -2473,6 +2655,84 @@ class ZlibHeaderTransformStream extends stream.Transform {
2473
2655
  }
2474
2656
  }
2475
2657
 
2658
+ class Http2Sessions {
2659
+ constructor() {
2660
+ this.sessions = Object.create(null);
2661
+ }
2662
+ getSession(authority, options) {
2663
+ options = Object.assign({
2664
+ sessionTimeout: 1000
2665
+ }, options);
2666
+ let authoritySessions = this.sessions[authority];
2667
+ if (authoritySessions) {
2668
+ let len = authoritySessions.length;
2669
+ for (let i = 0; i < len; i++) {
2670
+ const [sessionHandle, sessionOptions] = authoritySessions[i];
2671
+ if (!sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options)) {
2672
+ return sessionHandle;
2673
+ }
2674
+ }
2675
+ }
2676
+ const session = http2.connect(authority, options);
2677
+ let removed;
2678
+ let timer;
2679
+ const removeSession = () => {
2680
+ if (removed) {
2681
+ return;
2682
+ }
2683
+ removed = true;
2684
+ if (timer) {
2685
+ clearTimeout(timer);
2686
+ timer = null;
2687
+ }
2688
+ let entries = authoritySessions,
2689
+ len = entries.length,
2690
+ i = len;
2691
+ while (i--) {
2692
+ if (entries[i][0] === session) {
2693
+ if (len === 1) {
2694
+ delete this.sessions[authority];
2695
+ } else {
2696
+ entries.splice(i, 1);
2697
+ }
2698
+ if (!session.closed) {
2699
+ session.close();
2700
+ }
2701
+ return;
2702
+ }
2703
+ }
2704
+ };
2705
+ const originalRequestFn = session.request;
2706
+ const {
2707
+ sessionTimeout
2708
+ } = options;
2709
+ if (sessionTimeout != null) {
2710
+ let streamsCount = 0;
2711
+ session.request = function () {
2712
+ const stream = originalRequestFn.apply(this, arguments);
2713
+ streamsCount++;
2714
+ if (timer) {
2715
+ clearTimeout(timer);
2716
+ timer = null;
2717
+ }
2718
+ stream.once('close', () => {
2719
+ if (! --streamsCount) {
2720
+ timer = setTimeout(() => {
2721
+ timer = null;
2722
+ removeSession();
2723
+ }, sessionTimeout);
2724
+ }
2725
+ });
2726
+ return stream;
2727
+ };
2728
+ }
2729
+ session.once('close', removeSession);
2730
+ let entry = [session, options];
2731
+ authoritySessions ? authoritySessions.push(entry) : authoritySessions = this.sessions[authority] = [entry];
2732
+ return session;
2733
+ }
2734
+ }
2735
+
2476
2736
  const callbackify = (fn, reducer) => {
2477
2737
  return utils$1.isAsyncFn(fn) ? function (...args) {
2478
2738
  const cb = args.pop();
@@ -2486,13 +2746,34 @@ const callbackify = (fn, reducer) => {
2486
2746
  } : fn;
2487
2747
  };
2488
2748
 
2489
- const LOOPBACK_HOSTNAMES = new Set(['localhost']);
2749
+ const LOOPBACK_HOSTNAMES = new Set(['localhost', '0.0.0.0']);
2490
2750
  const isIPv4Loopback = host => {
2491
2751
  const parts = host.split('.');
2492
2752
  if (parts.length !== 4) return false;
2493
2753
  if (parts[0] !== '127') return false;
2494
2754
  return parts.every(p => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
2495
2755
  };
2756
+ const isIPv6ZeroGroup = group => /^0{1,4}$/.test(group);
2757
+
2758
+ // The unspecified address (IPv4 0.0.0.0 / IPv6 ::) resolves to the local host
2759
+ // for outbound connections, so treat it as loopback-equivalent for NO_PROXY
2760
+ // matching. 0.0.0.0 is covered by LOOPBACK_HOSTNAMES; this handles compressed
2761
+ // and full IPv6 all-zero forms so both families bypass symmetrically.
2762
+ const isIPv6Unspecified = host => {
2763
+ if (host === '::') return true;
2764
+ const compressionIndex = host.indexOf('::');
2765
+ if (compressionIndex !== -1) {
2766
+ if (compressionIndex !== host.lastIndexOf('::')) return false;
2767
+ const left = host.slice(0, compressionIndex);
2768
+ const right = host.slice(compressionIndex + 2);
2769
+ const leftGroups = left ? left.split(':') : [];
2770
+ const rightGroups = right ? right.split(':') : [];
2771
+ const explicitGroups = leftGroups.length + rightGroups.length;
2772
+ return explicitGroups < 8 && leftGroups.every(isIPv6ZeroGroup) && rightGroups.every(isIPv6ZeroGroup);
2773
+ }
2774
+ const groups = host.split(':');
2775
+ return groups.length === 8 && groups.every(isIPv6ZeroGroup);
2776
+ };
2496
2777
  const isIPv6Loopback = host => {
2497
2778
  // Collapse all-zero groups: any form of ::1 / 0:0:...:0:1
2498
2779
  // First, strip any leading "::" by normalising with Set lookup of common forms,
@@ -2525,6 +2806,7 @@ const isLoopback = host => {
2525
2806
  if (!host) return false;
2526
2807
  if (LOOPBACK_HOSTNAMES.has(host)) return true;
2527
2808
  if (isIPv4Loopback(host)) return true;
2809
+ if (isIPv6Unspecified(host)) return true;
2528
2810
  return isIPv6Loopback(host);
2529
2811
  };
2530
2812
  const DEFAULT_PORTS = {
@@ -2707,6 +2989,9 @@ const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
2707
2989
  let bytesNotified = 0;
2708
2990
  const _speedometer = speedometer(50, 250);
2709
2991
  return throttle(e => {
2992
+ if (!e || typeof e.loaded !== 'number') {
2993
+ return;
2994
+ }
2710
2995
  const rawLoaded = e.loaded;
2711
2996
  const total = e.lengthComputable ? e.total : undefined;
2712
2997
  const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;
@@ -2741,11 +3026,13 @@ const asyncDecorator = fn => (...args) => utils$1.asap(() => fn(...args));
2741
3026
  * Estimate decoded byte length of a data:// URL *without* allocating large buffers.
2742
3027
  * - For base64: compute exact decoded size using length and padding;
2743
3028
  * handle %XX at the character-count level (no string allocation).
2744
- * - For non-base64: use UTF-8 byteLength of the encoded body as a safe upper bound.
3029
+ * - For non-base64: compute the exact percent-decoded UTF-8 byte length.
2745
3030
  *
2746
3031
  * @param {string} url
2747
3032
  * @returns {number}
2748
3033
  */
3034
+ const isHexDigit = charCode => charCode >= 48 && charCode <= 57 || charCode >= 65 && charCode <= 70 || charCode >= 97 && charCode <= 102;
3035
+ const isPercentEncodedByte = (str, i, len) => i + 2 < len && isHexDigit(str.charCodeAt(i + 1)) && isHexDigit(str.charCodeAt(i + 2));
2749
3036
  function estimateDataURLDecodedBytes(url) {
2750
3037
  if (!url || typeof url !== 'string') return 0;
2751
3038
  if (!url.startsWith('data:')) return 0;
@@ -2762,7 +3049,7 @@ function estimateDataURLDecodedBytes(url) {
2762
3049
  if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {
2763
3050
  const a = body.charCodeAt(i + 1);
2764
3051
  const b = body.charCodeAt(i + 2);
2765
- const isHex = (a >= 48 && a <= 57 || a >= 65 && a <= 70 || a >= 97 && a <= 102) && (b >= 48 && b <= 57 || b >= 65 && b <= 70 || b >= 97 && b <= 102);
3052
+ const isHex = isHexDigit(a) && isHexDigit(b);
2766
3053
  if (isHex) {
2767
3054
  effectiveLen -= 2;
2768
3055
  i += 2;
@@ -2797,18 +3084,18 @@ function estimateDataURLDecodedBytes(url) {
2797
3084
  const bytes = groups * 3 - (pad || 0);
2798
3085
  return bytes > 0 ? bytes : 0;
2799
3086
  }
2800
- if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') {
2801
- return Buffer.byteLength(body, 'utf8');
2802
- }
2803
3087
 
2804
3088
  // Compute UTF-8 byte length directly from UTF-16 code units without allocating
2805
3089
  // a byte buffer (TextEncoder.encode would defeat the DoS guard on large bodies).
2806
- // Using body.length here would undercount non-ASCII (e.g. '€' is 1 code unit
2807
- // but 3 UTF-8 bytes).
3090
+ // Valid %XX triplets count as one decoded byte; this matches the bytes that
3091
+ // decodeURIComponent(body) would produce before Buffer re-encodes the string.
2808
3092
  let bytes = 0;
2809
3093
  for (let i = 0, len = body.length; i < len; i++) {
2810
3094
  const c = body.charCodeAt(i);
2811
- if (c < 0x80) {
3095
+ if (c === 37 /* '%' */ && isPercentEncodedByte(body, i, len)) {
3096
+ bytes += 1;
3097
+ i += 2;
3098
+ } else if (c < 0x80) {
2812
3099
  bytes += 1;
2813
3100
  } else if (c < 0x800) {
2814
3101
  bytes += 2;
@@ -2835,7 +3122,14 @@ const brotliOptions = {
2835
3122
  flush: zlib.constants.BROTLI_OPERATION_FLUSH,
2836
3123
  finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
2837
3124
  };
3125
+ const zstdOptions = {
3126
+ flush: zlib.constants.ZSTD_e_flush,
3127
+ finishFlush: zlib.constants.ZSTD_e_flush
3128
+ };
2838
3129
  const isBrotliSupported = utils$1.isFunction(zlib.createBrotliDecompress);
3130
+ const isZstdSupported = utils$1.isFunction(zlib.createZstdDecompress);
3131
+ const ACCEPT_ENCODING = 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : '');
3132
+ const ACCEPT_ENCODING_WITH_ZSTD = ACCEPT_ENCODING + (isZstdSupported ? ', zstd' : '');
2839
3133
  const {
2840
3134
  http: httpFollow,
2841
3135
  https: httpsFollow
@@ -2858,6 +3152,48 @@ function setFormDataHeaders$1(headers, formHeaders, policy) {
2858
3152
  // the request currently owning that socket across keep-alive reuse (issue #10780).
2859
3153
  const kAxiosSocketListener = Symbol('axios.http.socketListener');
2860
3154
  const kAxiosCurrentReq = Symbol('axios.http.currentReq');
3155
+
3156
+ // Tags HttpsProxyAgent instances installed by setProxy() so the redirect path
3157
+ // can strip them without clobbering a user-supplied agent that happens to be
3158
+ // an HttpsProxyAgent.
3159
+ const kAxiosInstalledTunnel = Symbol('axios.http.installedTunnel');
3160
+
3161
+ // Cache of CONNECT-tunneling agents keyed by proxy config so repeat requests
3162
+ // through the same proxy reuse a single agent (and its socket pool). The
3163
+ // keyspace is bounded by the set of distinct proxy configs the process uses,
3164
+ // so unbounded growth is not a concern in practice.
3165
+ const tunnelingAgentCache = new Map();
3166
+ const tunnelingAgentCacheUser = new WeakMap();
3167
+ function getTunnelingAgent(agentOptions, userHttpsAgent) {
3168
+ const key = agentOptions.protocol + '//' + agentOptions.hostname + ':' + (agentOptions.port || '') + '#' + (agentOptions.auth || '');
3169
+ const cache = userHttpsAgent ? tunnelingAgentCacheUser.get(userHttpsAgent) || tunnelingAgentCacheUser.set(userHttpsAgent, new Map()).get(userHttpsAgent) : tunnelingAgentCache;
3170
+ let agent = cache.get(key);
3171
+ if (agent) return agent;
3172
+ // Forward the user's TLS options (custom CA, rejectUnauthorized, client cert,
3173
+ // etc.) into the tunneling agent so they apply to the origin TLS upgrade
3174
+ // performed after CONNECT. Our proxy fields take precedence on conflict.
3175
+ const merged = userHttpsAgent && userHttpsAgent.options ? {
3176
+ ...userHttpsAgent.options,
3177
+ ...agentOptions
3178
+ } : agentOptions;
3179
+ agent = new HttpsProxyAgent(merged);
3180
+ if (userHttpsAgent && userHttpsAgent.options) {
3181
+ const originTLSOptions = {
3182
+ ...userHttpsAgent.options
3183
+ };
3184
+ const callback = agent.callback;
3185
+ agent.callback = function axiosTunnelingAgentCallback(req, opts) {
3186
+ // HttpsProxyAgent v5 reads callback opts for the post-CONNECT origin TLS upgrade.
3187
+ return callback.call(this, req, {
3188
+ ...originTLSOptions,
3189
+ ...opts
3190
+ });
3191
+ };
3192
+ }
3193
+ agent[kAxiosInstalledTunnel] = true;
3194
+ cache.set(key, agent);
3195
+ return agent;
3196
+ }
2861
3197
  const supportedProtocols = platform.protocols.map(protocol => {
2862
3198
  return protocol + ':';
2863
3199
  });
@@ -2866,7 +3202,7 @@ const supportedProtocols = platform.protocols.map(protocol => {
2866
3202
  // Decode before composing the `auth` option so credentials such as
2867
3203
  // `my%40email.com:pass` are sent as `my@email.com:pass`. Falls back to the
2868
3204
  // original value for malformed input so a bad encoding never throws.
2869
- const decodeURIComponentSafe = value => {
3205
+ const decodeURIComponentSafe$1 = value => {
2870
3206
  if (!utils$1.isString(value)) {
2871
3207
  return value;
2872
3208
  }
@@ -2880,84 +3216,11 @@ const flushOnFinish = (stream, [throttled, flush]) => {
2880
3216
  stream.on('end', flush).on('error', flush);
2881
3217
  return throttled;
2882
3218
  };
2883
- class Http2Sessions {
2884
- constructor() {
2885
- this.sessions = Object.create(null);
2886
- }
2887
- getSession(authority, options) {
2888
- options = Object.assign({
2889
- sessionTimeout: 1000
2890
- }, options);
2891
- let authoritySessions = this.sessions[authority];
2892
- if (authoritySessions) {
2893
- let len = authoritySessions.length;
2894
- for (let i = 0; i < len; i++) {
2895
- const [sessionHandle, sessionOptions] = authoritySessions[i];
2896
- if (!sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options)) {
2897
- return sessionHandle;
2898
- }
2899
- }
2900
- }
2901
- const session = http2.connect(authority, options);
2902
- let removed;
2903
- const removeSession = () => {
2904
- if (removed) {
2905
- return;
2906
- }
2907
- removed = true;
2908
- let entries = authoritySessions,
2909
- len = entries.length,
2910
- i = len;
2911
- while (i--) {
2912
- if (entries[i][0] === session) {
2913
- if (len === 1) {
2914
- delete this.sessions[authority];
2915
- } else {
2916
- entries.splice(i, 1);
2917
- }
2918
- if (!session.closed) {
2919
- session.close();
2920
- }
2921
- return;
2922
- }
2923
- }
2924
- };
2925
- const originalRequestFn = session.request;
2926
- const {
2927
- sessionTimeout
2928
- } = options;
2929
- if (sessionTimeout != null) {
2930
- let timer;
2931
- let streamsCount = 0;
2932
- session.request = function () {
2933
- const stream = originalRequestFn.apply(this, arguments);
2934
- streamsCount++;
2935
- if (timer) {
2936
- clearTimeout(timer);
2937
- timer = null;
2938
- }
2939
- stream.once('close', () => {
2940
- if (! --streamsCount) {
2941
- timer = setTimeout(() => {
2942
- timer = null;
2943
- removeSession();
2944
- }, sessionTimeout);
2945
- }
2946
- });
2947
- return stream;
2948
- };
2949
- }
2950
- session.once('close', removeSession);
2951
- let entry = [session, options];
2952
- authoritySessions ? authoritySessions.push(entry) : authoritySessions = this.sessions[authority] = [entry];
2953
- return session;
2954
- }
2955
- }
2956
3219
  const http2Sessions = new Http2Sessions();
2957
3220
 
2958
3221
  /**
2959
- * If the proxy or config beforeRedirects functions are defined, call them with the options
2960
- * object.
3222
+ * If the proxy, auth, sensitive header, or config beforeRedirects functions are defined,
3223
+ * call them with the options object.
2961
3224
  *
2962
3225
  * @param {Object<string, any>} options - The options object that was passed to the request.
2963
3226
  *
@@ -2967,10 +3230,37 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
2967
3230
  if (options.beforeRedirects.proxy) {
2968
3231
  options.beforeRedirects.proxy(options);
2969
3232
  }
3233
+ if (options.beforeRedirects.auth) {
3234
+ options.beforeRedirects.auth(options);
3235
+ }
3236
+ if (options.beforeRedirects.sensitiveHeaders) {
3237
+ options.beforeRedirects.sensitiveHeaders(options, requestDetails);
3238
+ }
2970
3239
  if (options.beforeRedirects.config) {
2971
3240
  options.beforeRedirects.config(options, responseDetails, requestDetails);
2972
3241
  }
2973
3242
  }
3243
+ function stripMatchingHeaders(headers, sensitiveSet) {
3244
+ if (!headers) {
3245
+ return;
3246
+ }
3247
+ Object.keys(headers).forEach(header => {
3248
+ if (sensitiveSet.has(header.toLowerCase())) {
3249
+ delete headers[header];
3250
+ }
3251
+ });
3252
+ }
3253
+ function isSameOriginRedirect(redirectOptions, requestDetails) {
3254
+ if (!requestDetails) {
3255
+ return false;
3256
+ }
3257
+ try {
3258
+ return new URL(requestDetails.url).origin === new URL(redirectOptions.href).origin;
3259
+ } catch (e) {
3260
+ // If origin comparison fails, treat the redirect as unsafe.
3261
+ return false;
3262
+ }
3263
+ }
2974
3264
 
2975
3265
  /**
2976
3266
  * If the proxy or config afterRedirects functions are defined, call them with the options
@@ -2981,7 +3271,7 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
2981
3271
  *
2982
3272
  * @returns {http.ClientRequestArgs}
2983
3273
  */
2984
- function setProxy(options, configProxy, location, isRedirect) {
3274
+ function setProxy(options, configProxy, location, isRedirect, configHttpsAgent) {
2985
3275
  let proxy = configProxy;
2986
3276
  if (!proxy && proxy !== false) {
2987
3277
  const proxyUrl = getProxyForUrl(location);
@@ -3002,6 +3292,13 @@ function setProxy(options, configProxy, location, isRedirect) {
3002
3292
  }
3003
3293
  }
3004
3294
  }
3295
+ // Strip any tunneling agent we installed for the previous hop so a redirect
3296
+ // that drops the proxy or crosses an HTTPS↔HTTP boundary doesn't reuse a
3297
+ // stale one. Match on our Symbol marker so a user-supplied HttpsProxyAgent
3298
+ // (which won't carry the marker) is left alone.
3299
+ if (isRedirect && options.agent && options.agent[kAxiosInstalledTunnel]) {
3300
+ options.agent = undefined;
3301
+ }
3005
3302
  if (proxy) {
3006
3303
  // Read proxy fields without traversing the prototype chain. URL instances expose
3007
3304
  // username/password/hostname/host/port/protocol via getters on URL.prototype (so
@@ -3034,37 +3331,84 @@ function setProxy(options, configProxy, location, isRedirect) {
3034
3331
  proxy
3035
3332
  });
3036
3333
  }
3037
- const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64');
3038
- options.headers['Proxy-Authorization'] = 'Basic ' + base64;
3039
3334
  }
3335
+ const targetIsHttps = isHttps.test(options.protocol);
3336
+ if (targetIsHttps) {
3337
+ // CONNECT-tunneling path for HTTPS targets. Preserves end-to-end TLS to
3338
+ // the origin so the proxy cannot inspect the URL, headers, or body — the
3339
+ // behavior already promised by THREATMODEL.md (T-R9). HttpsProxyAgent
3340
+ // sends Proxy-Authorization on the CONNECT request only, never on the
3341
+ // wrapped TLS request, which is why we don't stamp it onto
3342
+ // options.headers here. If the user already supplied an HttpsProxyAgent,
3343
+ // they own tunneling end-to-end and we leave them alone; otherwise we
3344
+ // install our own tunneling agent and forward their TLS options (if any)
3345
+ // so a custom httpsAgent for cert pinning / rejectUnauthorized still
3346
+ // applies to the origin TLS upgrade.
3347
+ if (!(configHttpsAgent instanceof HttpsProxyAgent)) {
3348
+ const proxyHost = readProxyField('hostname') || readProxyField('host');
3349
+ const proxyPort = readProxyField('port');
3350
+ const rawProxyProtocol = readProxyField('protocol');
3351
+ const normalizedProtocol = rawProxyProtocol ? rawProxyProtocol.includes(':') ? rawProxyProtocol : `${rawProxyProtocol}:` : 'http:';
3352
+ // Bracket IPv6 literals for URL parsing; URL.hostname strips the
3353
+ // brackets again on read so the agent receives the raw form.
3354
+ const proxyHostForURL = proxyHost && proxyHost.includes(':') && !proxyHost.startsWith('[') ? `[${proxyHost}]` : proxyHost;
3355
+ const proxyURL = new URL(`${normalizedProtocol}//${proxyHostForURL}${proxyPort ? ':' + proxyPort : ''}`);
3356
+ const agentOptions = {
3357
+ protocol: proxyURL.protocol,
3358
+ hostname: proxyURL.hostname.replace(/^\[|\]$/g, ''),
3359
+ port: proxyURL.port,
3360
+ auth: proxyAuth && typeof proxyAuth === 'string' ? proxyAuth : undefined
3361
+ };
3362
+ if (proxyURL.protocol === 'https:') {
3363
+ agentOptions.ALPNProtocols = ['http/1.1'];
3364
+ }
3365
+ const tunnelingAgent = getTunnelingAgent(agentOptions, configHttpsAgent);
3366
+ // Set both: `options.agent` is consumed by the native https.request path
3367
+ // (maxRedirects === 0); `options.agents.https` is consumed by
3368
+ // follow-redirects, which ignores `options.agent` when `options.agents`
3369
+ // is present.
3370
+ options.agent = tunnelingAgent;
3371
+ if (options.agents) {
3372
+ options.agents.https = tunnelingAgent;
3373
+ }
3374
+ }
3375
+ } else {
3376
+ // Forward-proxy mode for plaintext HTTP targets. The request line carries
3377
+ // the absolute URL and the proxy sees everything — acceptable for plain
3378
+ // HTTP since the wire was already plaintext.
3379
+ if (proxyAuth) {
3380
+ const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64');
3381
+ options.headers['Proxy-Authorization'] = 'Basic ' + base64;
3382
+ }
3040
3383
 
3041
- // Preserve a user-supplied Host header (case-insensitive) so callers can override
3042
- // the value forwarded to the proxy; otherwise default to the request URL's host.
3043
- let hasUserHostHeader = false;
3044
- for (const name of Object.keys(options.headers)) {
3045
- if (name.toLowerCase() === 'host') {
3046
- hasUserHostHeader = true;
3047
- break;
3384
+ // Preserve a user-supplied Host header (case-insensitive) so callers can override
3385
+ // the value forwarded to the proxy; otherwise default to the request URL's host.
3386
+ let hasUserHostHeader = false;
3387
+ for (const name of Object.keys(options.headers)) {
3388
+ if (name.toLowerCase() === 'host') {
3389
+ hasUserHostHeader = true;
3390
+ break;
3391
+ }
3392
+ }
3393
+ if (!hasUserHostHeader) {
3394
+ options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
3395
+ }
3396
+ const proxyHost = readProxyField('hostname') || readProxyField('host');
3397
+ options.hostname = proxyHost;
3398
+ // Replace 'host' since options is not a URL object
3399
+ options.host = proxyHost;
3400
+ options.port = readProxyField('port');
3401
+ options.path = location;
3402
+ const proxyProtocol = readProxyField('protocol');
3403
+ if (proxyProtocol) {
3404
+ options.protocol = proxyProtocol.includes(':') ? proxyProtocol : `${proxyProtocol}:`;
3048
3405
  }
3049
- }
3050
- if (!hasUserHostHeader) {
3051
- options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
3052
- }
3053
- const proxyHost = readProxyField('hostname') || readProxyField('host');
3054
- options.hostname = proxyHost;
3055
- // Replace 'host' since options is not a URL object
3056
- options.host = proxyHost;
3057
- options.port = readProxyField('port');
3058
- options.path = location;
3059
- const proxyProtocol = readProxyField('protocol');
3060
- if (proxyProtocol) {
3061
- options.protocol = proxyProtocol.includes(':') ? proxyProtocol : `${proxyProtocol}:`;
3062
3406
  }
3063
3407
  }
3064
3408
  options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {
3065
3409
  // Configure proxy for redirected request, passing the original config proxy to apply
3066
3410
  // the exact same logic as if the redirected request was performed by axios directly.
3067
- setProxy(redirectOptions, configProxy, redirectOptions.href, true);
3411
+ setProxy(redirectOptions, configProxy, redirectOptions.href, true, configHttpsAgent);
3068
3412
  };
3069
3413
  }
3070
3414
  const isHttpAdapterSupported = typeof process !== 'undefined' && utils$1.kindOf(process) === 'process';
@@ -3147,7 +3491,13 @@ const http2Transport = {
3147
3491
  /*eslint consistent-return:0*/
3148
3492
  var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3149
3493
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
3150
- const own = key => utils$1.hasOwnProp(config, key) ? config[key] : undefined;
3494
+ // Read config pollution-safely: own properties and members inherited from
3495
+ // a non-Object.prototype source (e.g. an Object.create(defaults) template)
3496
+ // are honored, but values injected onto a polluted Object.prototype are
3497
+ // ignored. All behavior-affecting reads in this adapter go through own()
3498
+ // so the protection boundary stays consistent.
3499
+ const own = key => utils$1.getSafeProp(config, key);
3500
+ const transitional = own('transitional') || transitionalDefaults;
3151
3501
  let data = own('data');
3152
3502
  let lookup = own('lookup');
3153
3503
  let family = own('family');
@@ -3156,7 +3506,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3156
3506
  let http2Options = own('http2Options');
3157
3507
  const responseType = own('responseType');
3158
3508
  const responseEncoding = own('responseEncoding');
3159
- const method = config.method.toUpperCase();
3509
+ const httpAgent = own('httpAgent');
3510
+ const httpsAgent = own('httpsAgent');
3511
+ const method = own('method').toUpperCase();
3512
+ const maxRedirects = own('maxRedirects');
3513
+ const maxBodyLength = own('maxBodyLength');
3514
+ const maxContentLength = own('maxContentLength');
3515
+ const decompress = own('decompress');
3160
3516
  let isDone;
3161
3517
  let rejected = false;
3162
3518
  let req;
@@ -3187,7 +3543,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3187
3543
  try {
3188
3544
  abortEmitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
3189
3545
  } catch (err) {
3190
- console.warn('emit error', err);
3546
+ // ignore emit errors
3191
3547
  }
3192
3548
  }
3193
3549
  function clearConnectPhaseTimer() {
@@ -3197,10 +3553,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3197
3553
  }
3198
3554
  }
3199
3555
  function createTimeoutError() {
3200
- let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';
3201
- const transitional = config.transitional || transitionalDefaults;
3202
- if (config.timeoutErrorMessage) {
3203
- timeoutErrorMessage = config.timeoutErrorMessage;
3556
+ const configTimeout = own('timeout');
3557
+ let timeoutErrorMessage = configTimeout ? 'timeout of ' + configTimeout + 'ms exceeded' : 'timeout exceeded';
3558
+ const configTimeoutErrorMessage = own('timeoutErrorMessage');
3559
+ if (configTimeoutErrorMessage) {
3560
+ timeoutErrorMessage = configTimeoutErrorMessage;
3204
3561
  }
3205
3562
  return new AxiosError(timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, req);
3206
3563
  }
@@ -3243,17 +3600,17 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3243
3600
  });
3244
3601
 
3245
3602
  // Parse url
3246
- const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
3603
+ const fullPath = buildFullPath(own('baseURL'), own('url'), own('allowAbsoluteUrls'), config);
3247
3604
  const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
3248
3605
  const protocol = parsed.protocol || supportedProtocols[0];
3249
3606
  if (protocol === 'data:') {
3250
3607
  // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
3251
- if (config.maxContentLength > -1) {
3252
- // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.
3253
- const dataUrl = String(config.url || fullPath || '');
3608
+ if (maxContentLength > -1) {
3609
+ // Use the exact string passed to fromDataURI (the configured url); fall back to fullPath if needed.
3610
+ const dataUrl = String(own('url') || fullPath || '');
3254
3611
  const estimated = estimateDataURLDecodedBytes(dataUrl);
3255
- if (estimated > config.maxContentLength) {
3256
- return reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config));
3612
+ if (estimated > maxContentLength) {
3613
+ return reject(new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config));
3257
3614
  }
3258
3615
  }
3259
3616
  let convertedData;
@@ -3266,7 +3623,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3266
3623
  });
3267
3624
  }
3268
3625
  try {
3269
- convertedData = fromDataURI(config.url, responseType === 'blob', {
3626
+ convertedData = fromDataURI(own('url'), responseType === 'blob', {
3270
3627
  Blob: config.env && config.env.Blob
3271
3628
  });
3272
3629
  } catch (err) {
@@ -3340,7 +3697,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3340
3697
 
3341
3698
  // Add Content-Length header if data exists
3342
3699
  headers.setContentLength(data.length, false);
3343
- if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
3700
+ if (maxBodyLength > -1 && data.length > maxBodyLength) {
3344
3701
  return reject(new AxiosError('Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config));
3345
3702
  }
3346
3703
  }
@@ -3367,37 +3724,37 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3367
3724
  let auth = undefined;
3368
3725
  const configAuth = own('auth');
3369
3726
  if (configAuth) {
3370
- const username = configAuth.username || '';
3371
- const password = configAuth.password || '';
3727
+ const username = utils$1.getSafeProp(configAuth, 'username') || '';
3728
+ const password = utils$1.getSafeProp(configAuth, 'password') || '';
3372
3729
  auth = username + ':' + password;
3373
3730
  }
3374
- if (!auth && parsed.username) {
3375
- const urlUsername = decodeURIComponentSafe(parsed.username);
3376
- const urlPassword = decodeURIComponentSafe(parsed.password);
3731
+ if (!auth && (parsed.username || parsed.password)) {
3732
+ const urlUsername = decodeURIComponentSafe$1(parsed.username);
3733
+ const urlPassword = decodeURIComponentSafe$1(parsed.password);
3377
3734
  auth = urlUsername + ':' + urlPassword;
3378
3735
  }
3379
3736
  auth && headers.delete('authorization');
3380
3737
  let path$1;
3381
3738
  try {
3382
- path$1 = buildURL(parsed.pathname + parsed.search, config.params, config.paramsSerializer).replace(/^\?/, '');
3739
+ path$1 = buildURL(parsed.pathname + parsed.search, own('params'), own('paramsSerializer')).replace(/^\?/, '');
3383
3740
  } catch (err) {
3384
3741
  const customErr = new Error(err.message);
3385
3742
  customErr.config = config;
3386
- customErr.url = config.url;
3743
+ customErr.url = own('url');
3387
3744
  customErr.exists = true;
3388
3745
  return reject(customErr);
3389
3746
  }
3390
- headers.set('Accept-Encoding', 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''), false);
3747
+ headers.set('Accept-Encoding', utils$1.hasOwnProp(transitional, 'advertiseZstdAcceptEncoding') && transitional.advertiseZstdAcceptEncoding === true ? ACCEPT_ENCODING_WITH_ZSTD : ACCEPT_ENCODING, false);
3391
3748
 
3392
3749
  // Null-prototype to block prototype pollution gadgets on properties read
3393
3750
  // directly by Node's http.request (e.g. insecureHTTPParser, lookup).
3394
3751
  const options = Object.assign(Object.create(null), {
3395
3752
  path: path$1,
3396
3753
  method: method,
3397
- headers: headers.toJSON(),
3754
+ headers: toByteStringHeaderObject(headers),
3398
3755
  agents: {
3399
- http: config.httpAgent,
3400
- https: config.httpsAgent
3756
+ http: httpAgent,
3757
+ https: httpsAgent
3401
3758
  },
3402
3759
  auth,
3403
3760
  protocol,
@@ -3409,50 +3766,101 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3409
3766
 
3410
3767
  // cacheable-lookup integration hotfix
3411
3768
  !utils$1.isUndefined(lookup) && (options.lookup = lookup);
3412
- if (config.socketPath) {
3413
- if (typeof config.socketPath !== 'string') {
3769
+ const socketPath = own('socketPath');
3770
+ if (socketPath) {
3771
+ if (typeof socketPath !== 'string') {
3414
3772
  return reject(new AxiosError('socketPath must be a string', AxiosError.ERR_BAD_OPTION_VALUE, config));
3415
3773
  }
3416
- if (config.allowedSocketPaths != null) {
3417
- const allowed = Array.isArray(config.allowedSocketPaths) ? config.allowedSocketPaths : [config.allowedSocketPaths];
3418
- const resolvedSocket = path.resolve(config.socketPath);
3774
+ const allowedSocketPaths = own('allowedSocketPaths');
3775
+ if (allowedSocketPaths != null) {
3776
+ const allowed = Array.isArray(allowedSocketPaths) ? allowedSocketPaths : [allowedSocketPaths];
3777
+ const resolvedSocket = path.resolve(socketPath);
3419
3778
  const isAllowed = allowed.some(entry => typeof entry === 'string' && path.resolve(entry) === resolvedSocket);
3420
3779
  if (!isAllowed) {
3421
- return reject(new AxiosError(`socketPath "${config.socketPath}" is not permitted by allowedSocketPaths`, AxiosError.ERR_BAD_OPTION_VALUE, config));
3780
+ return reject(new AxiosError(`socketPath "${socketPath}" is not permitted by allowedSocketPaths`, AxiosError.ERR_BAD_OPTION_VALUE, config));
3422
3781
  }
3423
3782
  }
3424
- options.socketPath = config.socketPath;
3783
+ options.socketPath = socketPath;
3425
3784
  } else {
3426
3785
  options.hostname = parsed.hostname.startsWith('[') ? parsed.hostname.slice(1, -1) : parsed.hostname;
3427
3786
  options.port = parsed.port;
3428
- setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);
3787
+ setProxy(options, own('proxy'), protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path, false, httpsAgent);
3429
3788
  }
3430
3789
  let transport;
3431
3790
  let isNativeTransport = false;
3791
+ // True only for the follow-redirects transport, which applies
3792
+ // options.maxBodyLength itself. Every other transport (http2, native
3793
+ // http/https, a user-supplied custom transport) needs the explicit
3794
+ // byte-counting pipeline below to enforce maxBodyLength on streamed uploads.
3795
+ let transportEnforcesMaxBodyLength = false;
3432
3796
  const isHttpsRequest = isHttps.test(options.protocol);
3433
- options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
3797
+ // Don't clobber a CONNECT-tunneling agent installed by setProxy() for an
3798
+ // HTTPS target.
3799
+ if (options.agent == null) {
3800
+ options.agent = isHttpsRequest ? httpsAgent : httpAgent;
3801
+ }
3434
3802
  if (isHttp2) {
3435
3803
  transport = http2Transport;
3436
3804
  } else {
3437
3805
  const configTransport = own('transport');
3438
3806
  if (configTransport) {
3439
3807
  transport = configTransport;
3440
- } else if (config.maxRedirects === 0) {
3808
+ } else if (maxRedirects === 0) {
3441
3809
  transport = isHttpsRequest ? https : http;
3442
3810
  isNativeTransport = true;
3443
3811
  } else {
3444
- if (config.maxRedirects) {
3445
- options.maxRedirects = config.maxRedirects;
3812
+ transportEnforcesMaxBodyLength = true;
3813
+ options.sensitiveHeaders = [];
3814
+ if (maxRedirects) {
3815
+ options.maxRedirects = maxRedirects;
3446
3816
  }
3447
3817
  const configBeforeRedirect = own('beforeRedirect');
3448
3818
  if (configBeforeRedirect) {
3449
3819
  options.beforeRedirects.config = configBeforeRedirect;
3450
3820
  }
3821
+ if (auth) {
3822
+ // Restore HTTP Basic credentials on same-origin redirects only.
3823
+ // follow-redirects >= 1.15.8 strips Authorization on every redirect (see #6929);
3824
+ // cross-origin stripping is the documented mitigation for T-R2 in THREATMODEL.md
3825
+ // and is preserved by deliberately not restoring on origin change.
3826
+ const requestOrigin = parsed.origin;
3827
+ const authToRestore = auth;
3828
+ options.beforeRedirects.auth = function beforeRedirectAuth(redirectOptions) {
3829
+ try {
3830
+ if (new URL(redirectOptions.href).origin === requestOrigin) {
3831
+ redirectOptions.auth = authToRestore;
3832
+ }
3833
+ } catch (e) {
3834
+ // ignore malformed URL: leaving auth stripped is fail-safe
3835
+ }
3836
+ };
3837
+ }
3838
+ const sensitiveHeaders = own('sensitiveHeaders');
3839
+ if (sensitiveHeaders != null) {
3840
+ if (!utils$1.isArray(sensitiveHeaders)) {
3841
+ return reject(new AxiosError('sensitiveHeaders must be an array of strings', AxiosError.ERR_BAD_OPTION_VALUE, config));
3842
+ }
3843
+ const sensitiveSet = new Set();
3844
+ for (const header of sensitiveHeaders) {
3845
+ if (!utils$1.isString(header)) {
3846
+ return reject(new AxiosError('sensitiveHeaders must be an array of strings', AxiosError.ERR_BAD_OPTION_VALUE, config));
3847
+ }
3848
+ sensitiveSet.add(header.toLowerCase());
3849
+ }
3850
+ if (sensitiveSet.size) {
3851
+ options.sensitiveHeaders = Array.from(sensitiveSet);
3852
+ options.beforeRedirects.sensitiveHeaders = function beforeRedirectSensitiveHeaders(redirectOptions, requestDetails) {
3853
+ if (!isSameOriginRedirect(redirectOptions, requestDetails)) {
3854
+ stripMatchingHeaders(redirectOptions.headers, sensitiveSet);
3855
+ }
3856
+ };
3857
+ }
3858
+ }
3451
3859
  transport = isHttpsRequest ? httpsFollow : httpFollow;
3452
3860
  }
3453
3861
  }
3454
- if (config.maxBodyLength > -1) {
3455
- options.maxBodyLength = config.maxBodyLength;
3862
+ if (maxBodyLength > -1) {
3863
+ options.maxBodyLength = maxBodyLength;
3456
3864
  } else {
3457
3865
  // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
3458
3866
  options.maxBodyLength = Infinity;
@@ -3484,7 +3892,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3484
3892
  const lastRequest = res.req || req;
3485
3893
 
3486
3894
  // if decompress disabled we should not decompress
3487
- if (config.decompress !== false && res.headers['content-encoding']) {
3895
+ if (decompress !== false && res.headers['content-encoding']) {
3488
3896
  // if no content, but headers still say that it is encoded,
3489
3897
  // remove the header not confuse downstream operations
3490
3898
  if (method === 'HEAD' || res.statusCode === 204) {
@@ -3516,6 +3924,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3516
3924
  streams.push(zlib.createBrotliDecompress(brotliOptions));
3517
3925
  delete res.headers['content-encoding'];
3518
3926
  }
3927
+ break;
3928
+ case 'zstd':
3929
+ if (isZstdSupported) {
3930
+ streams.push(zlib.createZstdDecompress(zstdOptions));
3931
+ delete res.headers['content-encoding'];
3932
+ }
3933
+ break;
3519
3934
  }
3520
3935
  }
3521
3936
  responseStream = streams.length > 1 ? stream.pipeline(streams, utils$1.noop) : streams[0];
@@ -3529,8 +3944,8 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3529
3944
  if (responseType === 'stream') {
3530
3945
  // Enforce maxContentLength on streamed responses; previously this
3531
3946
  // was applied only to buffered responses.
3532
- if (config.maxContentLength > -1) {
3533
- const limit = config.maxContentLength;
3947
+ if (maxContentLength > -1) {
3948
+ const limit = maxContentLength;
3534
3949
  const source = responseStream;
3535
3950
  async function* enforceMaxContentLength() {
3536
3951
  let totalResponseBytes = 0;
@@ -3556,11 +3971,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3556
3971
  totalResponseBytes += chunk.length;
3557
3972
 
3558
3973
  // make sure the content length is not over the maxContentLength if specified
3559
- if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
3974
+ if (maxContentLength > -1 && totalResponseBytes > maxContentLength) {
3560
3975
  // stream.destroy() emit aborted event before calling reject() on Node.js v16
3561
3976
  rejected = true;
3562
3977
  responseStream.destroy();
3563
- abort(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
3978
+ abort(new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
3564
3979
  }
3565
3980
  });
3566
3981
  responseStream.on('aborted', function handlerStreamAborted() {
@@ -3653,9 +4068,9 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3653
4068
  });
3654
4069
 
3655
4070
  // Handle request timeout
3656
- if (config.timeout) {
4071
+ if (own('timeout')) {
3657
4072
  // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
3658
- const timeout = parseInt(config.timeout, 10);
4073
+ const timeout = parseInt(own('timeout'), 10);
3659
4074
  if (Number.isNaN(timeout)) {
3660
4075
  abort(new AxiosError('error trying to parse `config.timeout` to int', AxiosError.ERR_BAD_OPTION_VALUE, config, req));
3661
4076
  return;
@@ -3699,12 +4114,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3699
4114
  }
3700
4115
  });
3701
4116
 
3702
- // Enforce maxBodyLength for streamed uploads on the native http/https
3703
- // transport (maxRedirects === 0); follow-redirects enforces it on the
3704
- // other path.
4117
+ // Enforce maxBodyLength for streamed uploads on every transport that
4118
+ // does not apply options.maxBodyLength itself (native http/https, http2,
4119
+ // and user-supplied custom transports). The follow-redirects transport
4120
+ // enforces it on the redirected HTTP/1 path.
3705
4121
  let uploadStream = data;
3706
- if (config.maxBodyLength > -1 && config.maxRedirects === 0) {
3707
- const limit = config.maxBodyLength;
4122
+ if (maxBodyLength > -1 && !transportEnforcesMaxBodyLength) {
4123
+ const limit = maxBodyLength;
3708
4124
  let bytesSent = 0;
3709
4125
  uploadStream = stream.pipeline([data, new stream.Transform({
3710
4126
  transform(chunk, _enc, cb) {
@@ -3851,6 +4267,23 @@ function mergeConfig(config1, config2) {
3851
4267
  return getMergedValue(undefined, a);
3852
4268
  }
3853
4269
  }
4270
+ function getMergedTransitionalOption(prop) {
4271
+ const transitional2 = utils$1.hasOwnProp(config2, 'transitional') ? config2.transitional : undefined;
4272
+ if (!utils$1.isUndefined(transitional2)) {
4273
+ if (utils$1.isPlainObject(transitional2)) {
4274
+ if (utils$1.hasOwnProp(transitional2, prop)) {
4275
+ return transitional2[prop];
4276
+ }
4277
+ } else {
4278
+ return undefined;
4279
+ }
4280
+ }
4281
+ const transitional1 = utils$1.hasOwnProp(config1, 'transitional') ? config1.transitional : undefined;
4282
+ if (utils$1.isPlainObject(transitional1) && utils$1.hasOwnProp(transitional1, prop)) {
4283
+ return transitional1[prop];
4284
+ }
4285
+ return undefined;
4286
+ }
3854
4287
 
3855
4288
  // eslint-disable-next-line consistent-return
3856
4289
  function mergeDirectKeys(a, b, prop) {
@@ -3903,6 +4336,13 @@ function mergeConfig(config1, config2) {
3903
4336
  const configValue = merge(a, b, prop);
3904
4337
  utils$1.isUndefined(configValue) && merge !== mergeDirectKeys || (config[prop] = configValue);
3905
4338
  });
4339
+ if (utils$1.hasOwnProp(config2, 'validateStatus') && utils$1.isUndefined(config2.validateStatus) && getMergedTransitionalOption('validateStatusUndefinedResolves') === false) {
4340
+ if (utils$1.hasOwnProp(config1, 'validateStatus')) {
4341
+ config.validateStatus = getMergedValue(undefined, config1.validateStatus);
4342
+ } else {
4343
+ delete config.validateStatus;
4344
+ }
4345
+ }
3906
4346
  return config;
3907
4347
  }
3908
4348
 
@@ -3927,8 +4367,8 @@ function setFormDataHeaders(headers, formHeaders, policy) {
3927
4367
  *
3928
4368
  * @returns {string} UTF-8 bytes as a Latin-1 string
3929
4369
  */
3930
- const encodeUTF8 = str => encodeURIComponent(str).replace(/%([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
3931
- var resolveConfig = config => {
4370
+ const encodeUTF8$1 = str => encodeURIComponent(str).replace(/%([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
4371
+ function resolveConfig(config) {
3932
4372
  const newConfig = mergeConfig({}, config);
3933
4373
 
3934
4374
  // Read only own properties to prevent prototype pollution gadgets
@@ -3944,15 +4384,17 @@ var resolveConfig = config => {
3944
4384
  const allowAbsoluteUrls = own('allowAbsoluteUrls');
3945
4385
  const url = own('url');
3946
4386
  newConfig.headers = headers = AxiosHeaders.from(headers);
3947
- newConfig.url = buildURL(buildFullPath(baseURL, url, allowAbsoluteUrls), config.params, config.paramsSerializer);
4387
+ newConfig.url = buildURL(buildFullPath(baseURL, url, allowAbsoluteUrls, newConfig), own('params'), own('paramsSerializer'));
3948
4388
 
3949
4389
  // HTTP basic authentication
3950
4390
  if (auth) {
3951
- headers.set('Authorization', 'Basic ' + btoa((auth.username || '') + ':' + (auth.password ? encodeUTF8(auth.password) : '')));
4391
+ const username = utils$1.getSafeProp(auth, 'username') || '';
4392
+ const password = utils$1.getSafeProp(auth, 'password') || '';
4393
+ headers.set('Authorization', 'Basic ' + btoa(username + ':' + (password ? encodeUTF8$1(password) : '')));
3952
4394
  }
3953
4395
  if (utils$1.isFormData(data)) {
3954
- if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {
3955
- headers.setContentType(undefined); // browser handles it
4396
+ if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv || utils$1.isReactNative(data)) {
4397
+ headers.setContentType(undefined); // browser/web worker/RN handles it
3956
4398
  } else if (utils$1.isFunction(data.getHeaders)) {
3957
4399
  // Node.js FormData (like form-data package)
3958
4400
  setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
@@ -3980,7 +4422,7 @@ var resolveConfig = config => {
3980
4422
  }
3981
4423
  }
3982
4424
  return newConfig;
3983
- };
4425
+ }
3984
4426
 
3985
4427
  const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';
3986
4428
  var xhrAdapter = isXHRAdapterSupported && function (config) {
@@ -4102,7 +4544,7 @@ var xhrAdapter = isXHRAdapterSupported && function (config) {
4102
4544
 
4103
4545
  // Add headers to the request
4104
4546
  if ('setRequestHeader' in request) {
4105
- utils$1.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {
4547
+ utils$1.forEach(toByteStringHeaderObject(requestHeaders), function setRequestHeader(val, key) {
4106
4548
  request.setRequestHeader(key, val);
4107
4549
  });
4108
4550
  }
@@ -4158,41 +4600,41 @@ var xhrAdapter = isXHRAdapterSupported && function (config) {
4158
4600
  };
4159
4601
 
4160
4602
  const composeSignals = (signals, timeout) => {
4161
- const {
4162
- length
4163
- } = signals = signals ? signals.filter(Boolean) : [];
4164
- if (timeout || length) {
4165
- let controller = new AbortController();
4166
- let aborted;
4167
- const onabort = function (reason) {
4168
- if (!aborted) {
4169
- aborted = true;
4170
- unsubscribe();
4171
- const err = reason instanceof Error ? reason : this.reason;
4172
- controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
4173
- }
4174
- };
4175
- let timer = timeout && setTimeout(() => {
4176
- timer = null;
4177
- onabort(new AxiosError(`timeout of ${timeout}ms exceeded`, AxiosError.ETIMEDOUT));
4178
- }, timeout);
4179
- const unsubscribe = () => {
4180
- if (signals) {
4181
- timer && clearTimeout(timer);
4182
- timer = null;
4183
- signals.forEach(signal => {
4184
- signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);
4185
- });
4186
- signals = null;
4187
- }
4188
- };
4189
- signals.forEach(signal => signal.addEventListener('abort', onabort));
4190
- const {
4191
- signal
4192
- } = controller;
4193
- signal.unsubscribe = () => utils$1.asap(unsubscribe);
4194
- return signal;
4603
+ signals = signals ? signals.filter(Boolean) : [];
4604
+ if (!timeout && !signals.length) {
4605
+ return;
4195
4606
  }
4607
+ const controller = new AbortController();
4608
+ let aborted = false;
4609
+ const onabort = function (reason) {
4610
+ if (!aborted) {
4611
+ aborted = true;
4612
+ unsubscribe();
4613
+ const err = reason instanceof Error ? reason : this.reason;
4614
+ controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
4615
+ }
4616
+ };
4617
+ let timer = timeout && setTimeout(() => {
4618
+ timer = null;
4619
+ onabort(new AxiosError(`timeout of ${timeout}ms exceeded`, AxiosError.ETIMEDOUT));
4620
+ }, timeout);
4621
+ const unsubscribe = () => {
4622
+ if (!signals) {
4623
+ return;
4624
+ }
4625
+ timer && clearTimeout(timer);
4626
+ timer = null;
4627
+ signals.forEach(signal => {
4628
+ signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);
4629
+ });
4630
+ signals = null;
4631
+ };
4632
+ signals.forEach(signal => signal.addEventListener('abort', onabort));
4633
+ const {
4634
+ signal
4635
+ } = controller;
4636
+ signal.unsubscribe = () => utils$1.asap(unsubscribe);
4637
+ return signal;
4196
4638
  };
4197
4639
 
4198
4640
  const streamChunk = function* (chunk, chunkSize) {
@@ -4281,6 +4723,31 @@ const DEFAULT_CHUNK_SIZE = 64 * 1024;
4281
4723
  const {
4282
4724
  isFunction
4283
4725
  } = utils$1;
4726
+
4727
+ /**
4728
+ * Encode a UTF-8 string to a Latin-1 byte string for use with btoa().
4729
+ * This is a modern replacement for the deprecated unescape(encodeURIComponent(str)) pattern.
4730
+ *
4731
+ * @param {string} str The string to encode
4732
+ *
4733
+ * @returns {string} UTF-8 bytes as a Latin-1 string
4734
+ */
4735
+ const encodeUTF8 = str => encodeURIComponent(str).replace(/%([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
4736
+
4737
+ // Node's WHATWG URL parser returns `username` and `password` percent-encoded.
4738
+ // Decode before composing the `auth` option so credentials such as
4739
+ // `my%40email.com:pass` are sent as `my@email.com:pass`. Falls back to the
4740
+ // original value for malformed input so a bad encoding never throws.
4741
+ const decodeURIComponentSafe = value => {
4742
+ if (!utils$1.isString(value)) {
4743
+ return value;
4744
+ }
4745
+ try {
4746
+ return decodeURIComponent(value);
4747
+ } catch (error) {
4748
+ return value;
4749
+ }
4750
+ };
4284
4751
  const test = (fn, ...args) => {
4285
4752
  try {
4286
4753
  return !!fn(...args);
@@ -4288,9 +4755,16 @@ const test = (fn, ...args) => {
4288
4755
  return false;
4289
4756
  }
4290
4757
  };
4758
+ const maybeWithAuthCredentials = url => {
4759
+ const protocolIndex = url.indexOf('://');
4760
+ let urlToCheck = url;
4761
+ if (protocolIndex !== -1) {
4762
+ urlToCheck = urlToCheck.slice(protocolIndex + 3);
4763
+ }
4764
+ return urlToCheck.includes('@') || urlToCheck.includes(':');
4765
+ };
4291
4766
  const factory = env => {
4292
- var _utils$global;
4293
- const globalObject = (_utils$global = utils$1.global) !== null && _utils$global !== void 0 ? _utils$global : globalThis;
4767
+ const globalObject = utils$1.global !== undefined && utils$1.global !== null ? utils$1.global : globalThis;
4294
4768
  const {
4295
4769
  ReadableStream,
4296
4770
  TextEncoder
@@ -4392,6 +4866,7 @@ const factory = env => {
4392
4866
  } = resolveConfig(config);
4393
4867
  const hasMaxContentLength = utils$1.isNumber(maxContentLength) && maxContentLength > -1;
4394
4868
  const hasMaxBodyLength = utils$1.isNumber(maxBodyLength) && maxBodyLength > -1;
4869
+ const own = key => utils$1.hasOwnProp(config, key) ? config[key] : undefined;
4395
4870
  let _fetch = envFetch || fetch;
4396
4871
  responseType = responseType ? (responseType + '').toLowerCase() : 'text';
4397
4872
  let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
@@ -4400,7 +4875,46 @@ const factory = env => {
4400
4875
  composedSignal.unsubscribe();
4401
4876
  });
4402
4877
  let requestContentLength;
4878
+
4879
+ // AxiosError we raise while the request body is being streamed. Captured
4880
+ // by identity so the catch block can surface it directly, regardless of
4881
+ // how the runtime wraps the resulting fetch rejection (undici exposes it
4882
+ // as `err.cause`; some browsers drop the original error entirely).
4883
+ let pendingBodyError = null;
4884
+ const maxBodyLengthError = () => new AxiosError('Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config, request);
4403
4885
  try {
4886
+ // HTTP basic authentication
4887
+ let auth = undefined;
4888
+ const configAuth = own('auth');
4889
+ if (configAuth) {
4890
+ const username = utils$1.getSafeProp(configAuth, 'username') || '';
4891
+ const password = utils$1.getSafeProp(configAuth, 'password') || '';
4892
+ auth = {
4893
+ username,
4894
+ password
4895
+ };
4896
+ }
4897
+ if (maybeWithAuthCredentials(url)) {
4898
+ const parsedURL = new URL(url, platform.origin);
4899
+ if (!auth && (parsedURL.username || parsedURL.password)) {
4900
+ const urlUsername = decodeURIComponentSafe(parsedURL.username);
4901
+ const urlPassword = decodeURIComponentSafe(parsedURL.password);
4902
+ auth = {
4903
+ username: urlUsername,
4904
+ password: urlPassword
4905
+ };
4906
+ }
4907
+ if (parsedURL.username || parsedURL.password) {
4908
+ parsedURL.username = '';
4909
+ parsedURL.password = '';
4910
+ url = parsedURL.href;
4911
+ }
4912
+ }
4913
+ if (auth) {
4914
+ headers.delete('authorization');
4915
+ headers.set('Authorization', 'Basic ' + btoa(encodeUTF8((auth.username || '') + ':' + (auth.password || ''))));
4916
+ }
4917
+
4404
4918
  // Enforce maxContentLength for data: URLs up-front so we never materialize
4405
4919
  // an oversized payload. The HTTP adapter applies the same check (see http.js
4406
4920
  // "if (protocol === 'data:')" branch).
@@ -4411,30 +4925,54 @@ const factory = env => {
4411
4925
  }
4412
4926
  }
4413
4927
 
4414
- // Enforce maxBodyLength against the outbound request body before dispatch.
4415
- // Mirrors http.js behavior (ERR_BAD_REQUEST / 'Request body larger than
4416
- // maxBodyLength limit'). Skip when the body length cannot be determined
4417
- // (e.g. a live ReadableStream supplied by the caller).
4928
+ // Enforce maxBodyLength against known-size bodies before dispatch using
4929
+ // the body's *actual* size never a caller-declared Content-Length,
4930
+ // which could under-report to slip an oversized body past the check.
4931
+ // Unknown-size streams return undefined here and are counted per-chunk
4932
+ // below as fetch consumes them.
4418
4933
  if (hasMaxBodyLength && method !== 'get' && method !== 'head') {
4419
- const outboundLength = await resolveBodyLength(headers, data);
4420
- if (typeof outboundLength === 'number' && isFinite(outboundLength) && outboundLength > maxBodyLength) {
4421
- throw new AxiosError('Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config, request);
4934
+ const outboundLength = await getBodyLength(data);
4935
+ if (typeof outboundLength === 'number' && isFinite(outboundLength)) {
4936
+ requestContentLength = outboundLength;
4937
+ if (outboundLength > maxBodyLength) {
4938
+ throw maxBodyLengthError();
4939
+ }
4422
4940
  }
4423
4941
  }
4424
- if (onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' && (requestContentLength = await resolveBodyLength(headers, data)) !== 0) {
4425
- let _request = new Request(url, {
4426
- method: 'POST',
4427
- body: data,
4428
- duplex: 'half'
4429
- });
4430
- let contentTypeHeader;
4431
- if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
4432
- headers.setContentType(contentTypeHeader);
4942
+
4943
+ // A streamed body under maxBodyLength must be counted as fetch consumes
4944
+ // it; its size is never trusted from a caller-declared Content-Length.
4945
+ const mustEnforceStreamBody = hasMaxBodyLength && (utils$1.isReadableStream(data) || utils$1.isStream(data));
4946
+ const trackRequestStream = (stream, onProgress, flush) => trackStream(stream, DEFAULT_CHUNK_SIZE, loadedBytes => {
4947
+ if (hasMaxBodyLength && loadedBytes > maxBodyLength) {
4948
+ throw pendingBodyError = maxBodyLengthError();
4433
4949
  }
4434
- if (_request.body) {
4435
- const [onProgress, flush] = progressEventDecorator(requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress)));
4436
- data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
4950
+ onProgress && onProgress(loadedBytes);
4951
+ }, flush);
4952
+ if (supportsRequestStream && method !== 'get' && method !== 'head' && (onUploadProgress || mustEnforceStreamBody)) {
4953
+ requestContentLength = requestContentLength == null ? await resolveBodyLength(headers, data) : requestContentLength;
4954
+
4955
+ // A declared length of 0 is only trusted to skip the wrap when we are
4956
+ // not enforcing a stream limit (which must not rely on that header).
4957
+ if (requestContentLength !== 0 || mustEnforceStreamBody) {
4958
+ let _request = new Request(url, {
4959
+ method: 'POST',
4960
+ body: data,
4961
+ duplex: 'half'
4962
+ });
4963
+ let contentTypeHeader;
4964
+ if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
4965
+ headers.setContentType(contentTypeHeader);
4966
+ }
4967
+ if (_request.body) {
4968
+ const [onProgress, flush] = onUploadProgress && progressEventDecorator(requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress))) || [];
4969
+ data = trackRequestStream(_request.body, onProgress, flush);
4970
+ }
4437
4971
  }
4972
+ } else if (mustEnforceStreamBody && !isRequestSupported && isReadableStreamSupported && method !== 'get' && method !== 'head') {
4973
+ data = trackRequestStream(data);
4974
+ } else if (mustEnforceStreamBody && isRequestSupported && !supportsRequestStream && method !== 'get' && method !== 'head') {
4975
+ throw new AxiosError('Stream request bodies are not supported by the current fetch implementation', AxiosError.ERR_NOT_SUPPORT, config, request);
4438
4976
  }
4439
4977
  if (!utils$1.isString(withCredentials)) {
4440
4978
  withCredentials = withCredentials ? 'include' : 'omit';
@@ -4459,18 +4997,19 @@ const factory = env => {
4459
4997
  ...fetchOptions,
4460
4998
  signal: composedSignal,
4461
4999
  method: method.toUpperCase(),
4462
- headers: headers.normalize().toJSON(),
5000
+ headers: toByteStringHeaderObject(headers.normalize()),
4463
5001
  body: data,
4464
5002
  duplex: 'half',
4465
5003
  credentials: isCredentialsSupported ? withCredentials : undefined
4466
5004
  };
4467
5005
  request = isRequestSupported && new Request(url, resolvedOptions);
4468
5006
  let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));
5007
+ const responseHeaders = AxiosHeaders.from(response.headers);
4469
5008
 
4470
5009
  // Cheap pre-check: if the server honestly declares a content-length that
4471
5010
  // already exceeds the cap, reject before we start streaming.
4472
5011
  if (hasMaxContentLength) {
4473
- const declaredLength = utils$1.toFiniteNumber(response.headers.get('content-length'));
5012
+ const declaredLength = utils$1.toFiniteNumber(responseHeaders.getContentLength());
4474
5013
  if (declaredLength != null && declaredLength > maxContentLength) {
4475
5014
  throw new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, request);
4476
5015
  }
@@ -4481,7 +5020,7 @@ const factory = env => {
4481
5020
  ['status', 'statusText', 'headers'].forEach(prop => {
4482
5021
  options[prop] = response[prop];
4483
5022
  });
4484
- const responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length'));
5023
+ const responseContentLength = utils$1.toFiniteNumber(responseHeaders.getContentLength());
4485
5024
  const [onProgress, flush] = onDownloadProgress && progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true)) || [];
4486
5025
  let bytesRead = 0;
4487
5026
  const onChunkProgress = loadedBytes => {
@@ -4543,6 +5082,23 @@ const factory = env => {
4543
5082
  err !== canceledError && (canceledError.cause = err);
4544
5083
  throw canceledError;
4545
5084
  }
5085
+
5086
+ // Surface a maxBodyLength violation we raised while the request body was
5087
+ // being streamed. Matching by identity (rather than reading
5088
+ // `err.cause.isAxiosError`) keeps the error deterministic across runtimes
5089
+ // and avoids both prototype-pollution reads and mis-attributing a foreign
5090
+ // AxiosError that merely happened to land in `err.cause`.
5091
+ if (pendingBodyError) {
5092
+ request && !pendingBodyError.request && (pendingBodyError.request = request);
5093
+ throw pendingBodyError;
5094
+ }
5095
+
5096
+ // Re-throw AxiosErrors we raised synchronously (data: URL / content-length
5097
+ // pre-checks, response size enforcement) without re-wrapping them.
5098
+ if (err instanceof AxiosError) {
5099
+ request && !err.request && (err.request = request);
5100
+ throw err;
5101
+ }
4546
5102
  if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
4547
5103
  throw Object.assign(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request, err && err.response), {
4548
5104
  cause: err.cause || err
@@ -4917,7 +5473,9 @@ class Axios {
4917
5473
  silentJSONParsing: validators.transitional(validators.boolean),
4918
5474
  forcedJSONParsing: validators.transitional(validators.boolean),
4919
5475
  clarifyTimeoutError: validators.transitional(validators.boolean),
4920
- legacyInterceptorReqResOrdering: validators.transitional(validators.boolean)
5476
+ legacyInterceptorReqResOrdering: validators.transitional(validators.boolean),
5477
+ advertiseZstdAcceptEncoding: validators.transitional(validators.boolean),
5478
+ validateStatusUndefinedResolves: validators.transitional(validators.boolean)
4921
5479
  }, false);
4922
5480
  }
4923
5481
  if (paramsSerializer != null) {
@@ -5014,7 +5572,7 @@ class Axios {
5014
5572
  }
5015
5573
  getUri(config) {
5016
5574
  config = mergeConfig(this.defaults, config);
5017
- const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
5575
+ const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls, config);
5018
5576
  return buildURL(fullPath, config.params, config.paramsSerializer);
5019
5577
  }
5020
5578
  }
@@ -5026,7 +5584,7 @@ utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoDa
5026
5584
  return this.request(mergeConfig(config || {}, {
5027
5585
  method,
5028
5586
  url,
5029
- data: (config || {}).data
5587
+ data: config && utils$1.hasOwnProp(config, 'data') ? config.data : undefined
5030
5588
  }));
5031
5589
  };
5032
5590
  });