@zuplo/cli 6.70.71 → 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 (38) hide show
  1. package/node_modules/@zuplo/core/package.json +1 -1
  2. package/node_modules/@zuplo/graphql/package.json +1 -1
  3. package/node_modules/@zuplo/openapi-tools/package.json +1 -1
  4. package/node_modules/@zuplo/otel/package.json +1 -1
  5. package/node_modules/@zuplo/runtime/package.json +1 -1
  6. package/node_modules/axios/CHANGELOG.md +52 -1
  7. package/node_modules/axios/README.md +30 -2
  8. package/node_modules/axios/dist/axios.js +350 -134
  9. package/node_modules/axios/dist/axios.min.js +3 -3
  10. package/node_modules/axios/dist/axios.min.js.map +1 -1
  11. package/node_modules/axios/dist/browser/axios.cjs +355 -90
  12. package/node_modules/axios/dist/esm/axios.js +355 -90
  13. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  14. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  15. package/node_modules/axios/dist/node/axios.cjs +399 -104
  16. package/node_modules/axios/index.d.cts +2 -0
  17. package/node_modules/axios/index.d.ts +2 -0
  18. package/node_modules/axios/lib/adapters/fetch.js +113 -37
  19. package/node_modules/axios/lib/adapters/http.js +132 -43
  20. package/node_modules/axios/lib/core/Axios.js +3 -2
  21. package/node_modules/axios/lib/core/AxiosHeaders.js +10 -7
  22. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  23. package/node_modules/axios/lib/core/mergeConfig.js +34 -0
  24. package/node_modules/axios/lib/defaults/transitional.js +1 -0
  25. package/node_modules/axios/lib/env/data.js +1 -1
  26. package/node_modules/axios/lib/helpers/buildURL.js +5 -3
  27. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  28. package/node_modules/axios/lib/helpers/formDataToJSON.js +25 -3
  29. package/node_modules/axios/lib/helpers/resolveConfig.js +5 -3
  30. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  31. package/node_modules/axios/lib/helpers/toFormData.js +40 -10
  32. package/node_modules/axios/lib/utils.js +75 -11
  33. package/node_modules/axios/package.json +1 -1
  34. package/node_modules/form-data/CHANGELOG.md +29 -2
  35. package/node_modules/form-data/README.md +4 -4
  36. package/node_modules/form-data/lib/form_data.js +14 -2
  37. package/node_modules/form-data/package.json +7 -7
  38. package/package.json +6 -6
@@ -397,6 +397,7 @@ declare namespace axios {
397
397
  clarifyTimeoutError?: boolean;
398
398
  legacyInterceptorReqResOrdering?: boolean;
399
399
  advertiseZstdAcceptEncoding?: boolean;
400
+ validateStatusUndefinedResolves?: boolean;
400
401
  }
401
402
 
402
403
  interface GenericAbortSignal {
@@ -559,6 +560,7 @@ declare namespace axios {
559
560
  };
560
561
  formDataHeaderPolicy?: 'legacy' | 'content-only';
561
562
  redact?: string[];
563
+ sensitiveHeaders?: string[];
562
564
  }
563
565
 
564
566
  // Alias
@@ -284,6 +284,7 @@ export interface TransitionalOptions {
284
284
  clarifyTimeoutError?: boolean;
285
285
  legacyInterceptorReqResOrdering?: boolean;
286
286
  advertiseZstdAcceptEncoding?: boolean;
287
+ validateStatusUndefinedResolves?: boolean;
287
288
  }
288
289
 
289
290
  export interface GenericAbortSignal {
@@ -452,6 +453,7 @@ export interface AxiosRequestConfig<D = any> {
452
453
  };
453
454
  formDataHeaderPolicy?: 'legacy' | 'content-only';
454
455
  redact?: string[];
456
+ sensitiveHeaders?: string[];
455
457
  }
456
458
 
457
459
  // Alias
@@ -234,14 +234,28 @@ const factory = (env) => {
234
234
 
235
235
  let requestContentLength;
236
236
 
237
+ // AxiosError we raise while the request body is being streamed. Captured
238
+ // by identity so the catch block can surface it directly, regardless of
239
+ // how the runtime wraps the resulting fetch rejection (undici exposes it
240
+ // as `err.cause`; some browsers drop the original error entirely).
241
+ let pendingBodyError = null;
242
+
243
+ const maxBodyLengthError = () =>
244
+ new AxiosError(
245
+ 'Request body larger than maxBodyLength limit',
246
+ AxiosError.ERR_BAD_REQUEST,
247
+ config,
248
+ request
249
+ );
250
+
237
251
  try {
238
252
  // HTTP basic authentication
239
253
  let auth = undefined;
240
254
  const configAuth = own('auth');
241
255
 
242
256
  if (configAuth) {
243
- const username = configAuth.username || '';
244
- const password = configAuth.password || '';
257
+ const username = utils.getSafeProp(configAuth, 'username') || '';
258
+ const password = utils.getSafeProp(configAuth, 'password') || '';
245
259
  auth = {
246
260
  username,
247
261
  password
@@ -290,53 +304,96 @@ const factory = (env) => {
290
304
  }
291
305
  }
292
306
 
293
- // Enforce maxBodyLength against the outbound request body before dispatch.
294
- // Mirrors http.js behavior (ERR_BAD_REQUEST / 'Request body larger than
295
- // maxBodyLength limit'). Skip when the body length cannot be determined
296
- // (e.g. a live ReadableStream supplied by the caller).
307
+ // Enforce maxBodyLength against known-size bodies before dispatch using
308
+ // the body's *actual* size never a caller-declared Content-Length,
309
+ // which could under-report to slip an oversized body past the check.
310
+ // Unknown-size streams return undefined here and are counted per-chunk
311
+ // below as fetch consumes them.
297
312
  if (hasMaxBodyLength && method !== 'get' && method !== 'head') {
298
- const outboundLength = await resolveBodyLength(headers, data);
299
- if (
300
- typeof outboundLength === 'number' &&
301
- isFinite(outboundLength) &&
302
- outboundLength > maxBodyLength
303
- ) {
304
- throw new AxiosError(
305
- 'Request body larger than maxBodyLength limit',
306
- AxiosError.ERR_BAD_REQUEST,
307
- config,
308
- request
309
- );
313
+ const outboundLength = await getBodyLength(data);
314
+ if (typeof outboundLength === 'number' && isFinite(outboundLength)) {
315
+ requestContentLength = outboundLength;
316
+ if (outboundLength > maxBodyLength) {
317
+ throw maxBodyLengthError();
318
+ }
310
319
  }
311
320
  }
312
321
 
322
+ // A streamed body under maxBodyLength must be counted as fetch consumes
323
+ // it; its size is never trusted from a caller-declared Content-Length.
324
+ const mustEnforceStreamBody =
325
+ hasMaxBodyLength && (utils.isReadableStream(data) || utils.isStream(data));
326
+
327
+ const trackRequestStream = (stream, onProgress, flush) =>
328
+ trackStream(
329
+ stream,
330
+ DEFAULT_CHUNK_SIZE,
331
+ (loadedBytes) => {
332
+ if (hasMaxBodyLength && loadedBytes > maxBodyLength) {
333
+ throw (pendingBodyError = maxBodyLengthError());
334
+ }
335
+ onProgress && onProgress(loadedBytes);
336
+ },
337
+ flush
338
+ );
339
+
313
340
  if (
314
- onUploadProgress &&
315
341
  supportsRequestStream &&
316
342
  method !== 'get' &&
317
343
  method !== 'head' &&
318
- (requestContentLength = await resolveBodyLength(headers, data)) !== 0
344
+ (onUploadProgress || mustEnforceStreamBody)
319
345
  ) {
320
- let _request = new Request(url, {
321
- method: 'POST',
322
- body: data,
323
- duplex: 'half',
324
- });
346
+ requestContentLength =
347
+ requestContentLength == null ? await resolveBodyLength(headers, data) : requestContentLength;
348
+
349
+ // A declared length of 0 is only trusted to skip the wrap when we are
350
+ // not enforcing a stream limit (which must not rely on that header).
351
+ if (requestContentLength !== 0 || mustEnforceStreamBody) {
352
+ let _request = new Request(url, {
353
+ method: 'POST',
354
+ body: data,
355
+ duplex: 'half',
356
+ });
325
357
 
326
- let contentTypeHeader;
358
+ let contentTypeHeader;
327
359
 
328
- if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
329
- headers.setContentType(contentTypeHeader);
330
- }
360
+ if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
361
+ headers.setContentType(contentTypeHeader);
362
+ }
331
363
 
332
- if (_request.body) {
333
- const [onProgress, flush] = progressEventDecorator(
334
- requestContentLength,
335
- progressEventReducer(asyncDecorator(onUploadProgress))
336
- );
364
+ if (_request.body) {
365
+ const [onProgress, flush] =
366
+ (onUploadProgress &&
367
+ progressEventDecorator(
368
+ requestContentLength,
369
+ progressEventReducer(asyncDecorator(onUploadProgress))
370
+ )) ||
371
+ [];
337
372
 
338
- data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
373
+ data = trackRequestStream(_request.body, onProgress, flush);
374
+ }
339
375
  }
376
+ } else if (
377
+ mustEnforceStreamBody &&
378
+ !isRequestSupported &&
379
+ isReadableStreamSupported &&
380
+ method !== 'get' &&
381
+ method !== 'head'
382
+ ) {
383
+ data = trackRequestStream(data);
384
+ } else if (
385
+ mustEnforceStreamBody &&
386
+ isRequestSupported &&
387
+ !supportsRequestStream &&
388
+ method !== 'get' &&
389
+ method !== 'head'
390
+ ) {
391
+ throw new AxiosError(
392
+ 'Stream request bodies are not supported by the current fetch implementation',
393
+ AxiosError.ERR_NOT_SUPPORT,
394
+ config,
395
+ request
396
+ );
340
397
  }
341
398
 
342
399
  if (!utils.isString(withCredentials)) {
@@ -379,10 +436,12 @@ const factory = (env) => {
379
436
  ? _fetch(request, fetchOptions)
380
437
  : _fetch(url, resolvedOptions));
381
438
 
439
+ const responseHeaders = AxiosHeaders.from(response.headers);
440
+
382
441
  // Cheap pre-check: if the server honestly declares a content-length that
383
442
  // already exceeds the cap, reject before we start streaming.
384
443
  if (hasMaxContentLength) {
385
- const declaredLength = utils.toFiniteNumber(response.headers.get('content-length'));
444
+ const declaredLength = utils.toFiniteNumber(responseHeaders.getContentLength());
386
445
  if (declaredLength != null && declaredLength > maxContentLength) {
387
446
  throw new AxiosError(
388
447
  'maxContentLength size of ' + maxContentLength + ' exceeded',
@@ -407,7 +466,7 @@ const factory = (env) => {
407
466
  options[prop] = response[prop];
408
467
  });
409
468
 
410
- const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
469
+ const responseContentLength = utils.toFiniteNumber(responseHeaders.getContentLength());
411
470
 
412
471
  const [onProgress, flush] =
413
472
  (onDownloadProgress &&
@@ -502,6 +561,23 @@ const factory = (env) => {
502
561
  throw canceledError;
503
562
  }
504
563
 
564
+ // Surface a maxBodyLength violation we raised while the request body was
565
+ // being streamed. Matching by identity (rather than reading
566
+ // `err.cause.isAxiosError`) keeps the error deterministic across runtimes
567
+ // and avoids both prototype-pollution reads and mis-attributing a foreign
568
+ // AxiosError that merely happened to land in `err.cause`.
569
+ if (pendingBodyError) {
570
+ request && !pendingBodyError.request && (pendingBodyError.request = request);
571
+ throw pendingBodyError;
572
+ }
573
+
574
+ // Re-throw AxiosErrors we raised synchronously (data: URL / content-length
575
+ // pre-checks, response size enforcement) without re-wrapping them.
576
+ if (err instanceof AxiosError) {
577
+ request && !err.request && (err.request = request);
578
+ throw err;
579
+ }
580
+
505
581
  if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
506
582
  throw Object.assign(
507
583
  new AxiosError(
@@ -154,8 +154,8 @@ const flushOnFinish = (stream, [throttled, flush]) => {
154
154
  const http2Sessions = new Http2Sessions();
155
155
 
156
156
  /**
157
- * If the proxy, auth, or config beforeRedirects functions are defined, call them
158
- * with the options object.
157
+ * If the proxy, auth, sensitive header, or config beforeRedirects functions are defined,
158
+ * call them with the options object.
159
159
  *
160
160
  * @param {Object<string, any>} options - The options object that was passed to the request.
161
161
  *
@@ -168,11 +168,39 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
168
168
  if (options.beforeRedirects.auth) {
169
169
  options.beforeRedirects.auth(options);
170
170
  }
171
+ if (options.beforeRedirects.sensitiveHeaders) {
172
+ options.beforeRedirects.sensitiveHeaders(options, requestDetails);
173
+ }
171
174
  if (options.beforeRedirects.config) {
172
175
  options.beforeRedirects.config(options, responseDetails, requestDetails);
173
176
  }
174
177
  }
175
178
 
179
+ function stripMatchingHeaders(headers, sensitiveSet) {
180
+ if (!headers) {
181
+ return;
182
+ }
183
+
184
+ Object.keys(headers).forEach((header) => {
185
+ if (sensitiveSet.has(header.toLowerCase())) {
186
+ delete headers[header];
187
+ }
188
+ });
189
+ }
190
+
191
+ function isSameOriginRedirect(redirectOptions, requestDetails) {
192
+ if (!requestDetails) {
193
+ return false;
194
+ }
195
+
196
+ try {
197
+ return new URL(requestDetails.url).origin === new URL(redirectOptions.href).origin;
198
+ } catch (e) {
199
+ // If origin comparison fails, treat the redirect as unsafe.
200
+ return false;
201
+ }
202
+ }
203
+
176
204
  /**
177
205
  * If the proxy or config afterRedirects functions are defined, call them with the options
178
206
  *
@@ -290,7 +318,7 @@ function setProxy(options, configProxy, location, isRedirect, configHttpsAgent)
290
318
  }
291
319
  const tunnelingAgent = getTunnelingAgent(agentOptions, configHttpsAgent);
292
320
  // Set both: `options.agent` is consumed by the native https.request path
293
- // (config.maxRedirects === 0); `options.agents.https` is consumed by
321
+ // (maxRedirects === 0); `options.agents.https` is consumed by
294
322
  // follow-redirects, which ignores `options.agent` when `options.agents`
295
323
  // is present.
296
324
  options.agent = tunnelingAgent;
@@ -434,7 +462,12 @@ const http2Transport = {
434
462
  export default isHttpAdapterSupported &&
435
463
  function httpAdapter(config) {
436
464
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
437
- const own = (key) => (utils.hasOwnProp(config, key) ? config[key] : undefined);
465
+ // Read config pollution-safely: own properties and members inherited from
466
+ // a non-Object.prototype source (e.g. an Object.create(defaults) template)
467
+ // are honored, but values injected onto a polluted Object.prototype are
468
+ // ignored. All behavior-affecting reads in this adapter go through own()
469
+ // so the protection boundary stays consistent.
470
+ const own = (key) => utils.getSafeProp(config, key);
438
471
  const transitional = own('transitional') || transitionalDefaults;
439
472
  let data = own('data');
440
473
  let lookup = own('lookup');
@@ -444,7 +477,13 @@ export default isHttpAdapterSupported &&
444
477
  let http2Options = own('http2Options');
445
478
  const responseType = own('responseType');
446
479
  const responseEncoding = own('responseEncoding');
447
- const method = config.method.toUpperCase();
480
+ const httpAgent = own('httpAgent');
481
+ const httpsAgent = own('httpsAgent');
482
+ const method = own('method').toUpperCase();
483
+ const maxRedirects = own('maxRedirects');
484
+ const maxBodyLength = own('maxBodyLength');
485
+ const maxContentLength = own('maxContentLength');
486
+ const decompress = own('decompress');
448
487
  let isDone;
449
488
  let rejected = false;
450
489
  let req;
@@ -501,11 +540,13 @@ export default isHttpAdapterSupported &&
501
540
  }
502
541
 
503
542
  function createTimeoutError() {
504
- let timeoutErrorMessage = config.timeout
505
- ? 'timeout of ' + config.timeout + 'ms exceeded'
543
+ const configTimeout = own('timeout');
544
+ let timeoutErrorMessage = configTimeout
545
+ ? 'timeout of ' + configTimeout + 'ms exceeded'
506
546
  : 'timeout exceeded';
507
- if (config.timeoutErrorMessage) {
508
- timeoutErrorMessage = config.timeoutErrorMessage;
547
+ const configTimeoutErrorMessage = own('timeoutErrorMessage');
548
+ if (configTimeoutErrorMessage) {
549
+ timeoutErrorMessage = configTimeoutErrorMessage;
509
550
  }
510
551
  return new AxiosError(
511
552
  timeoutErrorMessage,
@@ -561,21 +602,21 @@ export default isHttpAdapterSupported &&
561
602
  });
562
603
 
563
604
  // Parse url
564
- const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
605
+ const fullPath = buildFullPath(own('baseURL'), own('url'), own('allowAbsoluteUrls'), config);
565
606
  const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
566
607
  const protocol = parsed.protocol || supportedProtocols[0];
567
608
 
568
609
  if (protocol === 'data:') {
569
610
  // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
570
- if (config.maxContentLength > -1) {
571
- // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.
572
- const dataUrl = String(config.url || fullPath || '');
611
+ if (maxContentLength > -1) {
612
+ // Use the exact string passed to fromDataURI (the configured url); fall back to fullPath if needed.
613
+ const dataUrl = String(own('url') || fullPath || '');
573
614
  const estimated = estimateDataURLDecodedBytes(dataUrl);
574
615
 
575
- if (estimated > config.maxContentLength) {
616
+ if (estimated > maxContentLength) {
576
617
  return reject(
577
618
  new AxiosError(
578
- 'maxContentLength size of ' + config.maxContentLength + ' exceeded',
619
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
579
620
  AxiosError.ERR_BAD_RESPONSE,
580
621
  config
581
622
  )
@@ -595,7 +636,7 @@ export default isHttpAdapterSupported &&
595
636
  }
596
637
 
597
638
  try {
598
- convertedData = fromDataURI(config.url, responseType === 'blob', {
639
+ convertedData = fromDataURI(own('url'), responseType === 'blob', {
599
640
  Blob: config.env && config.env.Blob,
600
641
  });
601
642
  } catch (err) {
@@ -695,7 +736,7 @@ export default isHttpAdapterSupported &&
695
736
  // Add Content-Length header if data exists
696
737
  headers.setContentLength(data.length, false);
697
738
 
698
- if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
739
+ if (maxBodyLength > -1 && data.length > maxBodyLength) {
699
740
  return reject(
700
741
  new AxiosError(
701
742
  'Request body larger than maxBodyLength limit',
@@ -747,8 +788,8 @@ export default isHttpAdapterSupported &&
747
788
  let auth = undefined;
748
789
  const configAuth = own('auth');
749
790
  if (configAuth) {
750
- const username = configAuth.username || '';
751
- const password = configAuth.password || '';
791
+ const username = utils.getSafeProp(configAuth, 'username') || '';
792
+ const password = utils.getSafeProp(configAuth, 'password') || '';
752
793
  auth = username + ':' + password;
753
794
  }
754
795
 
@@ -765,13 +806,13 @@ export default isHttpAdapterSupported &&
765
806
  try {
766
807
  path = buildURL(
767
808
  parsed.pathname + parsed.search,
768
- config.params,
769
- config.paramsSerializer
809
+ own('params'),
810
+ own('paramsSerializer')
770
811
  ).replace(/^\?/, '');
771
812
  } catch (err) {
772
813
  const customErr = new Error(err.message);
773
814
  customErr.config = config;
774
- customErr.url = config.url;
815
+ customErr.url = own('url');
775
816
  customErr.exists = true;
776
817
  return reject(customErr);
777
818
  }
@@ -789,7 +830,7 @@ export default isHttpAdapterSupported &&
789
830
  path,
790
831
  method: method,
791
832
  headers: toByteStringHeaderObject(headers),
792
- agents: { http: config.httpAgent, https: config.httpsAgent },
833
+ agents: { http: httpAgent, https: httpsAgent },
793
834
  auth,
794
835
  protocol,
795
836
  family,
@@ -839,19 +880,24 @@ export default isHttpAdapterSupported &&
839
880
  options.port = parsed.port;
840
881
  setProxy(
841
882
  options,
842
- config.proxy,
883
+ own('proxy'),
843
884
  protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path,
844
885
  false,
845
- config.httpsAgent
886
+ httpsAgent
846
887
  );
847
888
  }
848
889
  let transport;
849
890
  let isNativeTransport = false;
891
+ // True only for the follow-redirects transport, which applies
892
+ // options.maxBodyLength itself. Every other transport (http2, native
893
+ // http/https, a user-supplied custom transport) needs the explicit
894
+ // byte-counting pipeline below to enforce maxBodyLength on streamed uploads.
895
+ let transportEnforcesMaxBodyLength = false;
850
896
  const isHttpsRequest = isHttps.test(options.protocol);
851
897
  // Don't clobber a CONNECT-tunneling agent installed by setProxy() for an
852
898
  // HTTPS target.
853
899
  if (options.agent == null) {
854
- options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
900
+ options.agent = isHttpsRequest ? httpsAgent : httpAgent;
855
901
  }
856
902
 
857
903
  if (isHttp2) {
@@ -860,12 +906,14 @@ export default isHttpAdapterSupported &&
860
906
  const configTransport = own('transport');
861
907
  if (configTransport) {
862
908
  transport = configTransport;
863
- } else if (config.maxRedirects === 0) {
909
+ } else if (maxRedirects === 0) {
864
910
  transport = isHttpsRequest ? https : http;
865
911
  isNativeTransport = true;
866
912
  } else {
867
- if (config.maxRedirects) {
868
- options.maxRedirects = config.maxRedirects;
913
+ transportEnforcesMaxBodyLength = true;
914
+ options.sensitiveHeaders = [];
915
+ if (maxRedirects) {
916
+ options.maxRedirects = maxRedirects;
869
917
  }
870
918
  const configBeforeRedirect = own('beforeRedirect');
871
919
  if (configBeforeRedirect) {
@@ -888,12 +936,51 @@ export default isHttpAdapterSupported &&
888
936
  }
889
937
  };
890
938
  }
939
+ const sensitiveHeaders = own('sensitiveHeaders');
940
+ if (sensitiveHeaders != null) {
941
+ if (!utils.isArray(sensitiveHeaders)) {
942
+ return reject(
943
+ new AxiosError(
944
+ 'sensitiveHeaders must be an array of strings',
945
+ AxiosError.ERR_BAD_OPTION_VALUE,
946
+ config
947
+ )
948
+ );
949
+ }
950
+
951
+ const sensitiveSet = new Set();
952
+ for (const header of sensitiveHeaders) {
953
+ if (!utils.isString(header)) {
954
+ return reject(
955
+ new AxiosError(
956
+ 'sensitiveHeaders must be an array of strings',
957
+ AxiosError.ERR_BAD_OPTION_VALUE,
958
+ config
959
+ )
960
+ );
961
+ }
962
+
963
+ sensitiveSet.add(header.toLowerCase());
964
+ }
965
+
966
+ if (sensitiveSet.size) {
967
+ options.sensitiveHeaders = Array.from(sensitiveSet);
968
+ options.beforeRedirects.sensitiveHeaders = function beforeRedirectSensitiveHeaders(
969
+ redirectOptions,
970
+ requestDetails
971
+ ) {
972
+ if (!isSameOriginRedirect(redirectOptions, requestDetails)) {
973
+ stripMatchingHeaders(redirectOptions.headers, sensitiveSet);
974
+ }
975
+ };
976
+ }
977
+ }
891
978
  transport = isHttpsRequest ? httpsFollow : httpFollow;
892
979
  }
893
980
  }
894
981
 
895
- if (config.maxBodyLength > -1) {
896
- options.maxBodyLength = config.maxBodyLength;
982
+ if (maxBodyLength > -1) {
983
+ options.maxBodyLength = maxBodyLength;
897
984
  } else {
898
985
  // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
899
986
  options.maxBodyLength = Infinity;
@@ -941,7 +1028,7 @@ export default isHttpAdapterSupported &&
941
1028
  const lastRequest = res.req || req;
942
1029
 
943
1030
  // if decompress disabled we should not decompress
944
- if (config.decompress !== false && res.headers['content-encoding']) {
1031
+ if (decompress !== false && res.headers['content-encoding']) {
945
1032
  // if no content, but headers still say that it is encoded,
946
1033
  // remove the header not confuse downstream operations
947
1034
  if (method === 'HEAD' || res.statusCode === 204) {
@@ -997,8 +1084,8 @@ export default isHttpAdapterSupported &&
997
1084
  if (responseType === 'stream') {
998
1085
  // Enforce maxContentLength on streamed responses; previously this
999
1086
  // was applied only to buffered responses.
1000
- if (config.maxContentLength > -1) {
1001
- const limit = config.maxContentLength;
1087
+ if (maxContentLength > -1) {
1088
+ const limit = maxContentLength;
1002
1089
  const source = responseStream;
1003
1090
  async function* enforceMaxContentLength() {
1004
1091
  let totalResponseBytes = 0;
@@ -1030,13 +1117,13 @@ export default isHttpAdapterSupported &&
1030
1117
  totalResponseBytes += chunk.length;
1031
1118
 
1032
1119
  // make sure the content length is not over the maxContentLength if specified
1033
- if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
1120
+ if (maxContentLength > -1 && totalResponseBytes > maxContentLength) {
1034
1121
  // stream.destroy() emit aborted event before calling reject() on Node.js v16
1035
1122
  rejected = true;
1036
1123
  responseStream.destroy();
1037
1124
  abort(
1038
1125
  new AxiosError(
1039
- 'maxContentLength size of ' + config.maxContentLength + ' exceeded',
1126
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
1040
1127
  AxiosError.ERR_BAD_RESPONSE,
1041
1128
  config,
1042
1129
  lastRequest
@@ -1151,9 +1238,9 @@ export default isHttpAdapterSupported &&
1151
1238
  });
1152
1239
 
1153
1240
  // Handle request timeout
1154
- if (config.timeout) {
1241
+ if (own('timeout')) {
1155
1242
  // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
1156
- const timeout = parseInt(config.timeout, 10);
1243
+ const timeout = parseInt(own('timeout'), 10);
1157
1244
 
1158
1245
  if (Number.isNaN(timeout)) {
1159
1246
  abort(
@@ -1211,12 +1298,13 @@ export default isHttpAdapterSupported &&
1211
1298
  }
1212
1299
  });
1213
1300
 
1214
- // Enforce maxBodyLength for streamed uploads on the native http/https
1215
- // transport (maxRedirects === 0); follow-redirects enforces it on the
1216
- // other path.
1301
+ // Enforce maxBodyLength for streamed uploads on every transport that
1302
+ // does not apply options.maxBodyLength itself (native http/https, http2,
1303
+ // and user-supplied custom transports). The follow-redirects transport
1304
+ // enforces it on the redirected HTTP/1 path.
1217
1305
  let uploadStream = data;
1218
- if (config.maxBodyLength > -1 && config.maxRedirects === 0) {
1219
- const limit = config.maxBodyLength;
1306
+ if (maxBodyLength > -1 && !transportEnforcesMaxBodyLength) {
1307
+ const limit = maxBodyLength;
1220
1308
  let bytesSent = 0;
1221
1309
  uploadStream = stream.pipeline(
1222
1310
  [
@@ -1254,3 +1342,4 @@ export default isHttpAdapterSupported &&
1254
1342
  };
1255
1343
 
1256
1344
  export const __setProxy = setProxy;
1345
+ export const __isSameOriginRedirect = isSameOriginRedirect;
@@ -102,6 +102,7 @@ class Axios {
102
102
  clarifyTimeoutError: validators.transitional(validators.boolean),
103
103
  legacyInterceptorReqResOrdering: validators.transitional(validators.boolean),
104
104
  advertiseZstdAcceptEncoding: validators.transitional(validators.boolean),
105
+ validateStatusUndefinedResolves: validators.transitional(validators.boolean),
105
106
  },
106
107
  false
107
108
  );
@@ -233,7 +234,7 @@ class Axios {
233
234
 
234
235
  getUri(config) {
235
236
  config = mergeConfig(this.defaults, config);
236
- const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
237
+ const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls, config);
237
238
  return buildURL(fullPath, config.params, config.paramsSerializer);
238
239
  }
239
240
  }
@@ -246,7 +247,7 @@ utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData
246
247
  mergeConfig(config || {}, {
247
248
  method,
248
249
  url,
249
- data: (config || {}).data,
250
+ data: config && utils.hasOwnProp(config, 'data') ? config.data : undefined,
250
251
  })
251
252
  );
252
253
  };
@@ -111,8 +111,8 @@ class AxiosHeaders {
111
111
  setHeaders(header, valueOrRewrite);
112
112
  } else if (utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
113
113
  setHeaders(parseHeaders(header), valueOrRewrite);
114
- } else if (utils.isObject(header) && utils.isIterable(header)) {
115
- let obj = {},
114
+ } else if (utils.isObject(header) && utils.isSafeIterable(header)) {
115
+ let obj = Object.create(null),
116
116
  dest,
117
117
  key;
118
118
  for (const entry of header) {
@@ -120,11 +120,14 @@ class AxiosHeaders {
120
120
  throw new TypeError('Object iterator must return a key-value pair');
121
121
  }
122
122
 
123
- obj[(key = entry[0])] = (dest = obj[key])
124
- ? utils.isArray(dest)
125
- ? [...dest, entry[1]]
126
- : [dest, entry[1]]
127
- : entry[1];
123
+ key = entry[0];
124
+
125
+ if (utils.hasOwnProp(obj, key)) {
126
+ dest = obj[key];
127
+ obj[key] = utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]];
128
+ } else {
129
+ obj[key] = entry[1];
130
+ }
128
131
  }
129
132
 
130
133
  setHeaders(obj, valueOrRewrite);