undici 6.20.0 → 7.0.0-alpha.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.
Files changed (137) hide show
  1. package/README.md +6 -10
  2. package/docs/docs/api/Agent.md +0 -3
  3. package/docs/docs/api/Client.md +1 -3
  4. package/docs/docs/api/Debug.md +1 -1
  5. package/docs/docs/api/Dispatcher.md +60 -8
  6. package/docs/docs/api/EnvHttpProxyAgent.md +0 -1
  7. package/docs/docs/api/Fetch.md +1 -0
  8. package/docs/docs/api/MockAgent.md +2 -0
  9. package/docs/docs/api/MockPool.md +2 -1
  10. package/docs/docs/api/Pool.md +0 -1
  11. package/docs/docs/api/RetryAgent.md +1 -1
  12. package/docs/docs/api/RetryHandler.md +1 -1
  13. package/docs/docs/api/WebSocket.md +45 -3
  14. package/index.js +6 -6
  15. package/lib/api/abort-signal.js +2 -0
  16. package/lib/api/api-connect.js +3 -1
  17. package/lib/api/api-pipeline.js +7 -6
  18. package/lib/api/api-request.js +32 -47
  19. package/lib/api/api-stream.js +39 -50
  20. package/lib/api/api-upgrade.js +5 -3
  21. package/lib/api/readable.js +261 -64
  22. package/lib/api/util.js +2 -0
  23. package/lib/core/constants.js +11 -9
  24. package/lib/core/diagnostics.js +122 -128
  25. package/lib/core/errors.js +4 -4
  26. package/lib/core/request.js +11 -9
  27. package/lib/core/symbols.js +2 -1
  28. package/lib/core/tree.js +9 -1
  29. package/lib/core/util.js +219 -48
  30. package/lib/dispatcher/agent.js +3 -17
  31. package/lib/dispatcher/balanced-pool.js +5 -8
  32. package/lib/dispatcher/client-h1.js +278 -54
  33. package/lib/dispatcher/client-h2.js +1 -1
  34. package/lib/dispatcher/client.js +23 -34
  35. package/lib/dispatcher/dispatcher-base.js +2 -34
  36. package/lib/dispatcher/dispatcher.js +3 -24
  37. package/lib/dispatcher/fixed-queue.js +91 -49
  38. package/lib/dispatcher/pool-stats.js +2 -0
  39. package/lib/dispatcher/pool.js +3 -6
  40. package/lib/dispatcher/proxy-agent.js +6 -7
  41. package/lib/handler/decorator-handler.js +24 -0
  42. package/lib/handler/redirect-handler.js +11 -2
  43. package/lib/handler/retry-handler.js +12 -3
  44. package/lib/interceptor/dns.js +346 -0
  45. package/lib/interceptor/dump.js +2 -2
  46. package/lib/interceptor/redirect.js +11 -14
  47. package/lib/interceptor/response-error.js +4 -1
  48. package/lib/llhttp/constants.d.ts +97 -0
  49. package/lib/llhttp/constants.js +412 -192
  50. package/lib/llhttp/constants.js.map +1 -0
  51. package/lib/llhttp/llhttp-wasm.js +11 -1
  52. package/lib/llhttp/llhttp_simd-wasm.js +11 -1
  53. package/lib/llhttp/utils.d.ts +2 -0
  54. package/lib/llhttp/utils.js +9 -9
  55. package/lib/llhttp/utils.js.map +1 -0
  56. package/lib/mock/mock-agent.js +5 -8
  57. package/lib/mock/mock-client.js +9 -4
  58. package/lib/mock/mock-errors.js +3 -1
  59. package/lib/mock/mock-interceptor.js +8 -6
  60. package/lib/mock/mock-pool.js +9 -4
  61. package/lib/mock/mock-symbols.js +3 -1
  62. package/lib/mock/mock-utils.js +29 -5
  63. package/lib/web/cache/cache.js +24 -21
  64. package/lib/web/cache/cachestorage.js +1 -1
  65. package/lib/web/cookies/index.js +17 -13
  66. package/lib/web/cookies/parse.js +2 -2
  67. package/lib/web/eventsource/eventsource-stream.js +9 -8
  68. package/lib/web/eventsource/eventsource.js +10 -6
  69. package/lib/web/fetch/body.js +42 -36
  70. package/lib/web/fetch/constants.js +35 -26
  71. package/lib/web/fetch/data-url.js +1 -1
  72. package/lib/web/fetch/formdata-parser.js +2 -2
  73. package/lib/web/fetch/formdata.js +65 -54
  74. package/lib/web/fetch/headers.js +117 -85
  75. package/lib/web/fetch/index.js +55 -62
  76. package/lib/web/fetch/request.js +135 -77
  77. package/lib/web/fetch/response.js +86 -56
  78. package/lib/web/fetch/util.js +90 -64
  79. package/lib/web/fetch/webidl.js +99 -64
  80. package/lib/web/websocket/connection.js +76 -147
  81. package/lib/web/websocket/constants.js +3 -4
  82. package/lib/web/websocket/events.js +4 -2
  83. package/lib/web/websocket/frame.js +45 -3
  84. package/lib/web/websocket/receiver.js +29 -33
  85. package/lib/web/websocket/sender.js +18 -13
  86. package/lib/web/websocket/stream/websocketerror.js +83 -0
  87. package/lib/web/websocket/stream/websocketstream.js +485 -0
  88. package/lib/web/websocket/util.js +128 -77
  89. package/lib/web/websocket/websocket.js +234 -135
  90. package/package.json +20 -33
  91. package/scripts/strip-comments.js +3 -1
  92. package/types/agent.d.ts +7 -7
  93. package/types/api.d.ts +24 -24
  94. package/types/balanced-pool.d.ts +11 -11
  95. package/types/client.d.ts +11 -12
  96. package/types/diagnostics-channel.d.ts +10 -10
  97. package/types/dispatcher.d.ts +96 -97
  98. package/types/env-http-proxy-agent.d.ts +2 -2
  99. package/types/errors.d.ts +53 -47
  100. package/types/fetch.d.ts +8 -8
  101. package/types/formdata.d.ts +7 -7
  102. package/types/global-dispatcher.d.ts +4 -4
  103. package/types/global-origin.d.ts +5 -5
  104. package/types/handlers.d.ts +4 -4
  105. package/types/header.d.ts +157 -1
  106. package/types/index.d.ts +42 -46
  107. package/types/interceptors.d.ts +22 -8
  108. package/types/mock-agent.d.ts +21 -18
  109. package/types/mock-client.d.ts +4 -4
  110. package/types/mock-errors.d.ts +3 -3
  111. package/types/mock-interceptor.d.ts +19 -19
  112. package/types/mock-pool.d.ts +4 -4
  113. package/types/patch.d.ts +0 -4
  114. package/types/pool-stats.d.ts +8 -8
  115. package/types/pool.d.ts +12 -12
  116. package/types/proxy-agent.d.ts +4 -4
  117. package/types/readable.d.ts +22 -14
  118. package/types/retry-agent.d.ts +1 -1
  119. package/types/retry-handler.d.ts +8 -8
  120. package/types/util.d.ts +3 -3
  121. package/types/utility.d.ts +7 -0
  122. package/types/webidl.d.ts +44 -6
  123. package/types/websocket.d.ts +34 -1
  124. package/docs/docs/api/DispatchInterceptor.md +0 -60
  125. package/lib/interceptor/redirect-interceptor.js +0 -21
  126. package/lib/mock/pluralizer.js +0 -29
  127. package/lib/web/cache/symbols.js +0 -5
  128. package/lib/web/fetch/file.js +0 -126
  129. package/lib/web/fetch/symbols.js +0 -9
  130. package/lib/web/fileapi/encoding.js +0 -290
  131. package/lib/web/fileapi/filereader.js +0 -344
  132. package/lib/web/fileapi/progressevent.js +0 -78
  133. package/lib/web/fileapi/symbols.js +0 -10
  134. package/lib/web/fileapi/util.js +0 -391
  135. package/lib/web/websocket/symbols.js +0 -12
  136. package/types/file.d.ts +0 -39
  137. package/types/filereader.d.ts +0 -54
@@ -9,7 +9,6 @@ const {
9
9
  isValidReasonPhrase,
10
10
  isCancelled,
11
11
  isAborted,
12
- isBlobLike,
13
12
  serializeJavascriptValueToJSONString,
14
13
  isErrorLike,
15
14
  isomorphicEncode,
@@ -19,9 +18,7 @@ const {
19
18
  redirectStatusSet,
20
19
  nullBodyStatus
21
20
  } = require('./constants')
22
- const { kState, kHeaders } = require('./symbols')
23
21
  const { webidl } = require('./webidl')
24
- const { FormData } = require('./formdata')
25
22
  const { URLSerializer } = require('./data-url')
26
23
  const { kConstruct } = require('../../core/symbols')
27
24
  const assert = require('node:assert')
@@ -31,6 +28,11 @@ const textEncoder = new TextEncoder('utf-8')
31
28
 
32
29
  // https://fetch.spec.whatwg.org/#response-class
33
30
  class Response {
31
+ /** @type {Headers} */
32
+ #headers
33
+
34
+ #state
35
+
34
36
  // Creates network error Response.
35
37
  static error () {
36
38
  // The static error() method steps are to return the result of creating a
@@ -42,7 +44,7 @@ class Response {
42
44
  }
43
45
 
44
46
  // https://fetch.spec.whatwg.org/#dom-response-json
45
- static json (data, init = {}) {
47
+ static json (data, init = undefined) {
46
48
  webidl.argumentLengthCheck(arguments, 1, 'Response.json')
47
49
 
48
50
  if (init !== null) {
@@ -96,20 +98,20 @@ class Response {
96
98
  const responseObject = fromInnerResponse(makeResponse({}), 'immutable')
97
99
 
98
100
  // 5. Set responseObject’s response’s status to status.
99
- responseObject[kState].status = status
101
+ responseObject.#state.status = status
100
102
 
101
103
  // 6. Let value be parsedURL, serialized and isomorphic encoded.
102
104
  const value = isomorphicEncode(URLSerializer(parsedURL))
103
105
 
104
106
  // 7. Append `Location`/value to responseObject’s response’s header list.
105
- responseObject[kState].headersList.append('location', value, true)
107
+ responseObject.#state.headersList.append('location', value, true)
106
108
 
107
109
  // 8. Return responseObject.
108
110
  return responseObject
109
111
  }
110
112
 
111
113
  // https://fetch.spec.whatwg.org/#dom-response
112
- constructor (body = null, init = {}) {
114
+ constructor (body = null, init = undefined) {
113
115
  if (body === kConstruct) {
114
116
  return
115
117
  }
@@ -121,14 +123,14 @@ class Response {
121
123
  init = webidl.converters.ResponseInit(init)
122
124
 
123
125
  // 1. Set this’s response to a new response.
124
- this[kState] = makeResponse({})
126
+ this.#state = makeResponse({})
125
127
 
126
128
  // 2. Set this’s headers to a new Headers object with this’s relevant
127
129
  // Realm, whose header list is this’s response’s header list and guard
128
130
  // is "response".
129
- this[kHeaders] = new Headers(kConstruct)
130
- setHeadersGuard(this[kHeaders], 'response')
131
- setHeadersList(this[kHeaders], this[kState].headersList)
131
+ this.#headers = new Headers(kConstruct)
132
+ setHeadersGuard(this.#headers, 'response')
133
+ setHeadersList(this.#headers, this.#state.headersList)
132
134
 
133
135
  // 3. Let bodyWithType be null.
134
136
  let bodyWithType = null
@@ -148,14 +150,14 @@ class Response {
148
150
  webidl.brandCheck(this, Response)
149
151
 
150
152
  // The type getter steps are to return this’s response’s type.
151
- return this[kState].type
153
+ return this.#state.type
152
154
  }
153
155
 
154
156
  // Returns response’s URL, if it has one; otherwise the empty string.
155
157
  get url () {
156
158
  webidl.brandCheck(this, Response)
157
159
 
158
- const urlList = this[kState].urlList
160
+ const urlList = this.#state.urlList
159
161
 
160
162
  // The url getter steps are to return the empty string if this’s
161
163
  // response’s URL is null; otherwise this’s response’s URL,
@@ -175,7 +177,7 @@ class Response {
175
177
 
176
178
  // The redirected getter steps are to return true if this’s response’s URL
177
179
  // list has more than one item; otherwise false.
178
- return this[kState].urlList.length > 1
180
+ return this.#state.urlList.length > 1
179
181
  }
180
182
 
181
183
  // Returns response’s status.
@@ -183,7 +185,7 @@ class Response {
183
185
  webidl.brandCheck(this, Response)
184
186
 
185
187
  // The status getter steps are to return this’s response’s status.
186
- return this[kState].status
188
+ return this.#state.status
187
189
  }
188
190
 
189
191
  // Returns whether response’s status is an ok status.
@@ -192,7 +194,7 @@ class Response {
192
194
 
193
195
  // The ok getter steps are to return true if this’s response’s status is an
194
196
  // ok status; otherwise false.
195
- return this[kState].status >= 200 && this[kState].status <= 299
197
+ return this.#state.status >= 200 && this.#state.status <= 299
196
198
  }
197
199
 
198
200
  // Returns response’s status message.
@@ -201,7 +203,7 @@ class Response {
201
203
 
202
204
  // The statusText getter steps are to return this’s response’s status
203
205
  // message.
204
- return this[kState].statusText
206
+ return this.#state.statusText
205
207
  }
206
208
 
207
209
  // Returns response’s headers as Headers.
@@ -209,19 +211,19 @@ class Response {
209
211
  webidl.brandCheck(this, Response)
210
212
 
211
213
  // The headers getter steps are to return this’s headers.
212
- return this[kHeaders]
214
+ return this.#headers
213
215
  }
214
216
 
215
217
  get body () {
216
218
  webidl.brandCheck(this, Response)
217
219
 
218
- return this[kState].body ? this[kState].body.stream : null
220
+ return this.#state.body ? this.#state.body.stream : null
219
221
  }
220
222
 
221
223
  get bodyUsed () {
222
224
  webidl.brandCheck(this, Response)
223
225
 
224
- return !!this[kState].body && util.isDisturbed(this[kState].body.stream)
226
+ return !!this.#state.body && util.isDisturbed(this.#state.body.stream)
225
227
  }
226
228
 
227
229
  // Returns a clone of response.
@@ -229,7 +231,7 @@ class Response {
229
231
  webidl.brandCheck(this, Response)
230
232
 
231
233
  // 1. If this is unusable, then throw a TypeError.
232
- if (bodyUnusable(this)) {
234
+ if (bodyUnusable(this.#state)) {
233
235
  throw webidl.errors.exception({
234
236
  header: 'Response.clone',
235
237
  message: 'Body has already been consumed.'
@@ -237,11 +239,11 @@ class Response {
237
239
  }
238
240
 
239
241
  // 2. Let clonedResponse be the result of cloning this’s response.
240
- const clonedResponse = cloneResponse(this[kState])
242
+ const clonedResponse = cloneResponse(this.#state)
241
243
 
242
244
  // 3. Return the result of creating a Response object, given
243
245
  // clonedResponse, this’s headers’s guard, and this’s relevant Realm.
244
- return fromInnerResponse(clonedResponse, getHeadersGuard(this[kHeaders]))
246
+ return fromInnerResponse(clonedResponse, getHeadersGuard(this.#headers))
245
247
  }
246
248
 
247
249
  [nodeUtil.inspect.custom] (depth, options) {
@@ -265,9 +267,45 @@ class Response {
265
267
 
266
268
  return `Response ${nodeUtil.formatWithOptions(options, properties)}`
267
269
  }
270
+
271
+ /**
272
+ * @param {Response} response
273
+ */
274
+ static getResponseHeaders (response) {
275
+ return response.#headers
276
+ }
277
+
278
+ /**
279
+ * @param {Response} response
280
+ * @param {Headers} newHeaders
281
+ */
282
+ static setResponseHeaders (response, newHeaders) {
283
+ response.#headers = newHeaders
284
+ }
285
+
286
+ /**
287
+ * @param {Response} response
288
+ */
289
+ static getResponseState (response) {
290
+ return response.#state
291
+ }
292
+
293
+ /**
294
+ * @param {Response} response
295
+ * @param {any} newState
296
+ */
297
+ static setResponseState (response, newState) {
298
+ response.#state = newState
299
+ }
268
300
  }
269
301
 
270
- mixinBody(Response)
302
+ const { getResponseHeaders, setResponseHeaders, getResponseState, setResponseState } = Response
303
+ Reflect.deleteProperty(Response, 'getResponseHeaders')
304
+ Reflect.deleteProperty(Response, 'setResponseHeaders')
305
+ Reflect.deleteProperty(Response, 'getResponseState')
306
+ Reflect.deleteProperty(Response, 'setResponseState')
307
+
308
+ mixinBody(Response, getResponseState)
271
309
 
272
310
  Object.defineProperties(Response.prototype, {
273
311
  type: kEnumerableProperty,
@@ -464,17 +502,17 @@ function initializeResponse (response, init, body) {
464
502
 
465
503
  // 3. Set response’s response’s status to init["status"].
466
504
  if ('status' in init && init.status != null) {
467
- response[kState].status = init.status
505
+ getResponseState(response).status = init.status
468
506
  }
469
507
 
470
508
  // 4. Set response’s response’s status message to init["statusText"].
471
509
  if ('statusText' in init && init.statusText != null) {
472
- response[kState].statusText = init.statusText
510
+ getResponseState(response).statusText = init.statusText
473
511
  }
474
512
 
475
513
  // 5. If init["headers"] exists, then fill response’s headers with init["headers"].
476
514
  if ('headers' in init && init.headers != null) {
477
- fill(response[kHeaders], init.headers)
515
+ fill(getResponseHeaders(response), init.headers)
478
516
  }
479
517
 
480
518
  // 6. If body was given, then:
@@ -488,12 +526,12 @@ function initializeResponse (response, init, body) {
488
526
  }
489
527
 
490
528
  // 2. Set response's body to body's body.
491
- response[kState].body = body.body
529
+ getResponseState(response).body = body.body
492
530
 
493
531
  // 3. If body's type is non-null and response's header list does not contain
494
532
  // `Content-Type`, then append (`Content-Type`, body's type) to response's header list.
495
- if (body.type != null && !response[kState].headersList.contains('content-type', true)) {
496
- response[kState].headersList.append('content-type', body.type, true)
533
+ if (body.type != null && !getResponseState(response).headersList.contains('content-type', true)) {
534
+ getResponseState(response).headersList.append('content-type', body.type, true)
497
535
  }
498
536
  }
499
537
  }
@@ -506,10 +544,11 @@ function initializeResponse (response, init, body) {
506
544
  */
507
545
  function fromInnerResponse (innerResponse, guard) {
508
546
  const response = new Response(kConstruct)
509
- response[kState] = innerResponse
510
- response[kHeaders] = new Headers(kConstruct)
511
- setHeadersList(response[kHeaders], innerResponse.headersList)
512
- setHeadersGuard(response[kHeaders], guard)
547
+ setResponseState(response, innerResponse)
548
+ const headers = new Headers(kConstruct)
549
+ setResponseHeaders(response, headers)
550
+ setHeadersList(headers, innerResponse.headersList)
551
+ setHeadersGuard(headers, guard)
513
552
 
514
553
  if (hasFinalizationRegistry && innerResponse.body?.stream) {
515
554
  // If the target (response) is reclaimed, the cleanup callback may be called at some point with
@@ -523,38 +562,26 @@ function fromInnerResponse (innerResponse, guard) {
523
562
  return response
524
563
  }
525
564
 
526
- webidl.converters.ReadableStream = webidl.interfaceConverter(
527
- ReadableStream
528
- )
529
-
530
- webidl.converters.FormData = webidl.interfaceConverter(
531
- FormData
532
- )
533
-
534
- webidl.converters.URLSearchParams = webidl.interfaceConverter(
535
- URLSearchParams
536
- )
537
-
538
565
  // https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit
539
566
  webidl.converters.XMLHttpRequestBodyInit = function (V, prefix, name) {
540
567
  if (typeof V === 'string') {
541
568
  return webidl.converters.USVString(V, prefix, name)
542
569
  }
543
570
 
544
- if (isBlobLike(V)) {
545
- return webidl.converters.Blob(V, prefix, name, { strict: false })
571
+ if (webidl.is.Blob(V)) {
572
+ return V
546
573
  }
547
574
 
548
575
  if (ArrayBuffer.isView(V) || types.isArrayBuffer(V)) {
549
- return webidl.converters.BufferSource(V, prefix, name)
576
+ return V
550
577
  }
551
578
 
552
- if (util.isFormDataLike(V)) {
553
- return webidl.converters.FormData(V, prefix, name, { strict: false })
579
+ if (webidl.is.FormData(V)) {
580
+ return V
554
581
  }
555
582
 
556
- if (V instanceof URLSearchParams) {
557
- return webidl.converters.URLSearchParams(V, prefix, name)
583
+ if (webidl.is.URLSearchParams(V)) {
584
+ return V
558
585
  }
559
586
 
560
587
  return webidl.converters.DOMString(V, prefix, name)
@@ -562,8 +589,8 @@ webidl.converters.XMLHttpRequestBodyInit = function (V, prefix, name) {
562
589
 
563
590
  // https://fetch.spec.whatwg.org/#bodyinit
564
591
  webidl.converters.BodyInit = function (V, prefix, argument) {
565
- if (V instanceof ReadableStream) {
566
- return webidl.converters.ReadableStream(V, prefix, argument)
592
+ if (webidl.is.ReadableStream(V)) {
593
+ return V
567
594
  }
568
595
 
569
596
  // Note: the spec doesn't include async iterables,
@@ -592,6 +619,8 @@ webidl.converters.ResponseInit = webidl.dictionaryConverter([
592
619
  }
593
620
  ])
594
621
 
622
+ webidl.is.Response = webidl.util.MakeTypeAssertion(Response.prototype)
623
+
595
624
  module.exports = {
596
625
  isNetworkError,
597
626
  makeNetworkError,
@@ -600,5 +629,6 @@ module.exports = {
600
629
  filterResponse,
601
630
  Response,
602
631
  cloneResponse,
603
- fromInnerResponse
632
+ fromInnerResponse,
633
+ getResponseState
604
634
  }
@@ -6,7 +6,7 @@ const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet
6
6
  const { getGlobalOrigin } = require('./global')
7
7
  const { collectASequenceOfCodePoints, collectAnHTTPQuotedString, removeChars, parseMIMEType } = require('./data-url')
8
8
  const { performance } = require('node:perf_hooks')
9
- const { isBlobLike, ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require('../../core/util')
9
+ const { ReadableStreamFrom, isValidHTTPToken, normalizedMethodRecordsBase } = require('../../core/util')
10
10
  const assert = require('node:assert')
11
11
  const { isUint8Array } = require('node:util/types')
12
12
  const { webidl } = require('./webidl')
@@ -399,7 +399,7 @@ function determineRequestsReferrer (request) {
399
399
 
400
400
  // note: we need to clone it as it's mutated
401
401
  referrerSource = new URL(globalOrigin)
402
- } else if (request.referrer instanceof URL) {
402
+ } else if (webidl.is.URL(request.referrer)) {
403
403
  // Let referrerSource be request’s referrer.
404
404
  referrerSource = request.referrer
405
405
  }
@@ -418,18 +418,37 @@ function determineRequestsReferrer (request) {
418
418
  referrerURL = referrerOrigin
419
419
  }
420
420
 
421
- const areSameOrigin = sameOrigin(request, referrerURL)
422
- const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) &&
423
- !isURLPotentiallyTrustworthy(request.url)
421
+ // 7. The user agent MAY alter referrerURL or referrerOrigin at this point
422
+ // to enforce arbitrary policy considerations in the interests of minimizing
423
+ // data leakage. For example, the user agent could strip the URL down to an
424
+ // origin, modify its host, replace it with an empty string, etc.
424
425
 
425
426
  // 8. Execute the switch statements corresponding to the value of policy:
426
427
  switch (policy) {
427
- case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true)
428
- case 'unsafe-url': return referrerURL
429
- case 'same-origin':
430
- return areSameOrigin ? referrerOrigin : 'no-referrer'
431
- case 'origin-when-cross-origin':
432
- return areSameOrigin ? referrerURL : referrerOrigin
428
+ case 'no-referrer':
429
+ // Return no referrer
430
+ return 'no-referrer'
431
+ case 'origin':
432
+ // Return referrerOrigin
433
+ if (referrerOrigin != null) {
434
+ return referrerOrigin
435
+ }
436
+ return stripURLForReferrer(referrerSource, true)
437
+ case 'unsafe-url':
438
+ // Return referrerURL.
439
+ return referrerURL
440
+ case 'strict-origin': {
441
+ const currentURL = requestCurrentURL(request)
442
+
443
+ // 1. If referrerURL is a potentially trustworthy URL and request’s
444
+ // current URL is not a potentially trustworthy URL, then return no
445
+ // referrer.
446
+ if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) {
447
+ return 'no-referrer'
448
+ }
449
+ // 2. Return referrerOrigin
450
+ return referrerOrigin
451
+ }
433
452
  case 'strict-origin-when-cross-origin': {
434
453
  const currentURL = requestCurrentURL(request)
435
454
 
@@ -449,34 +468,45 @@ function determineRequestsReferrer (request) {
449
468
  // 3. Return referrerOrigin.
450
469
  return referrerOrigin
451
470
  }
452
- case 'strict-origin': // eslint-disable-line
453
- /**
454
- * 1. If referrerURL is a potentially trustworthy URL and
455
- * request’s current URL is not a potentially trustworthy URL,
456
- * then return no referrer.
457
- * 2. Return referrerOrigin
458
- */
459
- case 'no-referrer-when-downgrade': // eslint-disable-line
460
- /**
461
- * 1. If referrerURL is a potentially trustworthy URL and
462
- * request’s current URL is not a potentially trustworthy URL,
463
- * then return no referrer.
464
- * 2. Return referrerOrigin
465
- */
466
-
467
- default: // eslint-disable-line
468
- return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin
471
+ case 'same-origin':
472
+ // 1. If the origin of referrerURL and the origin of request’s current
473
+ // URL are the same, then return referrerURL.
474
+ if (sameOrigin(request, referrerURL)) {
475
+ return referrerURL
476
+ }
477
+ // 2. Return no referrer.
478
+ return 'no-referrer'
479
+ case 'origin-when-cross-origin':
480
+ // 1. If the origin of referrerURL and the origin of request’s current
481
+ // URL are the same, then return referrerURL.
482
+ if (sameOrigin(request, referrerURL)) {
483
+ return referrerURL
484
+ }
485
+ // 2. Return referrerOrigin.
486
+ return referrerOrigin
487
+ case 'no-referrer-when-downgrade': {
488
+ const currentURL = requestCurrentURL(request)
489
+
490
+ // 1. If referrerURL is a potentially trustworthy URL and request’s
491
+ // current URL is not a potentially trustworthy URL, then return no
492
+ // referrer.
493
+ if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) {
494
+ return 'no-referrer'
495
+ }
496
+ // 2. Return referrerOrigin
497
+ return referrerOrigin
498
+ }
469
499
  }
470
500
  }
471
501
 
472
502
  /**
473
503
  * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url
474
504
  * @param {URL} url
475
- * @param {boolean|undefined} originOnly
505
+ * @param {boolean} [originOnly]
476
506
  */
477
507
  function stripURLForReferrer (url, originOnly) {
478
508
  // 1. Assert: url is a URL.
479
- assert(url instanceof URL)
509
+ assert(webidl.is.URL(url))
480
510
 
481
511
  url = new URL(url)
482
512
 
@@ -508,7 +538,7 @@ function stripURLForReferrer (url, originOnly) {
508
538
  }
509
539
 
510
540
  function isURLPotentiallyTrustworthy (url) {
511
- if (!(url instanceof URL)) {
541
+ if (!webidl.is.URL(url)) {
512
542
  return false
513
543
  }
514
544
 
@@ -825,7 +855,7 @@ const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbo
825
855
  /**
826
856
  * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
827
857
  * @param {string} name name of the instance
828
- * @param {symbol} kInternalIterator
858
+ * @param {((target: any) => any)} kInternalIterator
829
859
  * @param {string | number} [keyIndex]
830
860
  * @param {string | number} [valueIndex]
831
861
  */
@@ -867,7 +897,7 @@ function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1)
867
897
  // 7. Let kind be object’s kind.
868
898
  // 8. Let values be object’s target's value pairs to iterate over.
869
899
  const index = this.#index
870
- const values = this.#target[kInternalIterator]
900
+ const values = kInternalIterator(this.#target)
871
901
 
872
902
  // 9. Let len be the length of values.
873
903
  const len = values.length
@@ -961,7 +991,7 @@ function createIterator (name, kInternalIterator, keyIndex = 0, valueIndex = 1)
961
991
  * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
962
992
  * @param {string} name name of the instance
963
993
  * @param {any} object class
964
- * @param {symbol} kInternalIterator
994
+ * @param {(target: any) => any} kInternalIterator
965
995
  * @param {string | number} [keyIndex]
966
996
  * @param {string | number} [valueIndex]
967
997
  */
@@ -1029,7 +1059,7 @@ function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueInde
1029
1059
  /**
1030
1060
  * @see https://fetch.spec.whatwg.org/#body-fully-read
1031
1061
  */
1032
- async function fullyReadBody (body, processBody, processBodyError) {
1062
+ function fullyReadBody (body, processBody, processBodyError) {
1033
1063
  // 1. If taskDestination is null, then set taskDestination to
1034
1064
  // the result of starting a new parallel queue.
1035
1065
 
@@ -1054,18 +1084,7 @@ async function fullyReadBody (body, processBody, processBodyError) {
1054
1084
  }
1055
1085
 
1056
1086
  // 5. Read all bytes from reader, given successSteps and errorSteps.
1057
- try {
1058
- successSteps(await readAllBytes(reader))
1059
- } catch (e) {
1060
- errorSteps(e)
1061
- }
1062
- }
1063
-
1064
- function isReadableStreamLike (stream) {
1065
- return stream instanceof ReadableStream || (
1066
- stream[Symbol.toStringTag] === 'ReadableStream' &&
1067
- typeof stream.tee === 'function'
1068
- )
1087
+ readAllBytes(reader, successSteps, errorSteps)
1069
1088
  }
1070
1089
 
1071
1090
  /**
@@ -1103,30 +1122,39 @@ function isomorphicEncode (input) {
1103
1122
  * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes
1104
1123
  * @see https://streams.spec.whatwg.org/#read-loop
1105
1124
  * @param {ReadableStreamDefaultReader} reader
1125
+ * @param {(bytes: Uint8Array) => void} successSteps
1126
+ * @param {(error: Error) => void} failureSteps
1106
1127
  */
1107
- async function readAllBytes (reader) {
1128
+ async function readAllBytes (reader, successSteps, failureSteps) {
1108
1129
  const bytes = []
1109
1130
  let byteLength = 0
1110
1131
 
1111
- while (true) {
1112
- const { done, value: chunk } = await reader.read()
1132
+ try {
1133
+ do {
1134
+ const { done, value: chunk } = await reader.read()
1113
1135
 
1114
- if (done) {
1115
- // 1. Call successSteps with bytes.
1116
- return Buffer.concat(bytes, byteLength)
1117
- }
1136
+ if (done) {
1137
+ // 1. Call successSteps with bytes.
1138
+ successSteps(Buffer.concat(bytes, byteLength))
1139
+ return
1140
+ }
1118
1141
 
1119
- // 1. If chunk is not a Uint8Array object, call failureSteps
1120
- // with a TypeError and abort these steps.
1121
- if (!isUint8Array(chunk)) {
1122
- throw new TypeError('Received non-Uint8Array chunk')
1123
- }
1142
+ // 1. If chunk is not a Uint8Array object, call failureSteps
1143
+ // with a TypeError and abort these steps.
1144
+ if (!isUint8Array(chunk)) {
1145
+ failureSteps(TypeError('Received non-Uint8Array chunk'))
1146
+ return
1147
+ }
1124
1148
 
1125
- // 2. Append the bytes represented by chunk to bytes.
1126
- bytes.push(chunk)
1127
- byteLength += chunk.length
1149
+ // 2. Append the bytes represented by chunk to bytes.
1150
+ bytes.push(chunk)
1151
+ byteLength += chunk.length
1128
1152
 
1129
1153
  // 3. Read-loop given reader, bytes, successSteps, and failureSteps.
1154
+ } while (true)
1155
+ } catch (e) {
1156
+ // 1. Call failureSteps with e.
1157
+ failureSteps(e)
1130
1158
  }
1131
1159
  }
1132
1160
 
@@ -1601,7 +1629,6 @@ module.exports = {
1601
1629
  requestCurrentURL,
1602
1630
  responseURL,
1603
1631
  responseLocationURL,
1604
- isBlobLike,
1605
1632
  isURLPotentiallyTrustworthy,
1606
1633
  isValidReasonPhrase,
1607
1634
  sameOrigin,
@@ -1614,7 +1641,6 @@ module.exports = {
1614
1641
  isErrorLike,
1615
1642
  fullyReadBody,
1616
1643
  bytesMatch,
1617
- isReadableStreamLike,
1618
1644
  readableStreamClose,
1619
1645
  isomorphicEncode,
1620
1646
  urlIsLocal,