undici 7.0.0-alpha.1 → 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 (71) hide show
  1. package/README.md +2 -2
  2. package/docs/docs/api/Client.md +1 -1
  3. package/docs/docs/api/Debug.md +1 -1
  4. package/docs/docs/api/Dispatcher.md +53 -2
  5. package/docs/docs/api/MockAgent.md +2 -0
  6. package/docs/docs/api/MockPool.md +2 -1
  7. package/docs/docs/api/RetryAgent.md +1 -1
  8. package/docs/docs/api/RetryHandler.md +1 -1
  9. package/docs/docs/api/WebSocket.md +45 -3
  10. package/index.js +6 -2
  11. package/lib/api/abort-signal.js +2 -0
  12. package/lib/api/api-pipeline.js +4 -2
  13. package/lib/api/api-request.js +4 -2
  14. package/lib/api/api-stream.js +3 -1
  15. package/lib/api/api-upgrade.js +2 -2
  16. package/lib/api/readable.js +194 -41
  17. package/lib/api/util.js +2 -0
  18. package/lib/core/connect.js +49 -22
  19. package/lib/core/constants.js +11 -9
  20. package/lib/core/diagnostics.js +122 -128
  21. package/lib/core/request.js +4 -4
  22. package/lib/core/symbols.js +2 -0
  23. package/lib/core/tree.js +4 -2
  24. package/lib/core/util.js +220 -39
  25. package/lib/dispatcher/client-h1.js +299 -60
  26. package/lib/dispatcher/client-h2.js +1 -1
  27. package/lib/dispatcher/client.js +24 -7
  28. package/lib/dispatcher/fixed-queue.js +91 -49
  29. package/lib/dispatcher/pool-stats.js +2 -0
  30. package/lib/dispatcher/proxy-agent.js +3 -1
  31. package/lib/handler/redirect-handler.js +2 -2
  32. package/lib/handler/retry-handler.js +2 -2
  33. package/lib/interceptor/dns.js +346 -0
  34. package/lib/mock/mock-agent.js +5 -8
  35. package/lib/mock/mock-client.js +7 -2
  36. package/lib/mock/mock-errors.js +3 -1
  37. package/lib/mock/mock-interceptor.js +8 -6
  38. package/lib/mock/mock-pool.js +7 -2
  39. package/lib/mock/mock-symbols.js +2 -1
  40. package/lib/mock/mock-utils.js +33 -5
  41. package/lib/util/timers.js +50 -6
  42. package/lib/web/cache/cache.js +24 -21
  43. package/lib/web/cache/cachestorage.js +1 -1
  44. package/lib/web/cookies/index.js +6 -4
  45. package/lib/web/fetch/body.js +42 -34
  46. package/lib/web/fetch/constants.js +35 -26
  47. package/lib/web/fetch/formdata-parser.js +14 -3
  48. package/lib/web/fetch/formdata.js +40 -20
  49. package/lib/web/fetch/headers.js +116 -84
  50. package/lib/web/fetch/index.js +65 -59
  51. package/lib/web/fetch/request.js +130 -55
  52. package/lib/web/fetch/response.js +79 -36
  53. package/lib/web/fetch/util.js +104 -57
  54. package/lib/web/fetch/webidl.js +38 -14
  55. package/lib/web/websocket/connection.js +92 -15
  56. package/lib/web/websocket/constants.js +2 -3
  57. package/lib/web/websocket/events.js +4 -2
  58. package/lib/web/websocket/receiver.js +20 -26
  59. package/lib/web/websocket/stream/websocketerror.js +83 -0
  60. package/lib/web/websocket/stream/websocketstream.js +485 -0
  61. package/lib/web/websocket/util.js +115 -10
  62. package/lib/web/websocket/websocket.js +45 -170
  63. package/package.json +6 -6
  64. package/types/interceptors.d.ts +14 -0
  65. package/types/mock-agent.d.ts +3 -0
  66. package/types/readable.d.ts +10 -7
  67. package/types/webidl.d.ts +24 -4
  68. package/types/websocket.d.ts +33 -0
  69. package/lib/mock/pluralizer.js +0 -29
  70. package/lib/web/cache/symbols.js +0 -5
  71. package/lib/web/fetch/symbols.js +0 -8
@@ -18,7 +18,6 @@ const MockPool = require('./mock-pool')
18
18
  const { matchValue, buildMockOptions } = require('./mock-utils')
19
19
  const { InvalidArgumentError, UndiciError } = require('../core/errors')
20
20
  const Dispatcher = require('../dispatcher/dispatcher')
21
- const Pluralizer = require('./pluralizer')
22
21
  const PendingInterceptorsFormatter = require('./pending-interceptors-formatter')
23
22
 
24
23
  class MockAgent extends Dispatcher {
@@ -147,13 +146,11 @@ class MockAgent extends Dispatcher {
147
146
  return
148
147
  }
149
148
 
150
- const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length)
151
-
152
- throw new UndiciError(`
153
- ${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending:
154
-
155
- ${pendingInterceptorsFormatter.format(pending)}
156
- `.trim())
149
+ throw new UndiciError(
150
+ pending.length === 1
151
+ ? `1 interceptor is pending:\n\n${pendingInterceptorsFormatter.format(pending)}`.trim()
152
+ : `${pending.length} interceptors are pending:\n\n${pendingInterceptorsFormatter.format(pending)}`.trim()
153
+ )
157
154
  }
158
155
  }
159
156
 
@@ -10,7 +10,8 @@ const {
10
10
  kOriginalClose,
11
11
  kOrigin,
12
12
  kOriginalDispatch,
13
- kConnected
13
+ kConnected,
14
+ kIgnoreTrailingSlash
14
15
  } = require('./mock-symbols')
15
16
  const { MockInterceptor } = require('./mock-interceptor')
16
17
  const Symbols = require('../core/symbols')
@@ -29,6 +30,7 @@ class MockClient extends Client {
29
30
 
30
31
  this[kMockAgent] = opts.agent
31
32
  this[kOrigin] = origin
33
+ this[kIgnoreTrailingSlash] = opts.ignoreTrailingSlash ?? false
32
34
  this[kDispatches] = []
33
35
  this[kConnected] = 1
34
36
  this[kOriginalDispatch] = this.dispatch
@@ -46,7 +48,10 @@ class MockClient extends Client {
46
48
  * Sets up the base interceptor for mocking replies from undici.
47
49
  */
48
50
  intercept (opts) {
49
- return new MockInterceptor(opts, this[kDispatches])
51
+ return new MockInterceptor(
52
+ opts && { ignoreTrailingSlash: this[kIgnoreTrailingSlash], ...opts },
53
+ this[kDispatches]
54
+ )
50
55
  }
51
56
 
52
57
  async [kClose] () {
@@ -2,10 +2,12 @@
2
2
 
3
3
  const { UndiciError } = require('../core/errors')
4
4
 
5
+ /**
6
+ * The request does not match any registered mock dispatches.
7
+ */
5
8
  class MockNotMatchedError extends UndiciError {
6
9
  constructor (message) {
7
10
  super(message)
8
- Error.captureStackTrace(this, MockNotMatchedError)
9
11
  this.name = 'MockNotMatchedError'
10
12
  this.message = message || 'The request does not match any registered mock dispatches'
11
13
  this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED'
@@ -7,10 +7,11 @@ const {
7
7
  kDefaultHeaders,
8
8
  kDefaultTrailers,
9
9
  kContentLength,
10
- kMockDispatch
10
+ kMockDispatch,
11
+ kIgnoreTrailingSlash
11
12
  } = require('./mock-symbols')
12
13
  const { InvalidArgumentError } = require('../core/errors')
13
- const { buildURL } = require('../core/util')
14
+ const { serializePathWithQuery } = require('../core/util')
14
15
 
15
16
  /**
16
17
  * Defines the scope API for an interceptor reply
@@ -72,7 +73,7 @@ class MockInterceptor {
72
73
  // fragments to servers when they retrieve a document,
73
74
  if (typeof opts.path === 'string') {
74
75
  if (opts.query) {
75
- opts.path = buildURL(opts.path, opts.query)
76
+ opts.path = serializePathWithQuery(opts.path, opts.query)
76
77
  } else {
77
78
  // Matches https://github.com/nodejs/undici/blob/main/lib/web/fetch/index.js#L1811
78
79
  const parsedURL = new URL(opts.path, 'data://')
@@ -85,6 +86,7 @@ class MockInterceptor {
85
86
 
86
87
  this[kDispatchKey] = buildKey(opts)
87
88
  this[kDispatches] = mockDispatches
89
+ this[kIgnoreTrailingSlash] = opts.ignoreTrailingSlash ?? false
88
90
  this[kDefaultHeaders] = {}
89
91
  this[kDefaultTrailers] = {}
90
92
  this[kContentLength] = false
@@ -137,7 +139,7 @@ class MockInterceptor {
137
139
  }
138
140
 
139
141
  // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data.
140
- const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback)
142
+ const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback, { ignoreTrailingSlash: this[kIgnoreTrailingSlash] })
141
143
  return new MockScope(newMockDispatch)
142
144
  }
143
145
 
@@ -154,7 +156,7 @@ class MockInterceptor {
154
156
 
155
157
  // Send in-already provided data like usual
156
158
  const dispatchData = this.createMockScopeDispatchData(replyParameters)
157
- const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData)
159
+ const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData, { ignoreTrailingSlash: this[kIgnoreTrailingSlash] })
158
160
  return new MockScope(newMockDispatch)
159
161
  }
160
162
 
@@ -166,7 +168,7 @@ class MockInterceptor {
166
168
  throw new InvalidArgumentError('error must be defined')
167
169
  }
168
170
 
169
- const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error })
171
+ const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }, { ignoreTrailingSlash: this[kIgnoreTrailingSlash] })
170
172
  return new MockScope(newMockDispatch)
171
173
  }
172
174
 
@@ -10,7 +10,8 @@ const {
10
10
  kOriginalClose,
11
11
  kOrigin,
12
12
  kOriginalDispatch,
13
- kConnected
13
+ kConnected,
14
+ kIgnoreTrailingSlash
14
15
  } = require('./mock-symbols')
15
16
  const { MockInterceptor } = require('./mock-interceptor')
16
17
  const Symbols = require('../core/symbols')
@@ -29,6 +30,7 @@ class MockPool extends Pool {
29
30
 
30
31
  this[kMockAgent] = opts.agent
31
32
  this[kOrigin] = origin
33
+ this[kIgnoreTrailingSlash] = opts.ignoreTrailingSlash ?? false
32
34
  this[kDispatches] = []
33
35
  this[kConnected] = 1
34
36
  this[kOriginalDispatch] = this.dispatch
@@ -46,7 +48,10 @@ class MockPool extends Pool {
46
48
  * Sets up the base interceptor for mocking replies from undici.
47
49
  */
48
50
  intercept (opts) {
49
- return new MockInterceptor(opts, this[kDispatches])
51
+ return new MockInterceptor(
52
+ opts && { ignoreTrailingSlash: this[kIgnoreTrailingSlash], ...opts },
53
+ this[kDispatches]
54
+ )
50
55
  }
51
56
 
52
57
  async [kClose] () {
@@ -20,5 +20,6 @@ module.exports = {
20
20
  kIsMockActive: Symbol('is mock active'),
21
21
  kNetConnect: Symbol('net connect'),
22
22
  kGetNetConnect: Symbol('get net connect'),
23
- kConnected: Symbol('connected')
23
+ kConnected: Symbol('connected'),
24
+ kIgnoreTrailingSlash: Symbol('ignore trailing slash')
24
25
  }
@@ -8,7 +8,7 @@ const {
8
8
  kOrigin,
9
9
  kGetNetConnect
10
10
  } = require('./mock-symbols')
11
- const { buildURL } = require('../core/util')
11
+ const { serializePathWithQuery } = require('../core/util')
12
12
  const { STATUS_CODES } = require('node:http')
13
13
  const {
14
14
  types: {
@@ -118,6 +118,10 @@ function matchKey (mockDispatch, { path, method, body, headers }) {
118
118
  function getResponseData (data) {
119
119
  if (Buffer.isBuffer(data)) {
120
120
  return data
121
+ } else if (data instanceof Uint8Array) {
122
+ return data
123
+ } else if (data instanceof ArrayBuffer) {
124
+ return data
121
125
  } else if (typeof data === 'object') {
122
126
  return JSON.stringify(data)
123
127
  } else {
@@ -126,11 +130,19 @@ function getResponseData (data) {
126
130
  }
127
131
 
128
132
  function getMockDispatch (mockDispatches, key) {
129
- const basePath = key.query ? buildURL(key.path, key.query) : key.path
133
+ const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path
130
134
  const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath
131
135
 
136
+ const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath)
137
+
132
138
  // Match path
133
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath))
139
+ let matchedMockDispatches = mockDispatches
140
+ .filter(({ consumed }) => !consumed)
141
+ .filter(({ path, ignoreTrailingSlash }) => {
142
+ return ignoreTrailingSlash
143
+ ? matchValue(removeTrailingSlash(safeUrl(path)), resolvedPathWithoutTrailingSlash)
144
+ : matchValue(safeUrl(path), resolvedPath)
145
+ })
134
146
  if (matchedMockDispatches.length === 0) {
135
147
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`)
136
148
  }
@@ -157,8 +169,8 @@ function getMockDispatch (mockDispatches, key) {
157
169
  return matchedMockDispatches[0]
158
170
  }
159
171
 
160
- function addMockDispatch (mockDispatches, key, data) {
161
- const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false }
172
+ function addMockDispatch (mockDispatches, key, data, opts) {
173
+ const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false, ...opts }
162
174
  const replyData = typeof data === 'function' ? { callback: data } : { ...data }
163
175
  const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } }
164
176
  mockDispatches.push(newMockDispatch)
@@ -177,8 +189,24 @@ function deleteMockDispatch (mockDispatches, key) {
177
189
  }
178
190
  }
179
191
 
192
+ /**
193
+ * @param {string} path Path to remove trailing slash from
194
+ */
195
+ function removeTrailingSlash (path) {
196
+ while (path.endsWith('/')) {
197
+ path = path.slice(0, -1)
198
+ }
199
+
200
+ if (path.length === 0) {
201
+ path = '/'
202
+ }
203
+
204
+ return path
205
+ }
206
+
180
207
  function buildKey (opts) {
181
208
  const { path, method, body, headers, query } = opts
209
+
182
210
  return {
183
211
  path,
184
212
  method,
@@ -14,9 +14,6 @@
14
14
  * Consequently, timers may trigger later than their scheduled time.
15
15
  */
16
16
 
17
- const nativeSetTimeout = global.setTimeout
18
- const nativeClearTimeout = global.clearTimeout
19
-
20
17
  /**
21
18
  * The fastNow variable contains the internal fast timer clock value.
22
19
  *
@@ -340,14 +337,14 @@ module.exports = {
340
337
  // If the delay is less than or equal to the RESOLUTION_MS value return a
341
338
  // native Node.js Timer instance.
342
339
  return delay <= RESOLUTION_MS
343
- ? nativeSetTimeout(callback, delay, arg)
340
+ ? setTimeout(callback, delay, arg)
344
341
  : new FastTimer(callback, delay, arg)
345
342
  },
346
343
  /**
347
344
  * The clearTimeout method cancels an instantiated Timer previously created
348
345
  * by calling setTimeout.
349
346
  *
350
- * @param {FastTimer} timeout
347
+ * @param {NodeJS.Timeout|FastTimer} timeout
351
348
  */
352
349
  clearTimeout (timeout) {
353
350
  // If the timeout is a FastTimer, call its own clear method.
@@ -359,9 +356,32 @@ module.exports = {
359
356
  // Otherwise it is an instance of a native NodeJS.Timeout, so call the
360
357
  // Node.js native clearTimeout function.
361
358
  } else {
362
- nativeClearTimeout(timeout)
359
+ clearTimeout(timeout)
363
360
  }
364
361
  },
362
+ /**
363
+ * The setFastTimeout() method sets a fastTimer which executes a function once
364
+ * the timer expires.
365
+ * @param {Function} callback A function to be executed after the timer
366
+ * expires.
367
+ * @param {number} delay The time, in milliseconds that the timer should
368
+ * wait before the specified function or code is executed.
369
+ * @param {*} [arg] An optional argument to be passed to the callback function
370
+ * when the timer expires.
371
+ * @returns {FastTimer}
372
+ */
373
+ setFastTimeout (callback, delay, arg) {
374
+ return new FastTimer(callback, delay, arg)
375
+ },
376
+ /**
377
+ * The clearTimeout method cancels an instantiated FastTimer previously
378
+ * created by calling setFastTimeout.
379
+ *
380
+ * @param {FastTimer} timeout
381
+ */
382
+ clearFastTimeout (timeout) {
383
+ timeout.clear()
384
+ },
365
385
  /**
366
386
  * The now method returns the value of the internal fast timer clock.
367
387
  *
@@ -370,6 +390,30 @@ module.exports = {
370
390
  now () {
371
391
  return fastNow
372
392
  },
393
+ /**
394
+ * Trigger the onTick function to process the fastTimers array.
395
+ * Exported for testing purposes only.
396
+ * Marking as deprecated to discourage any use outside of testing.
397
+ * @deprecated
398
+ * @param {number} [delay=0] The delay in milliseconds to add to the now value.
399
+ */
400
+ tick (delay = 0) {
401
+ fastNow += delay - RESOLUTION_MS + 1
402
+ onTick()
403
+ onTick()
404
+ },
405
+ /**
406
+ * Reset FastTimers.
407
+ * Exported for testing purposes only.
408
+ * Marking as deprecated to discourage any use outside of testing.
409
+ * @deprecated
410
+ */
411
+ reset () {
412
+ fastNow = 0
413
+ fastTimers.length = 0
414
+ clearTimeout(fastNowTimeout)
415
+ fastNowTimeout = null
416
+ },
373
417
  /**
374
418
  * Exporting for testing purposes only.
375
419
  * Marking as deprecated to discourage any use outside of testing.
@@ -1,12 +1,11 @@
1
1
  'use strict'
2
2
 
3
- const { kConstruct } = require('./symbols')
3
+ const { kConstruct } = require('../../core/symbols')
4
4
  const { urlEquals, getFieldValues } = require('./util')
5
5
  const { kEnumerableProperty, isDisturbed } = require('../../core/util')
6
6
  const { webidl } = require('../fetch/webidl')
7
- const { Response, cloneResponse, fromInnerResponse } = require('../fetch/response')
8
- const { Request, fromInnerRequest } = require('../fetch/request')
9
- const { kState } = require('../fetch/symbols')
7
+ const { cloneResponse, fromInnerResponse, getResponseState } = require('../fetch/response')
8
+ const { Request, fromInnerRequest, getRequestState } = require('../fetch/request')
10
9
  const { fetching } = require('../fetch/index')
11
10
  const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = require('../fetch/util')
12
11
  const assert = require('node:assert')
@@ -115,7 +114,7 @@ class Cache {
115
114
  }
116
115
 
117
116
  // 3.1
118
- const r = request[kState]
117
+ const r = getRequestState(request)
119
118
 
120
119
  // 3.2
121
120
  if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') {
@@ -133,7 +132,7 @@ class Cache {
133
132
  // 5.
134
133
  for (const request of requests) {
135
134
  // 5.1
136
- const r = new Request(request)[kState]
135
+ const r = getRequestState(new Request(request))
137
136
 
138
137
  // 5.2
139
138
  if (!urlIsHttpHttpsScheme(r.url)) {
@@ -269,10 +268,10 @@ class Cache {
269
268
  let innerRequest = null
270
269
 
271
270
  // 2.
272
- if (request instanceof Request) {
273
- innerRequest = request[kState]
271
+ if (webidl.is.Request(request)) {
272
+ innerRequest = getRequestState(request)
274
273
  } else { // 3.
275
- innerRequest = new Request(request)[kState]
274
+ innerRequest = getRequestState(new Request(request))
276
275
  }
277
276
 
278
277
  // 4.
@@ -284,7 +283,7 @@ class Cache {
284
283
  }
285
284
 
286
285
  // 5.
287
- const innerResponse = response[kState]
286
+ const innerResponse = getResponseState(response)
288
287
 
289
288
  // 6.
290
289
  if (innerResponse.status === 206) {
@@ -334,7 +333,7 @@ class Cache {
334
333
  const reader = stream.getReader()
335
334
 
336
335
  // 11.3
337
- readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject)
336
+ readAllBytes(reader, bodyReadPromise.resolve, bodyReadPromise.reject)
338
337
  } else {
339
338
  bodyReadPromise.resolve(undefined)
340
339
  }
@@ -401,8 +400,8 @@ class Cache {
401
400
  */
402
401
  let r = null
403
402
 
404
- if (request instanceof Request) {
405
- r = request[kState]
403
+ if (webidl.is.Request(request)) {
404
+ r = getRequestState(request)
406
405
 
407
406
  if (r.method !== 'GET' && !options.ignoreMethod) {
408
407
  return false
@@ -410,7 +409,7 @@ class Cache {
410
409
  } else {
411
410
  assert(typeof request === 'string')
412
411
 
413
- r = new Request(request)[kState]
412
+ r = getRequestState(new Request(request))
414
413
  }
415
414
 
416
415
  /** @type {CacheBatchOperation[]} */
@@ -467,16 +466,16 @@ class Cache {
467
466
  // 2.
468
467
  if (request !== undefined) {
469
468
  // 2.1
470
- if (request instanceof Request) {
469
+ if (webidl.is.Request(request)) {
471
470
  // 2.1.1
472
- r = request[kState]
471
+ r = getRequestState(request)
473
472
 
474
473
  // 2.1.2
475
474
  if (r.method !== 'GET' && !options.ignoreMethod) {
476
475
  return []
477
476
  }
478
477
  } else if (typeof request === 'string') { // 2.2
479
- r = new Request(request)[kState]
478
+ r = getRequestState(new Request(request))
480
479
  }
481
480
  }
482
481
 
@@ -514,6 +513,7 @@ class Cache {
514
513
  for (const request of requests) {
515
514
  const requestObject = fromInnerRequest(
516
515
  request,
516
+ undefined,
517
517
  new AbortController().signal,
518
518
  'immutable'
519
519
  )
@@ -748,9 +748,9 @@ class Cache {
748
748
 
749
749
  // 2.
750
750
  if (request !== undefined) {
751
- if (request instanceof Request) {
751
+ if (webidl.is.Request(request)) {
752
752
  // 2.1.1
753
- r = request[kState]
753
+ r = getRequestState(request)
754
754
 
755
755
  // 2.1.2
756
756
  if (r.method !== 'GET' && !options.ignoreMethod) {
@@ -758,7 +758,7 @@ class Cache {
758
758
  }
759
759
  } else if (typeof request === 'string') {
760
760
  // 2.2.1
761
- r = new Request(request)[kState]
761
+ r = getRequestState(new Request(request))
762
762
  }
763
763
  }
764
764
 
@@ -847,7 +847,10 @@ webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([
847
847
  }
848
848
  ])
849
849
 
850
- webidl.converters.Response = webidl.interfaceConverter(Response)
850
+ webidl.converters.Response = webidl.interfaceConverter(
851
+ webidl.is.Response,
852
+ 'Response'
853
+ )
851
854
 
852
855
  webidl.converters['sequence<RequestInfo>'] = webidl.sequenceConverter(
853
856
  webidl.converters.RequestInfo
@@ -1,9 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const { kConstruct } = require('./symbols')
4
3
  const { Cache } = require('./cache')
5
4
  const { webidl } = require('../fetch/webidl')
6
5
  const { kEnumerableProperty } = require('../../core/util')
6
+ const { kConstruct } = require('../../core/symbols')
7
7
 
8
8
  class CacheStorage {
9
9
  /**
@@ -5,6 +5,8 @@ const { stringify } = require('./util')
5
5
  const { webidl } = require('../fetch/webidl')
6
6
  const { Headers } = require('../fetch/headers')
7
7
 
8
+ const brandChecks = webidl.brandCheckMultiple([Headers, globalThis.Headers].filter(Boolean))
9
+
8
10
  /**
9
11
  * @typedef {Object} Cookie
10
12
  * @property {string} name
@@ -26,7 +28,7 @@ const { Headers } = require('../fetch/headers')
26
28
  function getCookies (headers) {
27
29
  webidl.argumentLengthCheck(arguments, 1, 'getCookies')
28
30
 
29
- webidl.brandCheckMultiple(headers, [Headers, globalThis.Headers])
31
+ brandChecks(headers)
30
32
 
31
33
  const cookie = headers.get('cookie')
32
34
 
@@ -53,7 +55,7 @@ function getCookies (headers) {
53
55
  * @returns {void}
54
56
  */
55
57
  function deleteCookie (headers, name, attributes) {
56
- webidl.brandCheckMultiple(headers, [Headers, globalThis.Headers])
58
+ brandChecks(headers)
57
59
 
58
60
  const prefix = 'deleteCookie'
59
61
  webidl.argumentLengthCheck(arguments, 2, prefix)
@@ -78,7 +80,7 @@ function deleteCookie (headers, name, attributes) {
78
80
  function getSetCookies (headers) {
79
81
  webidl.argumentLengthCheck(arguments, 1, 'getSetCookies')
80
82
 
81
- webidl.brandCheckMultiple(headers, [Headers, globalThis.Headers])
83
+ brandChecks(headers)
82
84
 
83
85
  const cookies = headers.getSetCookie()
84
86
 
@@ -97,7 +99,7 @@ function getSetCookies (headers) {
97
99
  function setCookie (headers, cookie) {
98
100
  webidl.argumentLengthCheck(arguments, 2, 'setCookie')
99
101
 
100
- webidl.brandCheckMultiple(headers, [Headers, globalThis.Headers])
102
+ brandChecks(headers)
101
103
 
102
104
  cookie = webidl.converters.Cookie(cookie)
103
105