undici 6.6.0 → 6.6.2

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.
package/index-fetch.js CHANGED
@@ -14,4 +14,7 @@ module.exports.FormData = require('./lib/fetch/formdata').FormData
14
14
  module.exports.Headers = require('./lib/fetch/headers').Headers
15
15
  module.exports.Response = require('./lib/fetch/response').Response
16
16
  module.exports.Request = require('./lib/fetch/request').Request
17
+
17
18
  module.exports.WebSocket = require('./lib/websocket/websocket').WebSocket
19
+
20
+ module.exports.EventSource = require('./lib/eventsource/eventsource').EventSource
@@ -2,9 +2,10 @@
2
2
 
3
3
  const { isBlobLike, toUSVString, makeIterator } = require('./util')
4
4
  const { kState } = require('./symbols')
5
+ const { kEnumerableProperty } = require('../core/util')
5
6
  const { File: UndiciFile, FileLike, isFileLike } = require('./file')
6
7
  const { webidl } = require('./webidl')
7
- const { Blob, File: NativeFile } = require('node:buffer')
8
+ const { File: NativeFile } = require('node:buffer')
8
9
 
9
10
  /** @type {globalThis['File']} */
10
11
  const File = NativeFile ?? UndiciFile
@@ -158,9 +159,10 @@ class FormData {
158
159
  webidl.brandCheck(this, FormData)
159
160
 
160
161
  return makeIterator(
161
- () => this[kState].map(pair => [pair.name, pair.value]),
162
+ () => this[kState],
162
163
  'FormData',
163
- 'key+value'
164
+ 'key+value',
165
+ 'name', 'value'
164
166
  )
165
167
  }
166
168
 
@@ -168,9 +170,10 @@ class FormData {
168
170
  webidl.brandCheck(this, FormData)
169
171
 
170
172
  return makeIterator(
171
- () => this[kState].map(pair => [pair.name, pair.value]),
173
+ () => this[kState],
172
174
  'FormData',
173
- 'key'
175
+ 'key',
176
+ 'name', 'value'
174
177
  )
175
178
  }
176
179
 
@@ -178,9 +181,10 @@ class FormData {
178
181
  webidl.brandCheck(this, FormData)
179
182
 
180
183
  return makeIterator(
181
- () => this[kState].map(pair => [pair.name, pair.value]),
184
+ () => this[kState],
182
185
  'FormData',
183
- 'value'
186
+ 'value',
187
+ 'name', 'value'
184
188
  )
185
189
  }
186
190
 
@@ -200,7 +204,7 @@ class FormData {
200
204
  }
201
205
 
202
206
  for (const [key, value] of this) {
203
- callbackFn.apply(thisArg, [value, key, this])
207
+ callbackFn.call(thisArg, value, key, this)
204
208
  }
205
209
  }
206
210
  }
@@ -208,6 +212,17 @@ class FormData {
208
212
  FormData.prototype[Symbol.iterator] = FormData.prototype.entries
209
213
 
210
214
  Object.defineProperties(FormData.prototype, {
215
+ append: kEnumerableProperty,
216
+ delete: kEnumerableProperty,
217
+ get: kEnumerableProperty,
218
+ getAll: kEnumerableProperty,
219
+ has: kEnumerableProperty,
220
+ set: kEnumerableProperty,
221
+ entries: kEnumerableProperty,
222
+ keys: kEnumerableProperty,
223
+ values: kEnumerableProperty,
224
+ forEach: kEnumerableProperty,
225
+ [Symbol.iterator]: { enumerable: false },
211
226
  [Symbol.toStringTag]: {
212
227
  value: 'FormData',
213
228
  configurable: true
@@ -225,7 +240,7 @@ function makeEntry (name, value, filename) {
225
240
  // 1. Set name to the result of converting name into a scalar value string.
226
241
  // "To convert a string into a scalar value string, replace any surrogates
227
242
  // with U+FFFD."
228
- // see: https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#buftostringencoding-start-end
243
+ // see: https://nodejs.org/dist/latest-v20.x/docs/api/buffer.html#buftostringencoding-start-end
229
244
  name = Buffer.from(name).toString('utf8')
230
245
 
231
246
  // 2. If value is a string, then set value to the result of converting
@@ -492,48 +492,33 @@ class Headers {
492
492
  keys () {
493
493
  webidl.brandCheck(this, Headers)
494
494
 
495
- if (this[kGuard] === 'immutable') {
496
- const value = this[kHeadersSortedMap]
497
- return makeIterator(() => value, 'Headers',
498
- 'key')
499
- }
500
-
501
495
  return makeIterator(
502
- () => [...this[kHeadersSortedMap].values()],
496
+ () => this[kHeadersSortedMap],
503
497
  'Headers',
504
- 'key'
498
+ 'key',
499
+ 0, 1
505
500
  )
506
501
  }
507
502
 
508
503
  values () {
509
504
  webidl.brandCheck(this, Headers)
510
505
 
511
- if (this[kGuard] === 'immutable') {
512
- const value = this[kHeadersSortedMap]
513
- return makeIterator(() => value, 'Headers',
514
- 'value')
515
- }
516
-
517
506
  return makeIterator(
518
- () => [...this[kHeadersSortedMap].values()],
507
+ () => this[kHeadersSortedMap],
519
508
  'Headers',
520
- 'value'
509
+ 'value',
510
+ 0, 1
521
511
  )
522
512
  }
523
513
 
524
514
  entries () {
525
515
  webidl.brandCheck(this, Headers)
526
516
 
527
- if (this[kGuard] === 'immutable') {
528
- const value = this[kHeadersSortedMap]
529
- return makeIterator(() => value, 'Headers',
530
- 'key+value')
531
- }
532
-
533
517
  return makeIterator(
534
- () => [...this[kHeadersSortedMap].values()],
518
+ () => this[kHeadersSortedMap],
535
519
  'Headers',
536
- 'key+value'
520
+ 'key+value',
521
+ 0, 1
537
522
  )
538
523
  }
539
524
 
@@ -553,7 +538,7 @@ class Headers {
553
538
  }
554
539
 
555
540
  for (const [key, value] of this) {
556
- callbackFn.apply(thisArg, [value, key, this])
541
+ callbackFn.call(thisArg, value, key, this)
557
542
  }
558
543
  }
559
544
 
@@ -1099,11 +1099,12 @@ function fetchFinale (fetchParams, response) {
1099
1099
 
1100
1100
  const byteStream = new ReadableStream({
1101
1101
  readableStream: transformStream.readable,
1102
- async start (controller) {
1103
- const reader = this.readableStream.getReader()
1104
-
1105
- while (true) {
1106
- const { done, value } = await reader.read()
1102
+ async start () {
1103
+ this._bodyReader = this.readableStream.getReader()
1104
+ },
1105
+ async pull (controller) {
1106
+ while (controller.desiredSize >= 0) {
1107
+ const { done, value } = await this._bodyReader.read()
1107
1108
 
1108
1109
  if (done) {
1109
1110
  queueMicrotask(() => readableStreamClose(controller))
@@ -1113,6 +1114,7 @@ function fetchFinale (fetchParams, response) {
1113
1114
  controller.enqueue(value)
1114
1115
  }
1115
1116
  },
1117
+ queuingStrategy: new ByteLengthQueuingStrategy({ highWaterMark: 16384 }),
1116
1118
  type: 'bytes'
1117
1119
  })
1118
1120
 
@@ -1326,6 +1328,9 @@ function httpRedirectFetch (fetchParams, response) {
1326
1328
  // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name
1327
1329
  request.headersList.delete('authorization', true)
1328
1330
 
1331
+ // https://fetch.spec.whatwg.org/#authentication-entries
1332
+ request.headersList.delete('proxy-authorization', true)
1333
+
1329
1334
  // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement.
1330
1335
  request.headersList.delete('cookie', true)
1331
1336
  request.headersList.delete('host', true)
@@ -1901,8 +1906,8 @@ async function httpNetworkFetch (
1901
1906
 
1902
1907
  // 11. Let pullAlgorithm be an action that resumes the ongoing fetch
1903
1908
  // if it is suspended.
1904
- const pullAlgorithm = () => {
1905
- fetchParams.controller.resume()
1909
+ const pullAlgorithm = async () => {
1910
+ await fetchParams.controller.resume()
1906
1911
  }
1907
1912
 
1908
1913
  // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s
@@ -1924,6 +1929,7 @@ async function httpNetworkFetch (
1924
1929
  // cancelAlgorithm set to cancelAlgorithm.
1925
1930
  const stream = new ReadableStream(
1926
1931
  {
1932
+ highWaterMark: 16384,
1927
1933
  async start (controller) {
1928
1934
  fetchParams.controller.controller = controller
1929
1935
  },
@@ -1933,7 +1939,8 @@ async function httpNetworkFetch (
1933
1939
  async cancel (reason) {
1934
1940
  await cancelAlgorithm(reason)
1935
1941
  },
1936
- type: 'bytes'
1942
+ type: 'bytes',
1943
+ queuingStrategy: new ByteLengthQueuingStrategy({ highWaterMark: 16384 })
1937
1944
  }
1938
1945
  )
1939
1946
 
@@ -2026,7 +2033,7 @@ async function httpNetworkFetch (
2026
2033
 
2027
2034
  // 9. If stream doesn’t need more data ask the user agent to suspend
2028
2035
  // the ongoing fetch.
2029
- if (!fetchParams.controller.controller.desiredSize) {
2036
+ if (fetchParams.controller.controller.desiredSize <= 0) {
2030
2037
  return
2031
2038
  }
2032
2039
  }
package/lib/fetch/util.js CHANGED
@@ -739,19 +739,23 @@ const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbo
739
739
 
740
740
  /**
741
741
  * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
742
- * @param {() => unknown[]} iterator
742
+ * @param {() => unknown} iterator
743
743
  * @param {string} name name of the instance
744
744
  * @param {'key'|'value'|'key+value'} kind
745
+ * @param {string | number} [keyIndex]
746
+ * @param {string | number} [valueIndex]
745
747
  */
746
- function makeIterator (iterator, name, kind) {
748
+ function makeIterator (iterator, name, kind, keyIndex = 0, valueIndex = 1) {
747
749
  const object = {
748
750
  index: 0,
749
751
  kind,
750
752
  target: iterator
751
753
  }
754
+ // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
755
+ const iteratorObject = Object.create(esIteratorPrototype)
752
756
 
753
- const i = {
754
- next () {
757
+ Object.defineProperty(iteratorObject, 'next', {
758
+ value: function next () {
755
759
  // 1. Let interface be the interface for which the iterator prototype object exists.
756
760
 
757
761
  // 2. Let thisValue be the this value.
@@ -763,7 +767,7 @@ function makeIterator (iterator, name, kind) {
763
767
 
764
768
  // 5. If object is not a default iterator object for interface,
765
769
  // then throw a TypeError.
766
- if (Object.getPrototypeOf(this) !== i) {
770
+ if (Object.getPrototypeOf(this) !== iteratorObject) {
767
771
  throw new TypeError(
768
772
  `'next' called on an object that does not implement interface ${name} Iterator.`
769
773
  )
@@ -783,68 +787,66 @@ function makeIterator (iterator, name, kind) {
783
787
  if (index >= len) {
784
788
  return { value: undefined, done: true }
785
789
  }
786
-
787
790
  // 11. Let pair be the entry in values at index index.
788
- const pair = values[index]
789
-
791
+ const { [keyIndex]: key, [valueIndex]: value } = values[index]
790
792
  // 12. Set object’s index to index + 1.
791
793
  object.index = index + 1
792
-
793
794
  // 13. Return the iterator result for pair and kind.
794
- return iteratorResult(pair, kind)
795
+ // https://webidl.spec.whatwg.org/#iterator-result
796
+ // 1. Let result be a value determined by the value of kind:
797
+ let result
798
+ switch (kind) {
799
+ case 'key':
800
+ // 1. Let idlKey be pair’s key.
801
+ // 2. Let key be the result of converting idlKey to an
802
+ // ECMAScript value.
803
+ // 3. result is key.
804
+ result = key
805
+ break
806
+ case 'value':
807
+ // 1. Let idlValue be pair’s value.
808
+ // 2. Let value be the result of converting idlValue to
809
+ // an ECMAScript value.
810
+ // 3. result is value.
811
+ result = value
812
+ break
813
+ case 'key+value':
814
+ // 1. Let idlKey be pair’s key.
815
+ // 2. Let idlValue be pair’s value.
816
+ // 3. Let key be the result of converting idlKey to an
817
+ // ECMAScript value.
818
+ // 4. Let value be the result of converting idlValue to
819
+ // an ECMAScript value.
820
+ // 5. Let array be ! ArrayCreate(2).
821
+ // 6. Call ! CreateDataProperty(array, "0", key).
822
+ // 7. Call ! CreateDataProperty(array, "1", value).
823
+ // 8. result is array.
824
+ result = [key, value]
825
+ break
826
+ }
827
+ // 2. Return CreateIterResultObject(result, false).
828
+ return {
829
+ value: result,
830
+ done: false
831
+ }
795
832
  },
796
- // The class string of an iterator prototype object for a given interface is the
797
- // result of concatenating the identifier of the interface and the string " Iterator".
798
- [Symbol.toStringTag]: `${name} Iterator`
799
- }
800
-
801
- // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
802
- Object.setPrototypeOf(i, esIteratorPrototype)
803
- // esIteratorPrototype needs to be the prototype of i
804
- // which is the prototype of an empty object. Yes, it's confusing.
805
- return Object.setPrototypeOf({}, i)
806
- }
833
+ writable: true,
834
+ enumerable: true,
835
+ configurable: true
836
+ })
807
837
 
808
- // https://webidl.spec.whatwg.org/#iterator-result
809
- function iteratorResult (pair, kind) {
810
- let result
811
-
812
- // 1. Let result be a value determined by the value of kind:
813
- switch (kind) {
814
- case 'key': {
815
- // 1. Let idlKey be pair’s key.
816
- // 2. Let key be the result of converting idlKey to an
817
- // ECMAScript value.
818
- // 3. result is key.
819
- result = pair[0]
820
- break
821
- }
822
- case 'value': {
823
- // 1. Let idlValue be pair’s value.
824
- // 2. Let value be the result of converting idlValue to
825
- // an ECMAScript value.
826
- // 3. result is value.
827
- result = pair[1]
828
- break
829
- }
830
- case 'key+value': {
831
- // 1. Let idlKey be pair’s key.
832
- // 2. Let idlValue be pair’s value.
833
- // 3. Let key be the result of converting idlKey to an
834
- // ECMAScript value.
835
- // 4. Let value be the result of converting idlValue to
836
- // an ECMAScript value.
837
- // 5. Let array be ! ArrayCreate(2).
838
- // 6. Call ! CreateDataProperty(array, "0", key).
839
- // 7. Call ! CreateDataProperty(array, "1", value).
840
- // 8. result is array.
841
- result = pair
842
- break
843
- }
844
- }
838
+ // The class string of an iterator prototype object for a given interface is the
839
+ // result of concatenating the identifier of the interface and the string " Iterator".
840
+ Object.defineProperty(iteratorObject, Symbol.toStringTag, {
841
+ value: `${name} Iterator`,
842
+ writable: false,
843
+ enumerable: false,
844
+ configurable: true
845
+ })
845
846
 
846
- // 2. Return CreateIterResultObject(result, false).
847
- return { value: result, done: false }
847
+ // esIteratorPrototype needs to be the prototype of iteratorObject
848
+ // which is the prototype of an empty object. Yes, it's confusing.
849
+ return Object.create(iteratorObject)
848
850
  }
849
851
 
850
852
  /**
@@ -34,10 +34,14 @@ webidl.errors.invalidArgument = function (context) {
34
34
 
35
35
  // https://webidl.spec.whatwg.org/#implements
36
36
  webidl.brandCheck = function (V, I, opts = undefined) {
37
- if (opts?.strict !== false && !(V instanceof I)) {
38
- throw new TypeError('Illegal invocation')
37
+ if (opts?.strict !== false) {
38
+ if (!(V instanceof I)) {
39
+ throw new TypeError('Illegal invocation')
40
+ }
39
41
  } else {
40
- return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag]
42
+ if (V?.[Symbol.toStringTag] !== I.prototype[Symbol.toStringTag]) {
43
+ throw new TypeError('Illegal invocation')
44
+ }
41
45
  }
42
46
  }
43
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "undici",
3
- "version": "6.6.0",
3
+ "version": "6.6.2",
4
4
  "description": "An HTTP/1.1 client, written from scratch for Node.js",
5
5
  "homepage": "https://undici.nodejs.org",
6
6
  "bugs": {
@@ -104,7 +104,7 @@
104
104
  "@sinonjs/fake-timers": "^11.1.0",
105
105
  "@types/node": "^18.0.3",
106
106
  "abort-controller": "^3.0.0",
107
- "borp": "^0.5.0",
107
+ "borp": "^0.9.1",
108
108
  "chai": "^4.3.4",
109
109
  "chai-as-promised": "^7.1.1",
110
110
  "chai-iterator": "^3.0.2",
@@ -121,7 +121,7 @@
121
121
  "jest": "^29.0.2",
122
122
  "jsdom": "^24.0.0",
123
123
  "jsfuzz": "^1.0.15",
124
- "mitata": "^0.1.6",
124
+ "mitata": "^0.1.8",
125
125
  "mocha": "^10.0.0",
126
126
  "p-timeout": "^3.2.0",
127
127
  "pre-commit": "^1.2.2",