agent-relay 4.0.30 → 4.0.31

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 (137) hide show
  1. package/README.md +88 -48
  2. package/bin/agent-relay-broker-darwin-arm64 +0 -0
  3. package/bin/agent-relay-broker-darwin-x64 +0 -0
  4. package/bin/agent-relay-broker-linux-arm64 +0 -0
  5. package/bin/agent-relay-broker-linux-x64 +0 -0
  6. package/dist/index.cjs +99 -54
  7. package/dist/src/cli/bootstrap.d.ts +2 -1
  8. package/dist/src/cli/bootstrap.d.ts.map +1 -1
  9. package/dist/src/cli/bootstrap.js +223 -17
  10. package/dist/src/cli/bootstrap.js.map +1 -1
  11. package/dist/src/cli/commands/agent-management.d.ts.map +1 -1
  12. package/dist/src/cli/commands/agent-management.js +1 -3
  13. package/dist/src/cli/commands/agent-management.js.map +1 -1
  14. package/dist/src/cli/commands/auth.d.ts.map +1 -1
  15. package/dist/src/cli/commands/auth.js +32 -3
  16. package/dist/src/cli/commands/auth.js.map +1 -1
  17. package/dist/src/cli/commands/cloud.d.ts.map +1 -1
  18. package/dist/src/cli/commands/cloud.js +242 -144
  19. package/dist/src/cli/commands/cloud.js.map +1 -1
  20. package/dist/src/cli/commands/core.d.ts.map +1 -1
  21. package/dist/src/cli/commands/core.js +11 -6
  22. package/dist/src/cli/commands/core.js.map +1 -1
  23. package/dist/src/cli/commands/messaging.d.ts.map +1 -1
  24. package/dist/src/cli/commands/messaging.js +1 -3
  25. package/dist/src/cli/commands/messaging.js.map +1 -1
  26. package/dist/src/cli/commands/monitoring.d.ts.map +1 -1
  27. package/dist/src/cli/commands/monitoring.js +5 -4
  28. package/dist/src/cli/commands/monitoring.js.map +1 -1
  29. package/dist/src/cli/commands/on.d.ts.map +1 -1
  30. package/dist/src/cli/commands/on.js +1 -3
  31. package/dist/src/cli/commands/on.js.map +1 -1
  32. package/dist/src/cli/commands/setup.d.ts.map +1 -1
  33. package/dist/src/cli/commands/setup.js +62 -7
  34. package/dist/src/cli/commands/setup.js.map +1 -1
  35. package/dist/src/cli/commands/swarm.d.ts.map +1 -1
  36. package/dist/src/cli/commands/swarm.js +34 -4
  37. package/dist/src/cli/commands/swarm.js.map +1 -1
  38. package/dist/src/cli/index.js +9 -1
  39. package/dist/src/cli/index.js.map +1 -1
  40. package/dist/src/cli/lib/exit.d.ts +49 -0
  41. package/dist/src/cli/lib/exit.d.ts.map +1 -0
  42. package/dist/src/cli/lib/exit.js +73 -0
  43. package/dist/src/cli/lib/exit.js.map +1 -0
  44. package/dist/src/cli/lib/telemetry-helpers.d.ts +20 -0
  45. package/dist/src/cli/lib/telemetry-helpers.d.ts.map +1 -0
  46. package/dist/src/cli/lib/telemetry-helpers.js +31 -0
  47. package/dist/src/cli/lib/telemetry-helpers.js.map +1 -0
  48. package/node_modules/@agent-relay/cloud/package.json +2 -2
  49. package/node_modules/@agent-relay/config/package.json +1 -1
  50. package/node_modules/@agent-relay/hooks/package.json +4 -4
  51. package/node_modules/@agent-relay/sdk/dist/workflows/file-db.d.ts +62 -12
  52. package/node_modules/@agent-relay/sdk/dist/workflows/file-db.d.ts.map +1 -1
  53. package/node_modules/@agent-relay/sdk/dist/workflows/file-db.js +137 -47
  54. package/node_modules/@agent-relay/sdk/dist/workflows/file-db.js.map +1 -1
  55. package/node_modules/@agent-relay/sdk/package.json +2 -2
  56. package/node_modules/@agent-relay/telemetry/dist/client.d.ts +14 -2
  57. package/node_modules/@agent-relay/telemetry/dist/client.d.ts.map +1 -1
  58. package/node_modules/@agent-relay/telemetry/dist/client.js +22 -4
  59. package/node_modules/@agent-relay/telemetry/dist/client.js.map +1 -1
  60. package/node_modules/@agent-relay/telemetry/dist/events.d.ts +217 -10
  61. package/node_modules/@agent-relay/telemetry/dist/events.d.ts.map +1 -1
  62. package/node_modules/@agent-relay/telemetry/dist/events.js +11 -0
  63. package/node_modules/@agent-relay/telemetry/dist/events.js.map +1 -1
  64. package/node_modules/@agent-relay/telemetry/dist/index.d.ts +2 -2
  65. package/node_modules/@agent-relay/telemetry/dist/index.d.ts.map +1 -1
  66. package/node_modules/@agent-relay/telemetry/dist/index.js.map +1 -1
  67. package/node_modules/@agent-relay/telemetry/package.json +2 -2
  68. package/node_modules/@agent-relay/trajectory/package.json +2 -2
  69. package/node_modules/@agent-relay/user-directory/package.json +2 -2
  70. package/node_modules/@agent-relay/utils/package.json +2 -2
  71. package/node_modules/@relaycast/sdk/dist/version.d.ts +1 -1
  72. package/node_modules/@relaycast/sdk/dist/version.js +1 -1
  73. package/node_modules/@relaycast/sdk/node_modules/@relaycast/types/package.json +1 -1
  74. package/node_modules/@relaycast/sdk/package.json +2 -2
  75. package/node_modules/axios/CHANGELOG.md +166 -0
  76. package/node_modules/axios/README.md +210 -204
  77. package/node_modules/axios/dist/axios.js +92 -63
  78. package/node_modules/axios/dist/axios.js.map +1 -1
  79. package/node_modules/axios/dist/axios.min.js +2 -2
  80. package/node_modules/axios/dist/axios.min.js.map +1 -1
  81. package/node_modules/axios/dist/browser/axios.cjs +140 -101
  82. package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
  83. package/node_modules/axios/dist/esm/axios.js +140 -101
  84. package/node_modules/axios/dist/esm/axios.js.map +1 -1
  85. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  86. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  87. package/node_modules/axios/dist/node/axios.cjs +199 -75
  88. package/node_modules/axios/dist/node/axios.cjs.map +1 -1
  89. package/node_modules/axios/index.d.cts +14 -28
  90. package/node_modules/axios/index.d.ts +132 -226
  91. package/node_modules/axios/lib/adapters/fetch.js +21 -6
  92. package/node_modules/axios/lib/adapters/http.js +88 -6
  93. package/node_modules/axios/lib/core/AxiosError.js +34 -33
  94. package/node_modules/axios/lib/core/AxiosHeaders.js +24 -25
  95. package/node_modules/axios/lib/core/buildFullPath.js +1 -1
  96. package/node_modules/axios/lib/core/mergeConfig.js +5 -3
  97. package/node_modules/axios/lib/defaults/index.js +13 -8
  98. package/node_modules/axios/lib/env/data.js +1 -1
  99. package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -2
  100. package/node_modules/axios/lib/helpers/formDataToJSON.js +3 -1
  101. package/node_modules/axios/lib/helpers/formDataToStream.js +2 -1
  102. package/node_modules/axios/lib/helpers/progressEventReducer.js +5 -5
  103. package/node_modules/axios/lib/helpers/resolveConfig.js +11 -3
  104. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +48 -1
  105. package/node_modules/axios/lib/helpers/toFormData.js +10 -2
  106. package/node_modules/axios/lib/utils.js +10 -10
  107. package/node_modules/axios/package.json +4 -4
  108. package/package.json +9 -9
  109. package/packages/cloud/package.json +2 -2
  110. package/packages/config/package.json +1 -1
  111. package/packages/hooks/package.json +4 -4
  112. package/packages/sdk/dist/workflows/file-db.d.ts +62 -12
  113. package/packages/sdk/dist/workflows/file-db.d.ts.map +1 -1
  114. package/packages/sdk/dist/workflows/file-db.js +137 -47
  115. package/packages/sdk/dist/workflows/file-db.js.map +1 -1
  116. package/packages/sdk/package.json +2 -2
  117. package/packages/telemetry/dist/client.d.ts +14 -2
  118. package/packages/telemetry/dist/client.d.ts.map +1 -1
  119. package/packages/telemetry/dist/client.js +22 -4
  120. package/packages/telemetry/dist/client.js.map +1 -1
  121. package/packages/telemetry/dist/events.d.ts +217 -10
  122. package/packages/telemetry/dist/events.d.ts.map +1 -1
  123. package/packages/telemetry/dist/events.js +11 -0
  124. package/packages/telemetry/dist/events.js.map +1 -1
  125. package/packages/telemetry/dist/index.d.ts +2 -2
  126. package/packages/telemetry/dist/index.d.ts.map +1 -1
  127. package/packages/telemetry/dist/index.js.map +1 -1
  128. package/packages/telemetry/package.json +2 -2
  129. package/packages/trajectory/package.json +2 -2
  130. package/packages/user-directory/package.json +2 -2
  131. package/packages/utils/package.json +2 -2
  132. package/node_modules/@clack/prompts/node_modules/is-unicode-supported/index.d.ts +0 -12
  133. package/node_modules/@clack/prompts/node_modules/is-unicode-supported/index.js +0 -17
  134. package/node_modules/@clack/prompts/node_modules/is-unicode-supported/license +0 -9
  135. package/node_modules/@clack/prompts/node_modules/is-unicode-supported/package.json +0 -43
  136. package/node_modules/@clack/prompts/node_modules/is-unicode-supported/readme.md +0 -35
  137. package/node_modules/color-convert/CHANGELOG.md +0 -54
@@ -333,8 +333,15 @@ const http2Transport = {
333
333
  export default isHttpAdapterSupported &&
334
334
  function httpAdapter(config) {
335
335
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
336
- let { data, lookup, family, httpVersion = 1, http2Options } = config;
337
- const { responseType, responseEncoding } = config;
336
+ const own = (key) => (utils.hasOwnProp(config, key) ? config[key] : undefined);
337
+ let data = own('data');
338
+ let lookup = own('lookup');
339
+ let family = own('family');
340
+ let httpVersion = own('httpVersion');
341
+ if (httpVersion === undefined) httpVersion = 1;
342
+ let http2Options = own('http2Options');
343
+ const responseType = own('responseType');
344
+ const responseEncoding = own('responseEncoding');
338
345
  const method = config.method.toUpperCase();
339
346
  let isDone;
340
347
  let rejected = false;
@@ -520,7 +527,8 @@ export default isHttpAdapterSupported &&
520
527
  }
521
528
  );
522
529
  // support for https://www.npmjs.com/package/form-data api
523
- } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {
530
+ } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders) &&
531
+ data.getHeaders !== Object.prototype.getHeaders) {
524
532
  headers.set(data.getHeaders());
525
533
 
526
534
  if (!headers.hasContentLength()) {
@@ -678,8 +686,9 @@ export default isHttpAdapterSupported &&
678
686
  if (isHttp2) {
679
687
  transport = http2Transport;
680
688
  } else {
681
- if (config.transport) {
682
- transport = config.transport;
689
+ const configTransport = own('transport');
690
+ if (configTransport) {
691
+ transport = configTransport;
683
692
  } else if (config.maxRedirects === 0) {
684
693
  transport = isHttpsRequest ? https : http;
685
694
  } else {
@@ -786,6 +795,30 @@ export default isHttpAdapterSupported &&
786
795
  };
787
796
 
788
797
  if (responseType === 'stream') {
798
+ // Enforce maxContentLength on streamed responses; previously this
799
+ // was applied only to buffered responses. See GHSA-vf2m-468p-8v99.
800
+ if (config.maxContentLength > -1) {
801
+ const limit = config.maxContentLength;
802
+ const source = responseStream;
803
+ async function* enforceMaxContentLength() {
804
+ let totalResponseBytes = 0;
805
+ for await (const chunk of source) {
806
+ totalResponseBytes += chunk.length;
807
+ if (totalResponseBytes > limit) {
808
+ throw new AxiosError(
809
+ 'maxContentLength size of ' + limit + ' exceeded',
810
+ AxiosError.ERR_BAD_RESPONSE,
811
+ config,
812
+ lastRequest
813
+ );
814
+ }
815
+ yield chunk;
816
+ }
817
+ }
818
+ responseStream = stream.Readable.from(enforceMaxContentLength(), {
819
+ objectMode: false,
820
+ });
821
+ }
789
822
  response.data = responseStream;
790
823
  settle(resolve, reject, response);
791
824
  } else {
@@ -875,6 +908,21 @@ export default isHttpAdapterSupported &&
875
908
  req.on('socket', function handleRequestSocket(socket) {
876
909
  // default interval of sending ack packet is 1 minute
877
910
  socket.setKeepAlive(true, 1000 * 60);
911
+
912
+ const removeSocketErrorListener = () => {
913
+ socket.removeListener('error', handleRequestSocketError);
914
+ };
915
+
916
+ function handleRequestSocketError(err) {
917
+ removeSocketErrorListener();
918
+
919
+ if (!req.destroyed) {
920
+ req.destroy(err);
921
+ }
922
+ }
923
+
924
+ socket.on('error', handleRequestSocketError);
925
+ req.once('close', removeSocketErrorListener);
878
926
  });
879
927
 
880
928
  // Handle request timeout
@@ -943,7 +991,41 @@ export default isHttpAdapterSupported &&
943
991
  }
944
992
  });
945
993
 
946
- data.pipe(req);
994
+ // Enforce maxBodyLength for streamed uploads on the native http/https
995
+ // transport (maxRedirects === 0); follow-redirects enforces it on the
996
+ // other path. See GHSA-5c9x-8gcm-mpgx.
997
+ let uploadStream = data;
998
+ if (config.maxBodyLength > -1 && config.maxRedirects === 0) {
999
+ const limit = config.maxBodyLength;
1000
+ let bytesSent = 0;
1001
+ uploadStream = stream.pipeline(
1002
+ [
1003
+ data,
1004
+ new stream.Transform({
1005
+ transform(chunk, _enc, cb) {
1006
+ bytesSent += chunk.length;
1007
+ if (bytesSent > limit) {
1008
+ return cb(
1009
+ new AxiosError(
1010
+ 'Request body larger than maxBodyLength limit',
1011
+ AxiosError.ERR_BAD_REQUEST,
1012
+ config,
1013
+ req
1014
+ )
1015
+ );
1016
+ }
1017
+ cb(null, chunk);
1018
+ },
1019
+ }),
1020
+ ],
1021
+ utils.noop
1022
+ );
1023
+ uploadStream.on('error', (err) => {
1024
+ if (!req.destroyed) req.destroy(err);
1025
+ });
1026
+ }
1027
+
1028
+ uploadStream.pipe(req);
947
1029
  } else {
948
1030
  data && req.write(data);
949
1031
  req.end();
@@ -17,40 +17,40 @@ class AxiosError extends Error {
17
17
  return axiosError;
18
18
  }
19
19
 
20
- /**
21
- * Create an Error with the specified message, config, error code, request and response.
22
- *
23
- * @param {string} message The error message.
24
- * @param {string} [code] The error code (for example, 'ECONNABORTED').
25
- * @param {Object} [config] The config.
26
- * @param {Object} [request] The request.
27
- * @param {Object} [response] The response.
28
- *
29
- * @returns {Error} The created error.
30
- */
31
- constructor(message, code, config, request, response) {
32
- super(message);
33
-
34
- // Make message enumerable to maintain backward compatibility
35
- // The native Error constructor sets message as non-enumerable,
36
- // but axios < v1.13.3 had it as enumerable
37
- Object.defineProperty(this, 'message', {
38
- value: message,
39
- enumerable: true,
40
- writable: true,
41
- configurable: true
42
- });
43
-
44
- this.name = 'AxiosError';
45
- this.isAxiosError = true;
46
- code && (this.code = code);
47
- config && (this.config = config);
48
- request && (this.request = request);
49
- if (response) {
50
- this.response = response;
51
- this.status = response.status;
52
- }
20
+ /**
21
+ * Create an Error with the specified message, config, error code, request and response.
22
+ *
23
+ * @param {string} message The error message.
24
+ * @param {string} [code] The error code (for example, 'ECONNABORTED').
25
+ * @param {Object} [config] The config.
26
+ * @param {Object} [request] The request.
27
+ * @param {Object} [response] The response.
28
+ *
29
+ * @returns {Error} The created error.
30
+ */
31
+ constructor(message, code, config, request, response) {
32
+ super(message);
33
+
34
+ // Make message enumerable to maintain backward compatibility
35
+ // The native Error constructor sets message as non-enumerable,
36
+ // but axios < v1.13.3 had it as enumerable
37
+ Object.defineProperty(this, 'message', {
38
+ value: message,
39
+ enumerable: true,
40
+ writable: true,
41
+ configurable: true,
42
+ });
43
+
44
+ this.name = 'AxiosError';
45
+ this.isAxiosError = true;
46
+ code && (this.code = code);
47
+ config && (this.config = config);
48
+ request && (this.request = request);
49
+ if (response) {
50
+ this.response = response;
51
+ this.status = response.status;
53
52
  }
53
+ }
54
54
 
55
55
  toJSON() {
56
56
  return {
@@ -86,5 +86,6 @@ AxiosError.ERR_BAD_REQUEST = 'ERR_BAD_REQUEST';
86
86
  AxiosError.ERR_CANCELED = 'ERR_CANCELED';
87
87
  AxiosError.ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT';
88
88
  AxiosError.ERR_INVALID_URL = 'ERR_INVALID_URL';
89
+ AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED';
89
90
 
90
91
  export default AxiosError;
@@ -5,41 +5,41 @@ import parseHeaders from '../helpers/parseHeaders.js';
5
5
 
6
6
  const $internals = Symbol('internals');
7
7
 
8
- const isValidHeaderValue = (value) => !/[\r\n]/.test(value);
8
+ const INVALID_HEADER_VALUE_CHARS_RE = /[^\x09\x20-\x7E\x80-\xFF]/g;
9
9
 
10
- function assertValidHeaderValue(value, header) {
11
- if (value === false || value == null) {
12
- return;
13
- }
14
-
15
- if (utils.isArray(value)) {
16
- value.forEach((v) => assertValidHeaderValue(v, header));
17
- return;
18
- }
10
+ function trimSPorHTAB(str) {
11
+ let start = 0;
12
+ let end = str.length;
19
13
 
20
- if (!isValidHeaderValue(String(value))) {
21
- throw new Error(`Invalid character in header content ["${header}"]`);
22
- }
23
- }
14
+ while (start < end) {
15
+ const code = str.charCodeAt(start);
24
16
 
25
- function normalizeHeader(header) {
26
- return header && String(header).trim().toLowerCase();
27
- }
17
+ if (code !== 0x09 && code !== 0x20) {
18
+ break;
19
+ }
28
20
 
29
- function stripTrailingCRLF(str) {
30
- let end = str.length;
21
+ start += 1;
22
+ }
31
23
 
32
- while (end > 0) {
33
- const charCode = str.charCodeAt(end - 1);
24
+ while (end > start) {
25
+ const code = str.charCodeAt(end - 1);
34
26
 
35
- if (charCode !== 10 && charCode !== 13) {
27
+ if (code !== 0x09 && code !== 0x20) {
36
28
  break;
37
29
  }
38
30
 
39
31
  end -= 1;
40
32
  }
41
33
 
42
- return end === str.length ? str : str.slice(0, end);
34
+ return start === 0 && end === str.length ? str : str.slice(start, end);
35
+ }
36
+
37
+ function normalizeHeader(header) {
38
+ return header && String(header).trim().toLowerCase();
39
+ }
40
+
41
+ function sanitizeHeaderValue(str) {
42
+ return trimSPorHTAB(str.replace(INVALID_HEADER_VALUE_CHARS_RE, ''));
43
43
  }
44
44
 
45
45
  function normalizeValue(value) {
@@ -47,7 +47,7 @@ function normalizeValue(value) {
47
47
  return value;
48
48
  }
49
49
 
50
- return utils.isArray(value) ? value.map(normalizeValue) : stripTrailingCRLF(String(value));
50
+ return utils.isArray(value) ? value.map(normalizeValue) : sanitizeHeaderValue(String(value));
51
51
  }
52
52
 
53
53
  function parseTokens(str) {
@@ -129,7 +129,6 @@ class AxiosHeaders {
129
129
  _rewrite === true ||
130
130
  (_rewrite === undefined && self[key] !== false)
131
131
  ) {
132
- assertValidHeaderValue(_value, _header);
133
132
  self[key || _header] = normalizeValue(_value);
134
133
  }
135
134
  }
@@ -15,7 +15,7 @@ import combineURLs from '../helpers/combineURLs.js';
15
15
  */
16
16
  export default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
17
17
  let isRelativeUrl = !isAbsoluteURL(requestedURL);
18
- if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {
18
+ if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) {
19
19
  return combineURLs(baseURL, requestedURL);
20
20
  }
21
21
  return requestedURL;
@@ -56,9 +56,9 @@ export default function mergeConfig(config1, config2) {
56
56
 
57
57
  // eslint-disable-next-line consistent-return
58
58
  function mergeDirectKeys(a, b, prop) {
59
- if (prop in config2) {
59
+ if (utils.hasOwnProp(config2, prop)) {
60
60
  return getMergedValue(a, b);
61
- } else if (prop in config1) {
61
+ } else if (utils.hasOwnProp(config1, prop)) {
62
62
  return getMergedValue(undefined, a);
63
63
  }
64
64
  }
@@ -99,7 +99,9 @@ export default function mergeConfig(config1, config2) {
99
99
  utils.forEach(Object.keys({ ...config1, ...config2 }), function computeConfigValue(prop) {
100
100
  if (prop === '__proto__' || prop === 'constructor' || prop === 'prototype') return;
101
101
  const merge = utils.hasOwnProp(mergeMap, prop) ? mergeMap[prop] : mergeDeepProperties;
102
- const configValue = merge(config1[prop], config2[prop], prop);
102
+ const a = utils.hasOwnProp(config1, prop) ? config1[prop] : undefined;
103
+ const b = utils.hasOwnProp(config2, prop) ? config2[prop] : undefined;
104
+ const configValue = merge(a, b, prop);
103
105
  (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
104
106
  });
105
107
 
@@ -8,6 +8,8 @@ import toURLEncodedForm from '../helpers/toURLEncodedForm.js';
8
8
  import platform from '../platform/index.js';
9
9
  import formDataToJSON from '../helpers/formDataToJSON.js';
10
10
 
11
+ const own = (obj, key) => (obj != null && utils.hasOwnProp(obj, key) ? obj[key] : undefined);
12
+
11
13
  /**
12
14
  * It takes a string, tries to parse it, and if it fails, it returns the stringified version
13
15
  * of the input
@@ -75,20 +77,22 @@ const defaults = {
75
77
  let isFileList;
76
78
 
77
79
  if (isObjectPayload) {
80
+ const formSerializer = own(this, 'formSerializer');
78
81
  if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {
79
- return toURLEncodedForm(data, this.formSerializer).toString();
82
+ return toURLEncodedForm(data, formSerializer).toString();
80
83
  }
81
84
 
82
85
  if (
83
86
  (isFileList = utils.isFileList(data)) ||
84
87
  contentType.indexOf('multipart/form-data') > -1
85
88
  ) {
86
- const _FormData = this.env && this.env.FormData;
89
+ const env = own(this, 'env');
90
+ const _FormData = env && env.FormData;
87
91
 
88
92
  return toFormData(
89
93
  isFileList ? { 'files[]': data } : data,
90
94
  _FormData && new _FormData(),
91
- this.formSerializer
95
+ formSerializer
92
96
  );
93
97
  }
94
98
  }
@@ -104,9 +108,10 @@ const defaults = {
104
108
 
105
109
  transformResponse: [
106
110
  function transformResponse(data) {
107
- const transitional = this.transitional || defaults.transitional;
111
+ const transitional = own(this, 'transitional') || defaults.transitional;
108
112
  const forcedJSONParsing = transitional && transitional.forcedJSONParsing;
109
- const JSONRequested = this.responseType === 'json';
113
+ const responseType = own(this, 'responseType');
114
+ const JSONRequested = responseType === 'json';
110
115
 
111
116
  if (utils.isResponse(data) || utils.isReadableStream(data)) {
112
117
  return data;
@@ -115,17 +120,17 @@ const defaults = {
115
120
  if (
116
121
  data &&
117
122
  utils.isString(data) &&
118
- ((forcedJSONParsing && !this.responseType) || JSONRequested)
123
+ ((forcedJSONParsing && !responseType) || JSONRequested)
119
124
  ) {
120
125
  const silentJSONParsing = transitional && transitional.silentJSONParsing;
121
126
  const strictJSONParsing = !silentJSONParsing && JSONRequested;
122
127
 
123
128
  try {
124
- return JSON.parse(data, this.parseReviver);
129
+ return JSON.parse(data, own(this, 'parseReviver'));
125
130
  } catch (e) {
126
131
  if (strictJSONParsing) {
127
132
  if (e.name === 'SyntaxError') {
128
- throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);
133
+ throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, own(this, 'response'));
129
134
  }
130
135
  throw e;
131
136
  }
@@ -1 +1 @@
1
- export const VERSION = "1.15.0";
1
+ export const VERSION = "1.15.1";
@@ -18,9 +18,8 @@ function encode(str) {
18
18
  ')': '%29',
19
19
  '~': '%7E',
20
20
  '%20': '+',
21
- '%00': '\x00',
22
21
  };
23
- return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {
22
+ return encodeURIComponent(str).replace(/[!'()~]|%20/g, function replacer(match) {
24
23
  return charMap[match];
25
24
  });
26
25
  }
@@ -58,7 +58,9 @@ function formDataToJSON(formData) {
58
58
 
59
59
  if (isLast) {
60
60
  if (utils.hasOwnProp(target, name)) {
61
- target[name] = [target[name], value];
61
+ target[name] = utils.isArray(target[name])
62
+ ? target[name].concat(value)
63
+ : [target[name], value];
62
64
  } else {
63
65
  target[name] = value;
64
66
  }
@@ -24,7 +24,8 @@ class FormDataPart {
24
24
  if (isStringValue) {
25
25
  value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF));
26
26
  } else {
27
- headers += `Content-Type: ${value.type || 'application/octet-stream'}${CRLF}`;
27
+ const safeType = String(value.type || 'application/octet-stream').replace(/[\r\n]/g, '');
28
+ headers += `Content-Type: ${safeType}${CRLF}`;
28
29
  }
29
30
 
30
31
  this.headers = textEncoder.encode(headers + CRLF);
@@ -7,13 +7,13 @@ export const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
7
7
  const _speedometer = speedometer(50, 250);
8
8
 
9
9
  return throttle((e) => {
10
- const loaded = e.loaded;
10
+ const rawLoaded = e.loaded;
11
11
  const total = e.lengthComputable ? e.total : undefined;
12
- const progressBytes = loaded - bytesNotified;
12
+ const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;
13
+ const progressBytes = Math.max(0, loaded - bytesNotified);
13
14
  const rate = _speedometer(progressBytes);
14
- const inRange = loaded <= total;
15
15
 
16
- bytesNotified = loaded;
16
+ bytesNotified = Math.max(bytesNotified, loaded);
17
17
 
18
18
  const data = {
19
19
  loaded,
@@ -21,7 +21,7 @@ export const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
21
21
  progress: total ? loaded / total : undefined,
22
22
  bytes: progressBytes,
23
23
  rate: rate ? rate : undefined,
24
- estimated: rate && total && inRange ? (total - loaded) / rate : undefined,
24
+ estimated: rate && total ? (total - loaded) / rate : undefined,
25
25
  event: e,
26
26
  lengthComputable: total != null,
27
27
  [isDownloadStream ? 'download' : 'upload']: true,
@@ -54,10 +54,18 @@ export default (config) => {
54
54
  // Specifically not if we're in a web worker, or react-native.
55
55
 
56
56
  if (platform.hasStandardBrowserEnv) {
57
- withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));
57
+ if (utils.isFunction(withXSRFToken)) {
58
+ withXSRFToken = withXSRFToken(newConfig);
59
+ }
60
+
61
+ // Strict boolean check — prevents proto-pollution gadgets (e.g. Object.prototype.withXSRFToken = 1)
62
+ // and misconfigurations (e.g. "false") from short-circuiting the same-origin check and leaking
63
+ // the XSRF token cross-origin. See GHSA-xx6v-rp6x-q39c.
64
+ const shouldSendXSRF =
65
+ withXSRFToken === true ||
66
+ (withXSRFToken == null && isURLSameOrigin(newConfig.url));
58
67
 
59
- if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {
60
- // Add xsrf header
68
+ if (shouldSendXSRF) {
61
69
  const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);
62
70
 
63
71
  if (xsrfValue) {
@@ -1,3 +1,50 @@
1
+ const LOOPBACK_HOSTNAMES = new Set(['localhost']);
2
+
3
+ const isIPv4Loopback = (host) => {
4
+ const parts = host.split('.');
5
+ if (parts.length !== 4) return false;
6
+ if (parts[0] !== '127') return false;
7
+ return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
8
+ };
9
+
10
+ const isIPv6Loopback = (host) => {
11
+ // Collapse all-zero groups: any form of ::1 / 0:0:...:0:1
12
+ // First, strip any leading "::" by normalising with Set lookup of common forms,
13
+ // then fall back to structural check.
14
+ if (host === '::1') return true;
15
+
16
+ // Check IPv4-mapped IPv6 loopback: ::ffff:<v4-loopback> or ::ffff:<hex-v4-loopback>
17
+ // Node's URL parser normalises ::ffff:127.0.0.1 → ::ffff:7f00:1
18
+ const v4MappedDotted = host.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i);
19
+ if (v4MappedDotted) return isIPv4Loopback(v4MappedDotted[1]);
20
+
21
+ const v4MappedHex = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
22
+ if (v4MappedHex) {
23
+ const high = parseInt(v4MappedHex[1], 16);
24
+ // High 16 bits must start with 127 (0x7f) — i.e. 0x7f00..0x7fff
25
+ return high >= 0x7f00 && high <= 0x7fff;
26
+ }
27
+
28
+ // Full-form ::1 variants: any number of zero groups followed by trailing 1
29
+ // e.g. 0:0:0:0:0:0:0:1, 0000:...:0001
30
+ const groups = host.split(':');
31
+ if (groups.length === 8) {
32
+ for (let i = 0; i < 7; i++) {
33
+ if (!/^0+$/.test(groups[i])) return false;
34
+ }
35
+ return /^0*1$/.test(groups[7]);
36
+ }
37
+
38
+ return false;
39
+ };
40
+
41
+ const isLoopback = (host) => {
42
+ if (!host) return false;
43
+ if (LOOPBACK_HOSTNAMES.has(host)) return true;
44
+ if (isIPv4Loopback(host)) return true;
45
+ return isIPv6Loopback(host);
46
+ };
47
+
1
48
  const DEFAULT_PORTS = {
2
49
  http: 80,
3
50
  https: 443,
@@ -101,6 +148,6 @@ export default function shouldBypassProxy(location) {
101
148
  return hostname.endsWith(entryHost);
102
149
  }
103
150
 
104
- return hostname === entryHost;
151
+ return hostname === entryHost || (isLoopback(hostname) && isLoopback(entryHost));
105
152
  });
106
153
  }
@@ -115,6 +115,7 @@ function toFormData(obj, formData, options) {
115
115
  const dots = options.dots;
116
116
  const indexes = options.indexes;
117
117
  const _Blob = options.Blob || (typeof Blob !== 'undefined' && Blob);
118
+ const maxDepth = options.maxDepth === undefined ? 100 : options.maxDepth;
118
119
  const useBlob = _Blob && utils.isSpecCompliantForm(formData);
119
120
 
120
121
  if (!utils.isFunction(visitor)) {
@@ -207,9 +208,16 @@ function toFormData(obj, formData, options) {
207
208
  isVisitable,
208
209
  });
209
210
 
210
- function build(value, path) {
211
+ function build(value, path, depth = 0) {
211
212
  if (utils.isUndefined(value)) return;
212
213
 
214
+ if (depth > maxDepth) {
215
+ throw new AxiosError(
216
+ 'Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth,
217
+ AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED
218
+ );
219
+ }
220
+
213
221
  if (stack.indexOf(value) !== -1) {
214
222
  throw Error('Circular reference detected in ' + path.join('.'));
215
223
  }
@@ -222,7 +230,7 @@ function toFormData(obj, formData, options) {
222
230
  visitor.call(formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers);
223
231
 
224
232
  if (result === true) {
225
- build(el, path ? path.concat(key) : [key]);
233
+ build(el, path ? path.concat(key) : [key], depth + 1);
226
234
  }
227
235
  });
228
236
 
@@ -257,16 +257,16 @@ const G = getGlobal();
257
257
  const FormDataCtor = typeof G.FormData !== 'undefined' ? G.FormData : undefined;
258
258
 
259
259
  const isFormData = (thing) => {
260
- let kind;
261
- return thing && (
262
- (FormDataCtor && thing instanceof FormDataCtor) || (
263
- isFunction(thing.append) && (
264
- (kind = kindOf(thing)) === 'formdata' ||
265
- // detect form-data instance
266
- (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')
267
- )
268
- )
269
- );
260
+ if (!thing) return false;
261
+ if (FormDataCtor && thing instanceof FormDataCtor) return true;
262
+ // Reject plain objects inheriting directly from Object.prototype so prototype-pollution gadgets can't spoof FormData (GHSA-6chq-wfr3-2hj9).
263
+ const proto = getPrototypeOf(thing);
264
+ if (!proto || proto === Object.prototype) return false;
265
+ if (!isFunction(thing.append)) return false;
266
+ const kind = kindOf(thing);
267
+ return kind === 'formdata' ||
268
+ // detect form-data instance
269
+ (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]');
270
270
  };
271
271
 
272
272
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axios",
3
- "version": "1.15.0",
3
+ "version": "1.15.1",
4
4
  "description": "Promise based HTTP client for the browser and node.js",
5
5
  "main": "./dist/node/axios.cjs",
6
6
  "module": "./index.js",
@@ -82,14 +82,14 @@
82
82
  "Dmitriy Mozgovoy (https://github.com/DigitalBrainJS)",
83
83
  "Nick Uraltsev (https://github.com/nickuraltsev)",
84
84
  "Emily Morehouse (https://github.com/emilyemorehouse)",
85
- "Rubén Norte (https://github.com/rubennorte)",
86
85
  "Justin Beckwith (https://github.com/JustinBeckwith)",
86
+ "Rubén Norte (https://github.com/rubennorte)",
87
87
  "Martti Laine (https://github.com/codeclown)",
88
88
  "Xianming Zhong (https://github.com/chinesedfan)",
89
89
  "Remco Haszing (https://github.com/remcohaszing)",
90
+ "Shaan Majid (https://github.com/shaanmajid)",
90
91
  "Willian Agostini (https://github.com/WillianAgostini)",
91
- "Rikki Gibson (https://github.com/RikkiGibson)",
92
- "Ben Carp (https://github.com/carpben)"
92
+ "Rikki Gibson (https://github.com/RikkiGibson)"
93
93
  ],
94
94
  "sideEffects": false,
95
95
  "license": "MIT",