@openclaw/msteams 2026.6.11-beta.2 → 2026.6.33

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 (68) hide show
  1. package/dist/api.js +1 -1
  2. package/dist/{channel-D6Se2irO.js → channel-De7IU_NC.js} +2 -2
  3. package/dist/channel-plugin-api.js +1 -1
  4. package/dist/{channel.runtime-DIplgUVW.js → channel.runtime-DNzD6A6c.js} +2 -2
  5. package/dist/{probe-Cl6_-FSx.js → probe-BrPEeWJe.js} +19 -8
  6. package/dist/{src-DgSUjtxR.js → src-_fXCY2NI.js} +2 -2
  7. package/node_modules/axios/CHANGELOG.md +165 -1
  8. package/node_modules/axios/README.md +310 -247
  9. package/node_modules/axios/dist/axios.js +533 -197
  10. package/node_modules/axios/dist/axios.min.js +3 -3
  11. package/node_modules/axios/dist/axios.min.js.map +1 -1
  12. package/node_modules/axios/dist/browser/axios.cjs +564 -161
  13. package/node_modules/axios/dist/esm/axios.js +564 -161
  14. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  15. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  16. package/node_modules/axios/dist/node/axios.cjs +839 -281
  17. package/node_modules/axios/index.d.cts +11 -4
  18. package/node_modules/axios/index.d.ts +7 -2
  19. package/node_modules/axios/lib/adapters/fetch.js +196 -37
  20. package/node_modules/axios/lib/adapters/http.js +328 -185
  21. package/node_modules/axios/lib/adapters/xhr.js +2 -1
  22. package/node_modules/axios/lib/core/Axios.js +4 -2
  23. package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
  24. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  25. package/node_modules/axios/lib/core/mergeConfig.js +34 -0
  26. package/node_modules/axios/lib/defaults/transitional.js +2 -0
  27. package/node_modules/axios/lib/env/data.js +1 -1
  28. package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
  29. package/node_modules/axios/lib/helpers/buildURL.js +6 -4
  30. package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
  31. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  32. package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
  33. package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
  34. package/node_modules/axios/lib/helpers/fromDataURI.js +18 -5
  35. package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
  36. package/node_modules/axios/lib/helpers/resolveConfig.js +17 -9
  37. package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
  38. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  39. package/node_modules/axios/lib/helpers/toFormData.js +41 -11
  40. package/node_modules/axios/lib/utils.js +105 -19
  41. package/node_modules/axios/node_modules/agent-base/README.md +145 -0
  42. package/node_modules/axios/node_modules/agent-base/dist/src/index.d.ts +78 -0
  43. package/node_modules/axios/node_modules/agent-base/dist/src/index.js +203 -0
  44. package/node_modules/axios/node_modules/agent-base/dist/src/index.js.map +1 -0
  45. package/node_modules/axios/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
  46. package/node_modules/axios/node_modules/agent-base/dist/src/promisify.js +18 -0
  47. package/node_modules/axios/node_modules/agent-base/dist/src/promisify.js.map +1 -0
  48. package/node_modules/axios/node_modules/agent-base/package.json +64 -0
  49. package/node_modules/axios/node_modules/agent-base/src/index.ts +345 -0
  50. package/node_modules/axios/node_modules/agent-base/src/promisify.ts +33 -0
  51. package/node_modules/axios/node_modules/https-proxy-agent/README.md +137 -0
  52. package/node_modules/axios/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
  53. package/node_modules/axios/node_modules/https-proxy-agent/dist/agent.js +177 -0
  54. package/node_modules/axios/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
  55. package/node_modules/axios/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
  56. package/node_modules/axios/node_modules/https-proxy-agent/dist/index.js +14 -0
  57. package/node_modules/axios/node_modules/https-proxy-agent/dist/index.js.map +1 -0
  58. package/node_modules/axios/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
  59. package/node_modules/axios/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
  60. package/node_modules/axios/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
  61. package/node_modules/axios/node_modules/https-proxy-agent/package.json +56 -0
  62. package/node_modules/axios/package.json +31 -13
  63. package/npm-shrinkwrap.json +32 -6
  64. package/package.json +4 -4
  65. package/node_modules/axios/dist/axios.js.map +0 -1
  66. package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
  67. package/node_modules/axios/dist/esm/axios.js.map +0 -1
  68. package/node_modules/axios/dist/node/axios.cjs.map +0 -1
@@ -35,7 +35,7 @@ const encodeUTF8 = (str) =>
35
35
  String.fromCharCode(parseInt(hex, 16))
36
36
  );
37
37
 
38
- export default (config) => {
38
+ function resolveConfig(config) {
39
39
  const newConfig = mergeConfig({}, config);
40
40
 
41
41
  // Read only own properties to prevent prototype pollution gadgets
@@ -55,23 +55,29 @@ export default (config) => {
55
55
  newConfig.headers = headers = AxiosHeaders.from(headers);
56
56
 
57
57
  newConfig.url = buildURL(
58
- buildFullPath(baseURL, url, allowAbsoluteUrls),
59
- config.params,
60
- config.paramsSerializer
58
+ buildFullPath(baseURL, url, allowAbsoluteUrls, newConfig),
59
+ own('params'),
60
+ own('paramsSerializer')
61
61
  );
62
62
 
63
63
  // HTTP basic authentication
64
64
  if (auth) {
65
+ const username = utils.getSafeProp(auth, 'username') || '';
66
+ const password = utils.getSafeProp(auth, 'password') || '';
67
+
65
68
  headers.set(
66
69
  'Authorization',
67
- 'Basic ' +
68
- btoa((auth.username || '') + ':' + (auth.password ? encodeUTF8(auth.password) : ''))
70
+ 'Basic ' + btoa(username + ':' + (password ? encodeUTF8(password) : ''))
69
71
  );
70
72
  }
71
73
 
72
74
  if (utils.isFormData(data)) {
73
- if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {
74
- headers.setContentType(undefined); // browser handles it
75
+ if (
76
+ platform.hasStandardBrowserEnv ||
77
+ platform.hasStandardBrowserWebWorkerEnv ||
78
+ utils.isReactNative(data)
79
+ ) {
80
+ headers.setContentType(undefined); // browser/web worker/RN handles it
75
81
  } else if (utils.isFunction(data.getHeaders)) {
76
82
  // Node.js FormData (like form-data package)
77
83
  setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
@@ -103,4 +109,6 @@ export default (config) => {
103
109
  }
104
110
 
105
111
  return newConfig;
106
- };
112
+ }
113
+
114
+ export default resolveConfig;
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ import utils from '../utils.js';
4
+
5
+ function trimSPorHTAB(str) {
6
+ let start = 0;
7
+ let end = str.length;
8
+
9
+ while (start < end) {
10
+ const code = str.charCodeAt(start);
11
+
12
+ if (code !== 0x09 && code !== 0x20) {
13
+ break;
14
+ }
15
+
16
+ start += 1;
17
+ }
18
+
19
+ while (end > start) {
20
+ const code = str.charCodeAt(end - 1);
21
+
22
+ if (code !== 0x09 && code !== 0x20) {
23
+ break;
24
+ }
25
+
26
+ end -= 1;
27
+ }
28
+
29
+ return start === 0 && end === str.length ? str : str.slice(start, end);
30
+ }
31
+
32
+ // The control-code ranges are intentional: header sanitization strips C0/DEL bytes.
33
+ // eslint-disable-next-line no-control-regex
34
+ const INVALID_UNICODE_HEADER_VALUE_CHARS = new RegExp('[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+', 'g');
35
+ // eslint-disable-next-line no-control-regex
36
+ const INVALID_BYTE_STRING_HEADER_VALUE_CHARS = new RegExp('[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+', 'g');
37
+
38
+ function sanitizeValue(value, invalidChars) {
39
+ if (utils.isArray(value)) {
40
+ return value.map((item) => sanitizeValue(item, invalidChars));
41
+ }
42
+
43
+ return trimSPorHTAB(String(value).replace(invalidChars, ''));
44
+ }
45
+
46
+ export const sanitizeHeaderValue = (value) =>
47
+ sanitizeValue(value, INVALID_UNICODE_HEADER_VALUE_CHARS);
48
+
49
+ export const sanitizeByteStringHeaderValue = (value) =>
50
+ sanitizeValue(value, INVALID_BYTE_STRING_HEADER_VALUE_CHARS);
51
+
52
+ export function toByteStringHeaderObject(headers) {
53
+ const byteStringHeaders = Object.create(null);
54
+
55
+ utils.forEach(headers.toJSON(), (value, header) => {
56
+ byteStringHeaders[header] = sanitizeByteStringHeaderValue(value);
57
+ });
58
+
59
+ return byteStringHeaders;
60
+ }
@@ -1,4 +1,4 @@
1
- const LOOPBACK_HOSTNAMES = new Set(['localhost']);
1
+ const LOOPBACK_HOSTNAMES = new Set(['localhost', '0.0.0.0']);
2
2
 
3
3
  const isIPv4Loopback = (host) => {
4
4
  const parts = host.split('.');
@@ -7,6 +7,37 @@ const isIPv4Loopback = (host) => {
7
7
  return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
8
8
  };
9
9
 
10
+ const isIPv6ZeroGroup = (group) => /^0{1,4}$/.test(group);
11
+
12
+ // The unspecified address (IPv4 0.0.0.0 / IPv6 ::) resolves to the local host
13
+ // for outbound connections, so treat it as loopback-equivalent for NO_PROXY
14
+ // matching. 0.0.0.0 is covered by LOOPBACK_HOSTNAMES; this handles compressed
15
+ // and full IPv6 all-zero forms so both families bypass symmetrically.
16
+ const isIPv6Unspecified = (host) => {
17
+ if (host === '::') return true;
18
+
19
+ const compressionIndex = host.indexOf('::');
20
+
21
+ if (compressionIndex !== -1) {
22
+ if (compressionIndex !== host.lastIndexOf('::')) return false;
23
+
24
+ const left = host.slice(0, compressionIndex);
25
+ const right = host.slice(compressionIndex + 2);
26
+ const leftGroups = left ? left.split(':') : [];
27
+ const rightGroups = right ? right.split(':') : [];
28
+ const explicitGroups = leftGroups.length + rightGroups.length;
29
+
30
+ return (
31
+ explicitGroups < 8 &&
32
+ leftGroups.every(isIPv6ZeroGroup) &&
33
+ rightGroups.every(isIPv6ZeroGroup)
34
+ );
35
+ }
36
+
37
+ const groups = host.split(':');
38
+ return groups.length === 8 && groups.every(isIPv6ZeroGroup);
39
+ };
40
+
10
41
  const isIPv6Loopback = (host) => {
11
42
  // Collapse all-zero groups: any form of ::1 / 0:0:...:0:1
12
43
  // First, strip any leading "::" by normalising with Set lookup of common forms,
@@ -42,6 +73,7 @@ const isLoopback = (host) => {
42
73
  if (!host) return false;
43
74
  if (LOOPBACK_HOSTNAMES.has(host)) return true;
44
75
  if (isIPv4Loopback(host)) return true;
76
+ if (isIPv6Unspecified(host)) return true;
45
77
  return isIPv6Loopback(host);
46
78
  };
47
79
 
@@ -5,6 +5,10 @@ import AxiosError from '../core/AxiosError.js';
5
5
  // temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored
6
6
  import PlatformFormData from '../platform/node/classes/FormData.js';
7
7
 
8
+ // Default nesting limit shared with the inverse transform (formDataToJSON) so
9
+ // the FormData <-> JSON round-trip stays symmetric.
10
+ export const DEFAULT_FORM_DATA_MAX_DEPTH = 100;
11
+
8
12
  /**
9
13
  * Determines if the given thing is a array or js object.
10
14
  *
@@ -115,8 +119,9 @@ function toFormData(obj, formData, options) {
115
119
  const dots = options.dots;
116
120
  const indexes = options.indexes;
117
121
  const _Blob = options.Blob || (typeof Blob !== 'undefined' && Blob);
118
- const maxDepth = options.maxDepth === undefined ? 100 : options.maxDepth;
122
+ const maxDepth = options.maxDepth === undefined ? DEFAULT_FORM_DATA_MAX_DEPTH : options.maxDepth;
119
123
  const useBlob = _Blob && utils.isSpecCompliantForm(formData);
124
+ const stack = [];
120
125
 
121
126
  if (!utils.isFunction(visitor)) {
122
127
  throw new TypeError('visitor must be a function');
@@ -144,6 +149,38 @@ function toFormData(obj, formData, options) {
144
149
  return value;
145
150
  }
146
151
 
152
+ function throwIfMaxDepthExceeded(depth) {
153
+ if (depth > maxDepth) {
154
+ throw new AxiosError(
155
+ 'Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth,
156
+ AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED
157
+ );
158
+ }
159
+ }
160
+
161
+ function stringifyWithDepthLimit(value, depth) {
162
+ if (maxDepth === Infinity) {
163
+ return JSON.stringify(value);
164
+ }
165
+
166
+ const ancestors = [];
167
+
168
+ return JSON.stringify(value, function limitDepth(_key, currentValue) {
169
+ if (!utils.isObject(currentValue)) {
170
+ return currentValue;
171
+ }
172
+
173
+ while (ancestors.length && ancestors[ancestors.length - 1] !== this) {
174
+ ancestors.pop();
175
+ }
176
+
177
+ ancestors.push(currentValue);
178
+ throwIfMaxDepthExceeded(depth + ancestors.length - 1);
179
+
180
+ return currentValue;
181
+ });
182
+ }
183
+
147
184
  /**
148
185
  * Default visitor.
149
186
  *
@@ -167,7 +204,7 @@ function toFormData(obj, formData, options) {
167
204
  // eslint-disable-next-line no-param-reassign
168
205
  key = metaTokens ? key : key.slice(0, -2);
169
206
  // eslint-disable-next-line no-param-reassign
170
- value = JSON.stringify(value);
207
+ value = stringifyWithDepthLimit(value, 1);
171
208
  } else if (
172
209
  (utils.isArray(value) && isFlatArray(value)) ||
173
210
  ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value)))
@@ -200,8 +237,6 @@ function toFormData(obj, formData, options) {
200
237
  return false;
201
238
  }
202
239
 
203
- const stack = [];
204
-
205
240
  const exposedHelpers = Object.assign(predicates, {
206
241
  defaultVisitor,
207
242
  convertValue,
@@ -211,15 +246,10 @@ function toFormData(obj, formData, options) {
211
246
  function build(value, path, depth = 0) {
212
247
  if (utils.isUndefined(value)) return;
213
248
 
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
- }
249
+ throwIfMaxDepthExceeded(depth);
220
250
 
221
251
  if (stack.indexOf(value) !== -1) {
222
- throw Error('Circular reference detected in ' + path.join('.'));
252
+ throw new Error('Circular reference detected in ' + path.join('.'));
223
253
  }
224
254
 
225
255
  stack.push(value);
@@ -8,6 +8,57 @@ const { toString } = Object.prototype;
8
8
  const { getPrototypeOf } = Object;
9
9
  const { iterator, toStringTag } = Symbol;
10
10
 
11
+ /* Creating a function that will check if an object has a property. */
12
+ const hasOwnProperty = (
13
+ ({ hasOwnProperty }) =>
14
+ (obj, prop) =>
15
+ hasOwnProperty.call(obj, prop)
16
+ )(Object.prototype);
17
+
18
+ /**
19
+ * Walk the prototype chain (excluding the shared Object.prototype) looking for
20
+ * an own `prop`. This distinguishes genuine own/inherited members — including
21
+ * class accessors and template prototypes — from members injected via
22
+ * Object.prototype pollution (e.g. `Object.prototype.username = '...'`), which
23
+ * live on Object.prototype itself and are therefore never matched.
24
+ *
25
+ * @param {*} thing The value whose chain to inspect
26
+ * @param {string|symbol} prop The property key to look for
27
+ *
28
+ * @returns {boolean} True when `prop` is owned below Object.prototype
29
+ */
30
+ const hasOwnInPrototypeChain = (thing, prop) => {
31
+ let obj = thing;
32
+ const seen = [];
33
+
34
+ while (obj != null && obj !== Object.prototype) {
35
+ if (seen.indexOf(obj) !== -1) {
36
+ return false;
37
+ }
38
+ seen.push(obj);
39
+
40
+ if (hasOwnProperty(obj, prop)) {
41
+ return true;
42
+ }
43
+ obj = getPrototypeOf(obj);
44
+ }
45
+ return false;
46
+ };
47
+
48
+ /**
49
+ * Read `obj[prop]` only when it is safe from Object.prototype pollution. Own
50
+ * properties and members inherited from a non-Object.prototype source (a class
51
+ * instance or template object) are honored; a value reachable only through a
52
+ * polluted Object.prototype is ignored and `undefined` is returned.
53
+ *
54
+ * @param {*} obj The source object
55
+ * @param {string|symbol} prop The property key to read
56
+ *
57
+ * @returns {*} The resolved value, or undefined when unsafe/absent
58
+ */
59
+ const getSafeProp = (obj, prop) =>
60
+ obj != null && hasOwnInPrototypeChain(obj, prop) ? obj[prop] : undefined;
61
+
11
62
  const kindOf = ((cache) => (thing) => {
12
63
  const str = toString.call(thing);
13
64
  return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
@@ -133,7 +184,7 @@ const isBoolean = (thing) => thing === true || thing === false;
133
184
  * @returns {boolean} True if value is a plain Object, otherwise false
134
185
  */
135
186
  const isPlainObject = (val) => {
136
- if (kindOf(val) !== 'object') {
187
+ if (!isObject(val)) {
137
188
  return false;
138
189
  }
139
190
 
@@ -141,9 +192,12 @@ const isPlainObject = (val) => {
141
192
  return (
142
193
  (prototype === null ||
143
194
  prototype === Object.prototype ||
144
- Object.getPrototypeOf(prototype) === null) &&
145
- !(toStringTag in val) &&
146
- !(iterator in val)
195
+ getPrototypeOf(prototype) === null) &&
196
+ // Treat any genuine (non-Object.prototype-polluted) Symbol.toStringTag or
197
+ // Symbol.iterator as evidence the value is a tagged/iterable type rather
198
+ // than a plain object, while ignoring keys injected onto Object.prototype.
199
+ !hasOwnInPrototypeChain(val, toStringTag) &&
200
+ !hasOwnInPrototypeChain(val, iterator)
147
201
  );
148
202
  };
149
203
 
@@ -412,7 +466,9 @@ function merge(...objs) {
412
466
  return;
413
467
  }
414
468
 
415
- const targetKey = (caseless && findKey(result, key)) || key;
469
+ // findKey lowercases the key, so caseless lookup only applies to strings —
470
+ // symbol keys are identity-matched.
471
+ const targetKey = (caseless && typeof key === 'string' && findKey(result, key)) || key;
416
472
  // Read via own-prop only — a bare `result[targetKey]` walks the prototype
417
473
  // chain, so a polluted Object.prototype value could surface here and get
418
474
  // copied into the merged result.
@@ -429,7 +485,24 @@ function merge(...objs) {
429
485
  };
430
486
 
431
487
  for (let i = 0, l = objs.length; i < l; i++) {
432
- objs[i] && forEach(objs[i], assignValue);
488
+ const source = objs[i];
489
+ if (!source || isBuffer(source)) {
490
+ continue;
491
+ }
492
+
493
+ forEach(source, assignValue);
494
+
495
+ if (typeof source !== 'object' || isArray(source)) {
496
+ continue;
497
+ }
498
+
499
+ const symbols = Object.getOwnPropertySymbols(source);
500
+ for (let j = 0; j < symbols.length; j++) {
501
+ const symbol = symbols[j];
502
+ if (propertyIsEnumerable.call(source, symbol)) {
503
+ assignValue(source[symbol], symbol);
504
+ }
505
+ }
433
506
  }
434
507
  return result;
435
508
  }
@@ -651,12 +724,7 @@ const toCamelCase = (str) => {
651
724
  });
652
725
  };
653
726
 
654
- /* Creating a function that will check if an object has a property. */
655
- const hasOwnProperty = (
656
- ({ hasOwnProperty }) =>
657
- (obj, prop) =>
658
- hasOwnProperty.call(obj, prop)
659
- )(Object.prototype);
727
+ const { propertyIsEnumerable } = Object.prototype;
660
728
 
661
729
  /**
662
730
  * Determine if a value is a RegExp object
@@ -763,11 +831,11 @@ function isSpecCompliantForm(thing) {
763
831
  * @returns {Object} The JSON-compatible object.
764
832
  */
765
833
  const toJSONObject = (obj) => {
766
- const stack = new Array(10);
834
+ const visited = new WeakSet();
767
835
 
768
- const visit = (source, i) => {
836
+ const visit = (source) => {
769
837
  if (isObject(source)) {
770
- if (stack.indexOf(source) >= 0) {
838
+ if (visited.has(source)) {
771
839
  return;
772
840
  }
773
841
 
@@ -777,15 +845,16 @@ const toJSONObject = (obj) => {
777
845
  }
778
846
 
779
847
  if (!('toJSON' in source)) {
780
- stack[i] = source;
848
+ // add-on descent / delete-on-ascent: preserves path semantics, so DAG nodes serialise at every occurrence (see #7230).
849
+ visited.add(source);
781
850
  const target = isArray(source) ? [] : {};
782
851
 
783
852
  forEach(source, (value, key) => {
784
- const reducedValue = visit(value, i + 1);
853
+ const reducedValue = visit(value);
785
854
  !isUndefined(reducedValue) && (target[key] = reducedValue);
786
855
  });
787
856
 
788
- stack[i] = undefined;
857
+ visited.delete(source);
789
858
 
790
859
  return target;
791
860
  }
@@ -794,7 +863,7 @@ const toJSONObject = (obj) => {
794
863
  return source;
795
864
  };
796
865
 
797
- return visit(obj, 0);
866
+ return visit(obj);
798
867
  };
799
868
 
800
869
  /**
@@ -868,6 +937,20 @@ const asap =
868
937
 
869
938
  const isIterable = (thing) => thing != null && isFunction(thing[iterator]);
870
939
 
940
+ /**
941
+ * Determine if a value is iterable via an iterator that is NOT sourced solely
942
+ * from a polluted Object.prototype. Use this instead of `isIterable` whenever
943
+ * the iterable comes from untrusted input (e.g. user-supplied header sources),
944
+ * so `Object.prototype[Symbol.iterator] = ...` cannot turn an ordinary object
945
+ * into an attacker-controlled entries iterator.
946
+ *
947
+ * @param {*} thing The value to test
948
+ *
949
+ * @returns {boolean} True if value has a non-polluted iterator
950
+ */
951
+ const isSafeIterable = (thing) =>
952
+ thing != null && hasOwnInPrototypeChain(thing, iterator) && isIterable(thing);
953
+
871
954
  export default {
872
955
  isArray,
873
956
  isArrayBuffer,
@@ -912,6 +995,8 @@ export default {
912
995
  isHTMLForm,
913
996
  hasOwnProperty,
914
997
  hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection
998
+ hasOwnInPrototypeChain,
999
+ getSafeProp,
915
1000
  reduceDescriptors,
916
1001
  freezeMethods,
917
1002
  toObjectSet,
@@ -928,4 +1013,5 @@ export default {
928
1013
  setImmediate: _setImmediate,
929
1014
  asap,
930
1015
  isIterable,
1016
+ isSafeIterable,
931
1017
  };
@@ -0,0 +1,145 @@
1
+ agent-base
2
+ ==========
3
+ ### Turn a function into an [`http.Agent`][http.Agent] instance
4
+ [![Build Status](https://github.com/TooTallNate/node-agent-base/workflows/Node%20CI/badge.svg)](https://github.com/TooTallNate/node-agent-base/actions?workflow=Node+CI)
5
+
6
+ This module provides an `http.Agent` generator. That is, you pass it an async
7
+ callback function, and it returns a new `http.Agent` instance that will invoke the
8
+ given callback function when sending outbound HTTP requests.
9
+
10
+ #### Some subclasses:
11
+
12
+ Here's some more interesting uses of `agent-base`.
13
+ Send a pull request to list yours!
14
+
15
+ * [`http-proxy-agent`][http-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTP endpoints
16
+ * [`https-proxy-agent`][https-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTPS endpoints
17
+ * [`pac-proxy-agent`][pac-proxy-agent]: A PAC file proxy `http.Agent` implementation for HTTP and HTTPS
18
+ * [`socks-proxy-agent`][socks-proxy-agent]: A SOCKS proxy `http.Agent` implementation for HTTP and HTTPS
19
+
20
+
21
+ Installation
22
+ ------------
23
+
24
+ Install with `npm`:
25
+
26
+ ``` bash
27
+ $ npm install agent-base
28
+ ```
29
+
30
+
31
+ Example
32
+ -------
33
+
34
+ Here's a minimal example that creates a new `net.Socket` connection to the server
35
+ for every HTTP request (i.e. the equivalent of `agent: false` option):
36
+
37
+ ```js
38
+ var net = require('net');
39
+ var tls = require('tls');
40
+ var url = require('url');
41
+ var http = require('http');
42
+ var agent = require('agent-base');
43
+
44
+ var endpoint = 'http://nodejs.org/api/';
45
+ var parsed = url.parse(endpoint);
46
+
47
+ // This is the important part!
48
+ parsed.agent = agent(function (req, opts) {
49
+ var socket;
50
+ // `secureEndpoint` is true when using the https module
51
+ if (opts.secureEndpoint) {
52
+ socket = tls.connect(opts);
53
+ } else {
54
+ socket = net.connect(opts);
55
+ }
56
+ return socket;
57
+ });
58
+
59
+ // Everything else works just like normal...
60
+ http.get(parsed, function (res) {
61
+ console.log('"response" event!', res.headers);
62
+ res.pipe(process.stdout);
63
+ });
64
+ ```
65
+
66
+ Returning a Promise or using an `async` function is also supported:
67
+
68
+ ```js
69
+ agent(async function (req, opts) {
70
+ await sleep(1000);
71
+ // etc…
72
+ });
73
+ ```
74
+
75
+ Return another `http.Agent` instance to "pass through" the responsibility
76
+ for that HTTP request to that agent:
77
+
78
+ ```js
79
+ agent(function (req, opts) {
80
+ return opts.secureEndpoint ? https.globalAgent : http.globalAgent;
81
+ });
82
+ ```
83
+
84
+
85
+ API
86
+ ---
87
+
88
+ ## Agent(Function callback[, Object options]) → [http.Agent][]
89
+
90
+ Creates a base `http.Agent` that will execute the callback function `callback`
91
+ for every HTTP request that it is used as the `agent` for. The callback function
92
+ is responsible for creating a `stream.Duplex` instance of some kind that will be
93
+ used as the underlying socket in the HTTP request.
94
+
95
+ The `options` object accepts the following properties:
96
+
97
+ * `timeout` - Number - Timeout for the `callback()` function in milliseconds. Defaults to Infinity (optional).
98
+
99
+ The callback function should have the following signature:
100
+
101
+ ### callback(http.ClientRequest req, Object options, Function cb) → undefined
102
+
103
+ The ClientRequest `req` can be accessed to read request headers and
104
+ and the path, etc. The `options` object contains the options passed
105
+ to the `http.request()`/`https.request()` function call, and is formatted
106
+ to be directly passed to `net.connect()`/`tls.connect()`, or however
107
+ else you want a Socket to be created. Pass the created socket to
108
+ the callback function `cb` once created, and the HTTP request will
109
+ continue to proceed.
110
+
111
+ If the `https` module is used to invoke the HTTP request, then the
112
+ `secureEndpoint` property on `options` _will be set to `true`_.
113
+
114
+
115
+ License
116
+ -------
117
+
118
+ (The MIT License)
119
+
120
+ Copyright (c) 2013 Nathan Rajlich &lt;nathan@tootallnate.net&gt;
121
+
122
+ Permission is hereby granted, free of charge, to any person obtaining
123
+ a copy of this software and associated documentation files (the
124
+ 'Software'), to deal in the Software without restriction, including
125
+ without limitation the rights to use, copy, modify, merge, publish,
126
+ distribute, sublicense, and/or sell copies of the Software, and to
127
+ permit persons to whom the Software is furnished to do so, subject to
128
+ the following conditions:
129
+
130
+ The above copyright notice and this permission notice shall be
131
+ included in all copies or substantial portions of the Software.
132
+
133
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
134
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
135
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
136
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
137
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
138
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
139
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
140
+
141
+ [http-proxy-agent]: https://github.com/TooTallNate/node-http-proxy-agent
142
+ [https-proxy-agent]: https://github.com/TooTallNate/node-https-proxy-agent
143
+ [pac-proxy-agent]: https://github.com/TooTallNate/node-pac-proxy-agent
144
+ [socks-proxy-agent]: https://github.com/TooTallNate/node-socks-proxy-agent
145
+ [http.Agent]: https://nodejs.org/api/http.html#http_class_http_agent
@@ -0,0 +1,78 @@
1
+ /// <reference types="node" />
2
+ import net from 'net';
3
+ import http from 'http';
4
+ import https from 'https';
5
+ import { Duplex } from 'stream';
6
+ import { EventEmitter } from 'events';
7
+ declare function createAgent(opts?: createAgent.AgentOptions): createAgent.Agent;
8
+ declare function createAgent(callback: createAgent.AgentCallback, opts?: createAgent.AgentOptions): createAgent.Agent;
9
+ declare namespace createAgent {
10
+ interface ClientRequest extends http.ClientRequest {
11
+ _last?: boolean;
12
+ _hadError?: boolean;
13
+ method: string;
14
+ }
15
+ interface AgentRequestOptions {
16
+ host?: string;
17
+ path?: string;
18
+ port: number;
19
+ }
20
+ interface HttpRequestOptions extends AgentRequestOptions, Omit<http.RequestOptions, keyof AgentRequestOptions> {
21
+ secureEndpoint: false;
22
+ }
23
+ interface HttpsRequestOptions extends AgentRequestOptions, Omit<https.RequestOptions, keyof AgentRequestOptions> {
24
+ secureEndpoint: true;
25
+ }
26
+ type RequestOptions = HttpRequestOptions | HttpsRequestOptions;
27
+ type AgentLike = Pick<createAgent.Agent, 'addRequest'> | http.Agent;
28
+ type AgentCallbackReturn = Duplex | AgentLike;
29
+ type AgentCallbackCallback = (err?: Error | null, socket?: createAgent.AgentCallbackReturn) => void;
30
+ type AgentCallbackPromise = (req: createAgent.ClientRequest, opts: createAgent.RequestOptions) => createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>;
31
+ type AgentCallback = typeof Agent.prototype.callback;
32
+ type AgentOptions = {
33
+ timeout?: number;
34
+ };
35
+ /**
36
+ * Base `http.Agent` implementation.
37
+ * No pooling/keep-alive is implemented by default.
38
+ *
39
+ * @param {Function} callback
40
+ * @api public
41
+ */
42
+ class Agent extends EventEmitter {
43
+ timeout: number | null;
44
+ maxFreeSockets: number;
45
+ maxTotalSockets: number;
46
+ maxSockets: number;
47
+ sockets: {
48
+ [key: string]: net.Socket[];
49
+ };
50
+ freeSockets: {
51
+ [key: string]: net.Socket[];
52
+ };
53
+ requests: {
54
+ [key: string]: http.IncomingMessage[];
55
+ };
56
+ options: https.AgentOptions;
57
+ private promisifiedCallback?;
58
+ private explicitDefaultPort?;
59
+ private explicitProtocol?;
60
+ constructor(callback?: createAgent.AgentCallback | createAgent.AgentOptions, _opts?: createAgent.AgentOptions);
61
+ get defaultPort(): number;
62
+ set defaultPort(v: number);
63
+ get protocol(): string;
64
+ set protocol(v: string);
65
+ callback(req: createAgent.ClientRequest, opts: createAgent.RequestOptions, fn: createAgent.AgentCallbackCallback): void;
66
+ callback(req: createAgent.ClientRequest, opts: createAgent.RequestOptions): createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>;
67
+ /**
68
+ * Called by node-core's "_http_client.js" module when creating
69
+ * a new HTTP request with this Agent instance.
70
+ *
71
+ * @api public
72
+ */
73
+ addRequest(req: ClientRequest, _opts: RequestOptions): void;
74
+ freeSocket(socket: net.Socket, opts: AgentOptions): void;
75
+ destroy(): void;
76
+ }
77
+ }
78
+ export = createAgent;