@zuplo/cli 6.70.70 → 6.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/node_modules/@types/node/README.md +1 -1
  2. package/node_modules/@types/node/http2.d.ts +1 -0
  3. package/node_modules/@types/node/package.json +2 -2
  4. package/node_modules/@zuplo/core/package.json +1 -1
  5. package/node_modules/@zuplo/graphql/package.json +1 -1
  6. package/node_modules/@zuplo/openapi-tools/package.json +1 -1
  7. package/node_modules/@zuplo/otel/package.json +1 -1
  8. package/node_modules/@zuplo/runtime/out/esm/{chunk-GEVKFSKR.js → chunk-AZIRK6TC.js} +1 -1
  9. package/node_modules/@zuplo/runtime/out/esm/{chunk-GEVKFSKR.js.map → chunk-AZIRK6TC.js.map} +1 -1
  10. package/node_modules/@zuplo/runtime/out/esm/{chunk-MJPI3GFA.js → chunk-E7U425SB.js} +72 -72
  11. package/node_modules/@zuplo/runtime/out/esm/chunk-E7U425SB.js.map +1 -0
  12. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  13. package/node_modules/@zuplo/runtime/out/esm/index.js.map +1 -1
  14. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +7 -7
  15. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js.map +1 -1
  16. package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
  17. package/node_modules/@zuplo/runtime/out/types/index.d.ts +61 -0
  18. package/node_modules/@zuplo/runtime/package.json +1 -1
  19. package/node_modules/acorn/CHANGELOG.md +14 -0
  20. package/node_modules/acorn/README.md +3 -0
  21. package/node_modules/acorn/dist/acorn.d.mts +6 -0
  22. package/node_modules/acorn/dist/acorn.d.ts +6 -0
  23. package/node_modules/acorn/dist/acorn.js +87 -49
  24. package/node_modules/acorn/dist/acorn.mjs +87 -49
  25. package/node_modules/acorn/package.json +2 -2
  26. package/node_modules/axios/CHANGELOG.md +52 -1
  27. package/node_modules/axios/README.md +30 -2
  28. package/node_modules/axios/dist/axios.js +350 -134
  29. package/node_modules/axios/dist/axios.min.js +3 -3
  30. package/node_modules/axios/dist/axios.min.js.map +1 -1
  31. package/node_modules/axios/dist/browser/axios.cjs +355 -90
  32. package/node_modules/axios/dist/esm/axios.js +355 -90
  33. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  34. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  35. package/node_modules/axios/dist/node/axios.cjs +399 -104
  36. package/node_modules/axios/index.d.cts +2 -0
  37. package/node_modules/axios/index.d.ts +2 -0
  38. package/node_modules/axios/lib/adapters/fetch.js +113 -37
  39. package/node_modules/axios/lib/adapters/http.js +132 -43
  40. package/node_modules/axios/lib/core/Axios.js +3 -2
  41. package/node_modules/axios/lib/core/AxiosHeaders.js +10 -7
  42. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  43. package/node_modules/axios/lib/core/mergeConfig.js +34 -0
  44. package/node_modules/axios/lib/defaults/transitional.js +1 -0
  45. package/node_modules/axios/lib/env/data.js +1 -1
  46. package/node_modules/axios/lib/helpers/buildURL.js +5 -3
  47. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  48. package/node_modules/axios/lib/helpers/formDataToJSON.js +25 -3
  49. package/node_modules/axios/lib/helpers/resolveConfig.js +5 -3
  50. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  51. package/node_modules/axios/lib/helpers/toFormData.js +40 -10
  52. package/node_modules/axios/lib/utils.js +75 -11
  53. package/node_modules/axios/package.json +1 -1
  54. package/node_modules/form-data/CHANGELOG.md +29 -2
  55. package/node_modules/form-data/README.md +4 -4
  56. package/node_modules/form-data/lib/form_data.js +14 -2
  57. package/node_modules/form-data/package.json +7 -7
  58. package/node_modules/protobufjs/dist/light/protobuf.js +145 -188
  59. package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
  60. package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
  61. package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
  62. package/node_modules/protobufjs/dist/minimal/protobuf.js +33 -76
  63. package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
  64. package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
  65. package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
  66. package/node_modules/protobufjs/dist/protobuf.js +165 -208
  67. package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
  68. package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
  69. package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
  70. package/node_modules/protobufjs/index.d.ts +0 -8
  71. package/node_modules/protobufjs/package.json +2 -3
  72. package/node_modules/protobufjs/src/util/minimal.js +0 -3
  73. package/package.json +6 -6
  74. package/node_modules/@protobufjs/inquire/CHANGELOG.md +0 -8
  75. package/node_modules/@protobufjs/inquire/LICENSE +0 -26
  76. package/node_modules/@protobufjs/inquire/README.md +0 -13
  77. package/node_modules/@protobufjs/inquire/index.d.ts +0 -10
  78. package/node_modules/@protobufjs/inquire/index.js +0 -38
  79. package/node_modules/@protobufjs/inquire/package.json +0 -21
  80. package/node_modules/@protobufjs/inquire/tests/data/array.js +0 -1
  81. package/node_modules/@protobufjs/inquire/tests/data/emptyArray.js +0 -1
  82. package/node_modules/@protobufjs/inquire/tests/data/emptyObject.js +0 -1
  83. package/node_modules/@protobufjs/inquire/tests/data/object.js +0 -1
  84. package/node_modules/@protobufjs/inquire/tests/index.js +0 -20
  85. package/node_modules/@zuplo/runtime/out/esm/chunk-MJPI3GFA.js.map +0 -1
  86. /package/node_modules/@zuplo/runtime/out/esm/{chunk-MJPI3GFA.js.LEGAL.txt → chunk-E7U425SB.js.LEGAL.txt} +0 -0
@@ -1,4 +1,4 @@
1
- /*! Axios v1.17.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');
@@ -40,6 +40,52 @@ const {
40
40
  iterator,
41
41
  toStringTag
42
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;
43
89
  const kindOf = (cache => thing => {
44
90
  const str = toString.call(thing);
45
91
  return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
@@ -158,11 +204,15 @@ const isBoolean = thing => thing === true || thing === false;
158
204
  * @returns {boolean} True if value is a plain Object, otherwise false
159
205
  */
160
206
  const isPlainObject = val => {
161
- if (kindOf(val) !== 'object') {
207
+ if (!isObject(val)) {
162
208
  return false;
163
209
  }
164
210
  const prototype = getPrototypeOf(val);
165
- 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);
166
216
  };
167
217
 
168
218
  /**
@@ -662,11 +712,6 @@ const toCamelCase = str => {
662
712
  return p1.toUpperCase() + p2;
663
713
  });
664
714
  };
665
-
666
- /* Creating a function that will check if an object has a property. */
667
- const hasOwnProperty = (({
668
- hasOwnProperty
669
- }) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);
670
715
  const {
671
716
  propertyIsEnumerable
672
717
  } = Object.prototype;
@@ -844,6 +889,19 @@ const asap = typeof queueMicrotask !== 'undefined' ? queueMicrotask.bind(_global
844
889
  // *********************
845
890
 
846
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);
847
905
  var utils$1 = {
848
906
  isArray,
849
907
  isArrayBuffer,
@@ -889,6 +947,8 @@ var utils$1 = {
889
947
  hasOwnProperty,
890
948
  hasOwnProp: hasOwnProperty,
891
949
  // an alias to avoid ESLint no-prototype-builtins detection
950
+ hasOwnInPrototypeChain,
951
+ getSafeProp,
892
952
  reduceDescriptors,
893
953
  freezeMethods,
894
954
  toObjectSet,
@@ -904,7 +964,8 @@ var utils$1 = {
904
964
  isThenable,
905
965
  setImmediate: _setImmediate,
906
966
  asap,
907
- isIterable
967
+ isIterable,
968
+ isSafeIterable
908
969
  };
909
970
 
910
971
  // RawAxiosHeaders whose duplicates are ignored by node
@@ -1066,15 +1127,21 @@ class AxiosHeaders {
1066
1127
  setHeaders(header, valueOrRewrite);
1067
1128
  } else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
1068
1129
  setHeaders(parseHeaders(header), valueOrRewrite);
1069
- } else if (utils$1.isObject(header) && utils$1.isIterable(header)) {
1070
- let obj = {},
1130
+ } else if (utils$1.isObject(header) && utils$1.isSafeIterable(header)) {
1131
+ let obj = Object.create(null),
1071
1132
  dest,
1072
1133
  key;
1073
1134
  for (const entry of header) {
1074
1135
  if (!utils$1.isArray(entry)) {
1075
1136
  throw new TypeError('Object iterator must return a key-value pair');
1076
1137
  }
1077
- obj[key = entry[0]] = (dest = obj[key]) ? utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]] : entry[1];
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];
1144
+ }
1078
1145
  }
1079
1146
  setHeaders(obj, valueOrRewrite);
1080
1147
  } else {
@@ -1377,6 +1444,10 @@ AxiosError.ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT';
1377
1444
  AxiosError.ERR_INVALID_URL = 'ERR_INVALID_URL';
1378
1445
  AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED';
1379
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
+
1380
1451
  /**
1381
1452
  * Determines if the given thing is a array or js object.
1382
1453
  *
@@ -1477,8 +1548,9 @@ function toFormData(obj, formData, options) {
1477
1548
  const dots = options.dots;
1478
1549
  const indexes = options.indexes;
1479
1550
  const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;
1480
- const maxDepth = options.maxDepth === undefined ? 100 : options.maxDepth;
1551
+ const maxDepth = options.maxDepth === undefined ? DEFAULT_FORM_DATA_MAX_DEPTH : options.maxDepth;
1481
1552
  const useBlob = _Blob && utils$1.isSpecCompliantForm(formData);
1553
+ const stack = [];
1482
1554
  if (!utils$1.isFunction(visitor)) {
1483
1555
  throw new TypeError('visitor must be a function');
1484
1556
  }
@@ -1498,6 +1570,28 @@ function toFormData(obj, formData, options) {
1498
1570
  }
1499
1571
  return value;
1500
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
+ }
1501
1595
 
1502
1596
  /**
1503
1597
  * Default visitor.
@@ -1520,7 +1614,7 @@ function toFormData(obj, formData, options) {
1520
1614
  // eslint-disable-next-line no-param-reassign
1521
1615
  key = metaTokens ? key : key.slice(0, -2);
1522
1616
  // eslint-disable-next-line no-param-reassign
1523
- value = JSON.stringify(value);
1617
+ value = stringifyWithDepthLimit(value, 1);
1524
1618
  } else if (utils$1.isArray(value) && isFlatArray(value) || (utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value))) {
1525
1619
  // eslint-disable-next-line no-param-reassign
1526
1620
  key = removeBrackets(key);
@@ -1538,7 +1632,6 @@ function toFormData(obj, formData, options) {
1538
1632
  formData.append(renderKey(path, key, dots), convertValue(value));
1539
1633
  return false;
1540
1634
  }
1541
- const stack = [];
1542
1635
  const exposedHelpers = Object.assign(predicates, {
1543
1636
  defaultVisitor,
1544
1637
  convertValue,
@@ -1546,9 +1639,7 @@ function toFormData(obj, formData, options) {
1546
1639
  });
1547
1640
  function build(value, path, depth = 0) {
1548
1641
  if (utils$1.isUndefined(value)) return;
1549
- if (depth > maxDepth) {
1550
- throw new AxiosError('Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
1551
- }
1642
+ throwIfMaxDepthExceeded(depth);
1552
1643
  if (stack.indexOf(value) !== -1) {
1553
1644
  throw new Error('Circular reference detected in ' + path.join('.'));
1554
1645
  }
@@ -1640,11 +1731,15 @@ function buildURL(url, params, options) {
1640
1731
  if (!params) {
1641
1732
  return url;
1642
1733
  }
1643
- const _encode = options && options.encode || encode;
1644
1734
  const _options = utils$1.isFunction(options) ? {
1645
1735
  serialize: options
1646
1736
  } : options;
1647
- 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');
1648
1743
  let serializedParams;
1649
1744
  if (serializeFn) {
1650
1745
  serializedParams = serializeFn(params, _options);
@@ -1733,7 +1828,8 @@ var transitionalDefaults = {
1733
1828
  forcedJSONParsing: true,
1734
1829
  clarifyTimeoutError: false,
1735
1830
  legacyInterceptorReqResOrdering: true,
1736
- advertiseZstdAcceptEncoding: false
1831
+ advertiseZstdAcceptEncoding: false,
1832
+ validateStatusUndefinedResolves: true
1737
1833
  };
1738
1834
 
1739
1835
  var URLSearchParams = url.URLSearchParams;
@@ -1834,6 +1930,13 @@ function toURLEncodedForm(data, options) {
1834
1930
  });
1835
1931
  }
1836
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
+
1837
1940
  /**
1838
1941
  * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']
1839
1942
  *
@@ -1846,9 +1949,14 @@ function parsePropPath(name) {
1846
1949
  // foo.x.y.z
1847
1950
  // foo-x-y-z
1848
1951
  // foo x y z
1849
- return utils$1.matchAll(/\w+|\[(\w*)]/g, name).map(match => {
1850
- return match[0] === '[]' ? '' : match[1] || match[0];
1851
- });
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;
1852
1960
  }
1853
1961
 
1854
1962
  /**
@@ -1880,6 +1988,7 @@ function arrayToObject(arr) {
1880
1988
  */
1881
1989
  function formDataToJSON(formData) {
1882
1990
  function buildPath(path, value, target, index) {
1991
+ throwIfDepthExceeded(index);
1883
1992
  let name = path[index++];
1884
1993
  if (name === '__proto__') return true;
1885
1994
  const isNumericKey = Number.isFinite(+name);
@@ -2120,6 +2229,24 @@ function combineURLs(baseURL, relativeURL) {
2120
2229
  return relativeURL ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;
2121
2230
  }
2122
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
+
2123
2250
  /**
2124
2251
  * Creates a new URL by combining the baseURL with the requestedURL,
2125
2252
  * only when the requestedURL is not already an absolute URL.
@@ -2130,9 +2257,11 @@ function combineURLs(baseURL, relativeURL) {
2130
2257
  *
2131
2258
  * @returns {string} The combined full path
2132
2259
  */
2133
- function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
2260
+ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls, config) {
2261
+ assertValidHttpProtocolURL(requestedURL, config);
2134
2262
  let isRelativeUrl = !isAbsoluteURL(requestedURL);
2135
2263
  if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) {
2264
+ assertValidHttpProtocolURL(baseURL, config);
2136
2265
  return combineURLs(baseURL, requestedURL);
2137
2266
  }
2138
2267
  return requestedURL;
@@ -2234,7 +2363,7 @@ function getEnv(key) {
2234
2363
  return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
2235
2364
  }
2236
2365
 
2237
- const VERSION = "1.17.0";
2366
+ const VERSION = "1.18.0";
2238
2367
 
2239
2368
  function parseProtocol(url) {
2240
2369
  const match = /^([-+\w]{1,25}):(?:\/\/)?/.exec(url);
@@ -2617,13 +2746,34 @@ const callbackify = (fn, reducer) => {
2617
2746
  } : fn;
2618
2747
  };
2619
2748
 
2620
- const LOOPBACK_HOSTNAMES = new Set(['localhost']);
2749
+ const LOOPBACK_HOSTNAMES = new Set(['localhost', '0.0.0.0']);
2621
2750
  const isIPv4Loopback = host => {
2622
2751
  const parts = host.split('.');
2623
2752
  if (parts.length !== 4) return false;
2624
2753
  if (parts[0] !== '127') return false;
2625
2754
  return parts.every(p => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
2626
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
+ };
2627
2777
  const isIPv6Loopback = host => {
2628
2778
  // Collapse all-zero groups: any form of ::1 / 0:0:...:0:1
2629
2779
  // First, strip any leading "::" by normalising with Set lookup of common forms,
@@ -2656,6 +2806,7 @@ const isLoopback = host => {
2656
2806
  if (!host) return false;
2657
2807
  if (LOOPBACK_HOSTNAMES.has(host)) return true;
2658
2808
  if (isIPv4Loopback(host)) return true;
2809
+ if (isIPv6Unspecified(host)) return true;
2659
2810
  return isIPv6Loopback(host);
2660
2811
  };
2661
2812
  const DEFAULT_PORTS = {
@@ -2875,11 +3026,13 @@ const asyncDecorator = fn => (...args) => utils$1.asap(() => fn(...args));
2875
3026
  * Estimate decoded byte length of a data:// URL *without* allocating large buffers.
2876
3027
  * - For base64: compute exact decoded size using length and padding;
2877
3028
  * handle %XX at the character-count level (no string allocation).
2878
- * - 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.
2879
3030
  *
2880
3031
  * @param {string} url
2881
3032
  * @returns {number}
2882
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));
2883
3036
  function estimateDataURLDecodedBytes(url) {
2884
3037
  if (!url || typeof url !== 'string') return 0;
2885
3038
  if (!url.startsWith('data:')) return 0;
@@ -2896,7 +3049,7 @@ function estimateDataURLDecodedBytes(url) {
2896
3049
  if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {
2897
3050
  const a = body.charCodeAt(i + 1);
2898
3051
  const b = body.charCodeAt(i + 2);
2899
- 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);
2900
3053
  if (isHex) {
2901
3054
  effectiveLen -= 2;
2902
3055
  i += 2;
@@ -2931,18 +3084,18 @@ function estimateDataURLDecodedBytes(url) {
2931
3084
  const bytes = groups * 3 - (pad || 0);
2932
3085
  return bytes > 0 ? bytes : 0;
2933
3086
  }
2934
- if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') {
2935
- return Buffer.byteLength(body, 'utf8');
2936
- }
2937
3087
 
2938
3088
  // Compute UTF-8 byte length directly from UTF-16 code units without allocating
2939
3089
  // a byte buffer (TextEncoder.encode would defeat the DoS guard on large bodies).
2940
- // Using body.length here would undercount non-ASCII (e.g. '€' is 1 code unit
2941
- // 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.
2942
3092
  let bytes = 0;
2943
3093
  for (let i = 0, len = body.length; i < len; i++) {
2944
3094
  const c = body.charCodeAt(i);
2945
- if (c < 0x80) {
3095
+ if (c === 37 /* '%' */ && isPercentEncodedByte(body, i, len)) {
3096
+ bytes += 1;
3097
+ i += 2;
3098
+ } else if (c < 0x80) {
2946
3099
  bytes += 1;
2947
3100
  } else if (c < 0x800) {
2948
3101
  bytes += 2;
@@ -3066,8 +3219,8 @@ const flushOnFinish = (stream, [throttled, flush]) => {
3066
3219
  const http2Sessions = new Http2Sessions();
3067
3220
 
3068
3221
  /**
3069
- * If the proxy, auth, or config beforeRedirects functions are defined, call them
3070
- * with the options object.
3222
+ * If the proxy, auth, sensitive header, or config beforeRedirects functions are defined,
3223
+ * call them with the options object.
3071
3224
  *
3072
3225
  * @param {Object<string, any>} options - The options object that was passed to the request.
3073
3226
  *
@@ -3080,10 +3233,34 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
3080
3233
  if (options.beforeRedirects.auth) {
3081
3234
  options.beforeRedirects.auth(options);
3082
3235
  }
3236
+ if (options.beforeRedirects.sensitiveHeaders) {
3237
+ options.beforeRedirects.sensitiveHeaders(options, requestDetails);
3238
+ }
3083
3239
  if (options.beforeRedirects.config) {
3084
3240
  options.beforeRedirects.config(options, responseDetails, requestDetails);
3085
3241
  }
3086
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
+ }
3087
3264
 
3088
3265
  /**
3089
3266
  * If the proxy or config afterRedirects functions are defined, call them with the options
@@ -3187,7 +3364,7 @@ function setProxy(options, configProxy, location, isRedirect, configHttpsAgent)
3187
3364
  }
3188
3365
  const tunnelingAgent = getTunnelingAgent(agentOptions, configHttpsAgent);
3189
3366
  // Set both: `options.agent` is consumed by the native https.request path
3190
- // (config.maxRedirects === 0); `options.agents.https` is consumed by
3367
+ // (maxRedirects === 0); `options.agents.https` is consumed by
3191
3368
  // follow-redirects, which ignores `options.agent` when `options.agents`
3192
3369
  // is present.
3193
3370
  options.agent = tunnelingAgent;
@@ -3314,7 +3491,12 @@ const http2Transport = {
3314
3491
  /*eslint consistent-return:0*/
3315
3492
  var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3316
3493
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
3317
- 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);
3318
3500
  const transitional = own('transitional') || transitionalDefaults;
3319
3501
  let data = own('data');
3320
3502
  let lookup = own('lookup');
@@ -3324,7 +3506,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3324
3506
  let http2Options = own('http2Options');
3325
3507
  const responseType = own('responseType');
3326
3508
  const responseEncoding = own('responseEncoding');
3327
- 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');
3328
3516
  let isDone;
3329
3517
  let rejected = false;
3330
3518
  let req;
@@ -3365,9 +3553,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3365
3553
  }
3366
3554
  }
3367
3555
  function createTimeoutError() {
3368
- let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';
3369
- if (config.timeoutErrorMessage) {
3370
- 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;
3371
3561
  }
3372
3562
  return new AxiosError(timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, req);
3373
3563
  }
@@ -3410,17 +3600,17 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3410
3600
  });
3411
3601
 
3412
3602
  // Parse url
3413
- const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
3603
+ const fullPath = buildFullPath(own('baseURL'), own('url'), own('allowAbsoluteUrls'), config);
3414
3604
  const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
3415
3605
  const protocol = parsed.protocol || supportedProtocols[0];
3416
3606
  if (protocol === 'data:') {
3417
3607
  // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
3418
- if (config.maxContentLength > -1) {
3419
- // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.
3420
- 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 || '');
3421
3611
  const estimated = estimateDataURLDecodedBytes(dataUrl);
3422
- if (estimated > config.maxContentLength) {
3423
- 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));
3424
3614
  }
3425
3615
  }
3426
3616
  let convertedData;
@@ -3433,7 +3623,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3433
3623
  });
3434
3624
  }
3435
3625
  try {
3436
- convertedData = fromDataURI(config.url, responseType === 'blob', {
3626
+ convertedData = fromDataURI(own('url'), responseType === 'blob', {
3437
3627
  Blob: config.env && config.env.Blob
3438
3628
  });
3439
3629
  } catch (err) {
@@ -3507,7 +3697,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3507
3697
 
3508
3698
  // Add Content-Length header if data exists
3509
3699
  headers.setContentLength(data.length, false);
3510
- if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
3700
+ if (maxBodyLength > -1 && data.length > maxBodyLength) {
3511
3701
  return reject(new AxiosError('Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config));
3512
3702
  }
3513
3703
  }
@@ -3534,8 +3724,8 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3534
3724
  let auth = undefined;
3535
3725
  const configAuth = own('auth');
3536
3726
  if (configAuth) {
3537
- const username = configAuth.username || '';
3538
- const password = configAuth.password || '';
3727
+ const username = utils$1.getSafeProp(configAuth, 'username') || '';
3728
+ const password = utils$1.getSafeProp(configAuth, 'password') || '';
3539
3729
  auth = username + ':' + password;
3540
3730
  }
3541
3731
  if (!auth && (parsed.username || parsed.password)) {
@@ -3546,11 +3736,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3546
3736
  auth && headers.delete('authorization');
3547
3737
  let path$1;
3548
3738
  try {
3549
- 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(/^\?/, '');
3550
3740
  } catch (err) {
3551
3741
  const customErr = new Error(err.message);
3552
3742
  customErr.config = config;
3553
- customErr.url = config.url;
3743
+ customErr.url = own('url');
3554
3744
  customErr.exists = true;
3555
3745
  return reject(customErr);
3556
3746
  }
@@ -3563,8 +3753,8 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3563
3753
  method: method,
3564
3754
  headers: toByteStringHeaderObject(headers),
3565
3755
  agents: {
3566
- http: config.httpAgent,
3567
- https: config.httpsAgent
3756
+ http: httpAgent,
3757
+ https: httpsAgent
3568
3758
  },
3569
3759
  auth,
3570
3760
  protocol,
@@ -3594,15 +3784,20 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3594
3784
  } else {
3595
3785
  options.hostname = parsed.hostname.startsWith('[') ? parsed.hostname.slice(1, -1) : parsed.hostname;
3596
3786
  options.port = parsed.port;
3597
- setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path, false, config.httpsAgent);
3787
+ setProxy(options, own('proxy'), protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path, false, httpsAgent);
3598
3788
  }
3599
3789
  let transport;
3600
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;
3601
3796
  const isHttpsRequest = isHttps.test(options.protocol);
3602
3797
  // Don't clobber a CONNECT-tunneling agent installed by setProxy() for an
3603
3798
  // HTTPS target.
3604
3799
  if (options.agent == null) {
3605
- options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
3800
+ options.agent = isHttpsRequest ? httpsAgent : httpAgent;
3606
3801
  }
3607
3802
  if (isHttp2) {
3608
3803
  transport = http2Transport;
@@ -3610,12 +3805,14 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3610
3805
  const configTransport = own('transport');
3611
3806
  if (configTransport) {
3612
3807
  transport = configTransport;
3613
- } else if (config.maxRedirects === 0) {
3808
+ } else if (maxRedirects === 0) {
3614
3809
  transport = isHttpsRequest ? https : http;
3615
3810
  isNativeTransport = true;
3616
3811
  } else {
3617
- if (config.maxRedirects) {
3618
- options.maxRedirects = config.maxRedirects;
3812
+ transportEnforcesMaxBodyLength = true;
3813
+ options.sensitiveHeaders = [];
3814
+ if (maxRedirects) {
3815
+ options.maxRedirects = maxRedirects;
3619
3816
  }
3620
3817
  const configBeforeRedirect = own('beforeRedirect');
3621
3818
  if (configBeforeRedirect) {
@@ -3638,11 +3835,32 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3638
3835
  }
3639
3836
  };
3640
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
+ }
3641
3859
  transport = isHttpsRequest ? httpsFollow : httpFollow;
3642
3860
  }
3643
3861
  }
3644
- if (config.maxBodyLength > -1) {
3645
- options.maxBodyLength = config.maxBodyLength;
3862
+ if (maxBodyLength > -1) {
3863
+ options.maxBodyLength = maxBodyLength;
3646
3864
  } else {
3647
3865
  // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
3648
3866
  options.maxBodyLength = Infinity;
@@ -3674,7 +3892,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3674
3892
  const lastRequest = res.req || req;
3675
3893
 
3676
3894
  // if decompress disabled we should not decompress
3677
- if (config.decompress !== false && res.headers['content-encoding']) {
3895
+ if (decompress !== false && res.headers['content-encoding']) {
3678
3896
  // if no content, but headers still say that it is encoded,
3679
3897
  // remove the header not confuse downstream operations
3680
3898
  if (method === 'HEAD' || res.statusCode === 204) {
@@ -3726,8 +3944,8 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3726
3944
  if (responseType === 'stream') {
3727
3945
  // Enforce maxContentLength on streamed responses; previously this
3728
3946
  // was applied only to buffered responses.
3729
- if (config.maxContentLength > -1) {
3730
- const limit = config.maxContentLength;
3947
+ if (maxContentLength > -1) {
3948
+ const limit = maxContentLength;
3731
3949
  const source = responseStream;
3732
3950
  async function* enforceMaxContentLength() {
3733
3951
  let totalResponseBytes = 0;
@@ -3753,11 +3971,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3753
3971
  totalResponseBytes += chunk.length;
3754
3972
 
3755
3973
  // make sure the content length is not over the maxContentLength if specified
3756
- if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
3974
+ if (maxContentLength > -1 && totalResponseBytes > maxContentLength) {
3757
3975
  // stream.destroy() emit aborted event before calling reject() on Node.js v16
3758
3976
  rejected = true;
3759
3977
  responseStream.destroy();
3760
- 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));
3761
3979
  }
3762
3980
  });
3763
3981
  responseStream.on('aborted', function handlerStreamAborted() {
@@ -3850,9 +4068,9 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3850
4068
  });
3851
4069
 
3852
4070
  // Handle request timeout
3853
- if (config.timeout) {
4071
+ if (own('timeout')) {
3854
4072
  // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
3855
- const timeout = parseInt(config.timeout, 10);
4073
+ const timeout = parseInt(own('timeout'), 10);
3856
4074
  if (Number.isNaN(timeout)) {
3857
4075
  abort(new AxiosError('error trying to parse `config.timeout` to int', AxiosError.ERR_BAD_OPTION_VALUE, config, req));
3858
4076
  return;
@@ -3896,12 +4114,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
3896
4114
  }
3897
4115
  });
3898
4116
 
3899
- // Enforce maxBodyLength for streamed uploads on the native http/https
3900
- // transport (maxRedirects === 0); follow-redirects enforces it on the
3901
- // 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.
3902
4121
  let uploadStream = data;
3903
- if (config.maxBodyLength > -1 && config.maxRedirects === 0) {
3904
- const limit = config.maxBodyLength;
4122
+ if (maxBodyLength > -1 && !transportEnforcesMaxBodyLength) {
4123
+ const limit = maxBodyLength;
3905
4124
  let bytesSent = 0;
3906
4125
  uploadStream = stream.pipeline([data, new stream.Transform({
3907
4126
  transform(chunk, _enc, cb) {
@@ -4048,6 +4267,23 @@ function mergeConfig(config1, config2) {
4048
4267
  return getMergedValue(undefined, a);
4049
4268
  }
4050
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
+ }
4051
4287
 
4052
4288
  // eslint-disable-next-line consistent-return
4053
4289
  function mergeDirectKeys(a, b, prop) {
@@ -4100,6 +4336,13 @@ function mergeConfig(config1, config2) {
4100
4336
  const configValue = merge(a, b, prop);
4101
4337
  utils$1.isUndefined(configValue) && merge !== mergeDirectKeys || (config[prop] = configValue);
4102
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
+ }
4103
4346
  return config;
4104
4347
  }
4105
4348
 
@@ -4141,11 +4384,13 @@ function resolveConfig(config) {
4141
4384
  const allowAbsoluteUrls = own('allowAbsoluteUrls');
4142
4385
  const url = own('url');
4143
4386
  newConfig.headers = headers = AxiosHeaders.from(headers);
4144
- newConfig.url = buildURL(buildFullPath(baseURL, url, allowAbsoluteUrls), own('params'), own('paramsSerializer'));
4387
+ newConfig.url = buildURL(buildFullPath(baseURL, url, allowAbsoluteUrls, newConfig), own('params'), own('paramsSerializer'));
4145
4388
 
4146
4389
  // HTTP basic authentication
4147
4390
  if (auth) {
4148
- headers.set('Authorization', 'Basic ' + btoa((auth.username || '') + ':' + (auth.password ? encodeUTF8$1(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) : '')));
4149
4394
  }
4150
4395
  if (utils$1.isFormData(data)) {
4151
4396
  if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv || utils$1.isReactNative(data)) {
@@ -4630,13 +4875,20 @@ const factory = env => {
4630
4875
  composedSignal.unsubscribe();
4631
4876
  });
4632
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);
4633
4885
  try {
4634
4886
  // HTTP basic authentication
4635
4887
  let auth = undefined;
4636
4888
  const configAuth = own('auth');
4637
4889
  if (configAuth) {
4638
- const username = configAuth.username || '';
4639
- const password = configAuth.password || '';
4890
+ const username = utils$1.getSafeProp(configAuth, 'username') || '';
4891
+ const password = utils$1.getSafeProp(configAuth, 'password') || '';
4640
4892
  auth = {
4641
4893
  username,
4642
4894
  password
@@ -4673,30 +4925,54 @@ const factory = env => {
4673
4925
  }
4674
4926
  }
4675
4927
 
4676
- // Enforce maxBodyLength against the outbound request body before dispatch.
4677
- // Mirrors http.js behavior (ERR_BAD_REQUEST / 'Request body larger than
4678
- // maxBodyLength limit'). Skip when the body length cannot be determined
4679
- // (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.
4680
4933
  if (hasMaxBodyLength && method !== 'get' && method !== 'head') {
4681
- const outboundLength = await resolveBodyLength(headers, data);
4682
- if (typeof outboundLength === 'number' && isFinite(outboundLength) && outboundLength > maxBodyLength) {
4683
- 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
+ }
4684
4940
  }
4685
4941
  }
4686
- if (onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' && (requestContentLength = await resolveBodyLength(headers, data)) !== 0) {
4687
- let _request = new Request(url, {
4688
- method: 'POST',
4689
- body: data,
4690
- duplex: 'half'
4691
- });
4692
- let contentTypeHeader;
4693
- if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
4694
- 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();
4695
4949
  }
4696
- if (_request.body) {
4697
- const [onProgress, flush] = progressEventDecorator(requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress)));
4698
- 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
+ }
4699
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);
4700
4976
  }
4701
4977
  if (!utils$1.isString(withCredentials)) {
4702
4978
  withCredentials = withCredentials ? 'include' : 'omit';
@@ -4728,11 +5004,12 @@ const factory = env => {
4728
5004
  };
4729
5005
  request = isRequestSupported && new Request(url, resolvedOptions);
4730
5006
  let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));
5007
+ const responseHeaders = AxiosHeaders.from(response.headers);
4731
5008
 
4732
5009
  // Cheap pre-check: if the server honestly declares a content-length that
4733
5010
  // already exceeds the cap, reject before we start streaming.
4734
5011
  if (hasMaxContentLength) {
4735
- const declaredLength = utils$1.toFiniteNumber(response.headers.get('content-length'));
5012
+ const declaredLength = utils$1.toFiniteNumber(responseHeaders.getContentLength());
4736
5013
  if (declaredLength != null && declaredLength > maxContentLength) {
4737
5014
  throw new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, request);
4738
5015
  }
@@ -4743,7 +5020,7 @@ const factory = env => {
4743
5020
  ['status', 'statusText', 'headers'].forEach(prop => {
4744
5021
  options[prop] = response[prop];
4745
5022
  });
4746
- const responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length'));
5023
+ const responseContentLength = utils$1.toFiniteNumber(responseHeaders.getContentLength());
4747
5024
  const [onProgress, flush] = onDownloadProgress && progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true)) || [];
4748
5025
  let bytesRead = 0;
4749
5026
  const onChunkProgress = loadedBytes => {
@@ -4805,6 +5082,23 @@ const factory = env => {
4805
5082
  err !== canceledError && (canceledError.cause = err);
4806
5083
  throw canceledError;
4807
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
+ }
4808
5102
  if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
4809
5103
  throw Object.assign(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request, err && err.response), {
4810
5104
  cause: err.cause || err
@@ -5180,7 +5474,8 @@ class Axios {
5180
5474
  forcedJSONParsing: validators.transitional(validators.boolean),
5181
5475
  clarifyTimeoutError: validators.transitional(validators.boolean),
5182
5476
  legacyInterceptorReqResOrdering: validators.transitional(validators.boolean),
5183
- advertiseZstdAcceptEncoding: validators.transitional(validators.boolean)
5477
+ advertiseZstdAcceptEncoding: validators.transitional(validators.boolean),
5478
+ validateStatusUndefinedResolves: validators.transitional(validators.boolean)
5184
5479
  }, false);
5185
5480
  }
5186
5481
  if (paramsSerializer != null) {
@@ -5277,7 +5572,7 @@ class Axios {
5277
5572
  }
5278
5573
  getUri(config) {
5279
5574
  config = mergeConfig(this.defaults, config);
5280
- const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
5575
+ const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls, config);
5281
5576
  return buildURL(fullPath, config.params, config.paramsSerializer);
5282
5577
  }
5283
5578
  }
@@ -5289,7 +5584,7 @@ utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoDa
5289
5584
  return this.request(mergeConfig(config || {}, {
5290
5585
  method,
5291
5586
  url,
5292
- data: (config || {}).data
5587
+ data: config && utils$1.hasOwnProp(config, 'data') ? config.data : undefined
5293
5588
  }));
5294
5589
  };
5295
5590
  });