undici 6.13.0 → 6.14.0

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 (38) hide show
  1. package/docs/docs/api/EnvHttpProxyAgent.md +162 -0
  2. package/docs/docs/api/EventSource.md +27 -3
  3. package/docs/docs/api/Fetch.md +0 -6
  4. package/index.js +3 -1
  5. package/lib/api/util.js +14 -7
  6. package/lib/core/request.js +3 -5
  7. package/lib/core/symbols.js +4 -1
  8. package/lib/core/util.js +45 -20
  9. package/lib/dispatcher/client-h2.js +2 -4
  10. package/lib/dispatcher/client.js +2 -1
  11. package/lib/dispatcher/dispatcher-base.js +1 -3
  12. package/lib/dispatcher/env-http-proxy-agent.js +160 -0
  13. package/lib/dispatcher/pool.js +1 -1
  14. package/lib/llhttp/.gitkeep +0 -0
  15. package/lib/llhttp/llhttp-wasm.js +3 -1
  16. package/lib/llhttp/llhttp_simd-wasm.js +3 -1
  17. package/lib/web/cache/cache.js +2 -3
  18. package/lib/web/eventsource/eventsource.js +35 -38
  19. package/lib/web/fetch/body.js +12 -10
  20. package/lib/web/fetch/file.js +5 -216
  21. package/lib/web/fetch/formdata-parser.js +2 -2
  22. package/lib/web/fetch/formdata.js +3 -3
  23. package/lib/web/fetch/index.js +3 -6
  24. package/lib/web/fetch/request.js +8 -26
  25. package/lib/web/fetch/response.js +9 -22
  26. package/lib/web/fetch/symbols.js +0 -1
  27. package/lib/web/fetch/util.js +34 -8
  28. package/lib/web/websocket/util.js +6 -13
  29. package/package.json +4 -3
  30. package/types/dispatcher.d.ts +1 -1
  31. package/types/env-http-proxy-agent.d.ts +21 -0
  32. package/types/eventsource.d.ts +4 -2
  33. package/types/index.d.ts +2 -1
  34. package/lib/llhttp/constants.d.ts +0 -199
  35. package/lib/llhttp/constants.js.map +0 -1
  36. package/lib/llhttp/utils.d.ts +0 -4
  37. package/lib/llhttp/utils.js.map +0 -1
  38. package/lib/llhttp/wasm_build_env.txt +0 -32
@@ -1,100 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const { EOL } = require('node:os')
4
- const { Blob, File: NativeFile } = require('node:buffer')
5
- const { types } = require('node:util')
3
+ const { Blob, File } = require('node:buffer')
6
4
  const { kState } = require('./symbols')
7
- const { isBlobLike } = require('./util')
8
5
  const { webidl } = require('./webidl')
9
- const { parseMIMEType, serializeAMimeType } = require('./data-url')
10
- const { kEnumerableProperty } = require('../../core/util')
11
-
12
- const encoder = new TextEncoder()
13
-
14
- class File extends Blob {
15
- constructor (fileBits, fileName, options = {}) {
16
- // The File constructor is invoked with two or three parameters, depending
17
- // on whether the optional dictionary parameter is used. When the File()
18
- // constructor is invoked, user agents must run the following steps:
19
- webidl.argumentLengthCheck(arguments, 2, { header: 'File constructor' })
20
-
21
- fileBits = webidl.converters['sequence<BlobPart>'](fileBits)
22
- fileName = webidl.converters.USVString(fileName)
23
- options = webidl.converters.FilePropertyBag(options)
24
-
25
- // 1. Let bytes be the result of processing blob parts given fileBits and
26
- // options.
27
- // Note: Blob handles this for us
28
-
29
- // 2. Let n be the fileName argument to the constructor.
30
- const n = fileName
31
-
32
- // 3. Process FilePropertyBag dictionary argument by running the following
33
- // substeps:
34
-
35
- // 1. If the type member is provided and is not the empty string, let t
36
- // be set to the type dictionary member. If t contains any characters
37
- // outside the range U+0020 to U+007E, then set t to the empty string
38
- // and return from these substeps.
39
- // 2. Convert every character in t to ASCII lowercase.
40
- let t = options.type
41
- let d
42
-
43
- // eslint-disable-next-line no-labels
44
- substep: {
45
- if (t) {
46
- t = parseMIMEType(t)
47
-
48
- if (t === 'failure') {
49
- t = ''
50
- // eslint-disable-next-line no-labels
51
- break substep
52
- }
53
-
54
- t = serializeAMimeType(t).toLowerCase()
55
- }
56
-
57
- // 3. If the lastModified member is provided, let d be set to the
58
- // lastModified dictionary member. If it is not provided, set d to the
59
- // current date and time represented as the number of milliseconds since
60
- // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]).
61
- d = options.lastModified
62
- }
63
-
64
- // 4. Return a new File object F such that:
65
- // F refers to the bytes byte sequence.
66
- // F.size is set to the number of total bytes in bytes.
67
- // F.name is set to n.
68
- // F.type is set to t.
69
- // F.lastModified is set to d.
70
-
71
- super(processBlobParts(fileBits, options), { type: t })
72
- this[kState] = {
73
- name: n,
74
- lastModified: d,
75
- type: t
76
- }
77
- }
78
-
79
- get name () {
80
- webidl.brandCheck(this, File)
81
-
82
- return this[kState].name
83
- }
84
-
85
- get lastModified () {
86
- webidl.brandCheck(this, File)
87
-
88
- return this[kState].lastModified
89
- }
90
-
91
- get type () {
92
- webidl.brandCheck(this, File)
93
-
94
- return this[kState].type
95
- }
96
- }
97
6
 
7
+ // TODO(@KhafraDev): remove
98
8
  class FileLike {
99
9
  constructor (blobLike, fileName, options = {}) {
100
10
  // TODO: argument idl type check
@@ -196,136 +106,15 @@ class FileLike {
196
106
  }
197
107
  }
198
108
 
199
- Object.defineProperties(File.prototype, {
200
- [Symbol.toStringTag]: {
201
- value: 'File',
202
- configurable: true
203
- },
204
- name: kEnumerableProperty,
205
- lastModified: kEnumerableProperty
206
- })
207
-
208
109
  webidl.converters.Blob = webidl.interfaceConverter(Blob)
209
110
 
210
- webidl.converters.BlobPart = function (V, opts) {
211
- if (webidl.util.Type(V) === 'Object') {
212
- if (isBlobLike(V)) {
213
- return webidl.converters.Blob(V, { strict: false })
214
- }
215
-
216
- if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) {
217
- return webidl.converters.BufferSource(V, opts)
218
- }
219
- }
220
-
221
- return webidl.converters.USVString(V, opts)
222
- }
223
-
224
- webidl.converters['sequence<BlobPart>'] = webidl.sequenceConverter(
225
- webidl.converters.BlobPart
226
- )
227
-
228
- // https://www.w3.org/TR/FileAPI/#dfn-FilePropertyBag
229
- webidl.converters.FilePropertyBag = webidl.dictionaryConverter([
230
- {
231
- key: 'lastModified',
232
- converter: webidl.converters['long long'],
233
- get defaultValue () {
234
- return Date.now()
235
- }
236
- },
237
- {
238
- key: 'type',
239
- converter: webidl.converters.DOMString,
240
- defaultValue: ''
241
- },
242
- {
243
- key: 'endings',
244
- converter: (value) => {
245
- value = webidl.converters.DOMString(value)
246
- value = value.toLowerCase()
247
-
248
- if (value !== 'native') {
249
- value = 'transparent'
250
- }
251
-
252
- return value
253
- },
254
- defaultValue: 'transparent'
255
- }
256
- ])
257
-
258
- /**
259
- * @see https://www.w3.org/TR/FileAPI/#process-blob-parts
260
- * @param {(NodeJS.TypedArray|Blob|string)[]} parts
261
- * @param {{ type: string, endings: string }} options
262
- */
263
- function processBlobParts (parts, options) {
264
- // 1. Let bytes be an empty sequence of bytes.
265
- /** @type {NodeJS.TypedArray[]} */
266
- const bytes = []
267
-
268
- // 2. For each element in parts:
269
- for (const element of parts) {
270
- // 1. If element is a USVString, run the following substeps:
271
- if (typeof element === 'string') {
272
- // 1. Let s be element.
273
- let s = element
274
-
275
- // 2. If the endings member of options is "native", set s
276
- // to the result of converting line endings to native
277
- // of element.
278
- if (options.endings === 'native') {
279
- s = convertLineEndingsNative(s)
280
- }
281
-
282
- // 3. Append the result of UTF-8 encoding s to bytes.
283
- bytes.push(encoder.encode(s))
284
- } else if (ArrayBuffer.isView(element) || types.isArrayBuffer(element)) {
285
- // 2. If element is a BufferSource, get a copy of the
286
- // bytes held by the buffer source, and append those
287
- // bytes to bytes.
288
- if (element.buffer) {
289
- bytes.push(
290
- new Uint8Array(element.buffer, element.byteOffset, element.byteLength)
291
- )
292
- } else { // ArrayBuffer
293
- bytes.push(new Uint8Array(element))
294
- }
295
- } else if (isBlobLike(element)) {
296
- // 3. If element is a Blob, append the bytes it represents
297
- // to bytes.
298
- bytes.push(element)
299
- }
300
- }
301
-
302
- // 3. Return bytes.
303
- return bytes
304
- }
305
-
306
- /**
307
- * @see https://www.w3.org/TR/FileAPI/#convert-line-endings-to-native
308
- * @param {string} s
309
- */
310
- function convertLineEndingsNative (s) {
311
- // 1. Let native line ending be be the code point U+000A LF.
312
- // 2. If the underlying platform’s conventions are to
313
- // represent newlines as a carriage return and line feed
314
- // sequence, set native line ending to the code point
315
- // U+000D CR followed by the code point U+000A LF.
316
- // NOTE: We are using the native line ending for the current
317
- // platform, provided by node's os module.
318
-
319
- return s.replace(/\r?\n/g, EOL)
320
- }
321
-
322
111
  // If this function is moved to ./util.js, some tools (such as
323
112
  // rollup) will warn about circular dependencies. See:
324
113
  // https://github.com/nodejs/undici/issues/1629
325
114
  function isFileLike (object) {
326
115
  return (
327
- (NativeFile && object instanceof NativeFile) ||
328
- object instanceof File || (
116
+ (object instanceof File) ||
117
+ (
329
118
  object &&
330
119
  (typeof object.stream === 'function' ||
331
120
  typeof object.arrayBuffer === 'function') &&
@@ -334,4 +123,4 @@ function isFileLike (object) {
334
123
  )
335
124
  }
336
125
 
337
- module.exports = { File, FileLike, isFileLike }
126
+ module.exports = { FileLike, isFileLike }
@@ -3,12 +3,12 @@
3
3
  const { isUSVString, bufferToLowerCasedHeaderName } = require('../../core/util')
4
4
  const { utf8DecodeBytes } = require('./util')
5
5
  const { HTTP_TOKEN_CODEPOINTS, isomorphicDecode } = require('./data-url')
6
- const { isFileLike, File: UndiciFile } = require('./file')
6
+ const { isFileLike } = require('./file')
7
7
  const { makeEntry } = require('./formdata')
8
8
  const assert = require('node:assert')
9
9
  const { File: NodeFile } = require('node:buffer')
10
10
 
11
- const File = globalThis.File ?? NodeFile ?? UndiciFile
11
+ const File = globalThis.File ?? NodeFile
12
12
 
13
13
  const formDataNameBuffer = Buffer.from('form-data; name="')
14
14
  const filenameBuffer = Buffer.from('; filename')
@@ -3,13 +3,13 @@
3
3
  const { isBlobLike, iteratorMixin } = require('./util')
4
4
  const { kState } = require('./symbols')
5
5
  const { kEnumerableProperty } = require('../../core/util')
6
- const { File: UndiciFile, FileLike, isFileLike } = require('./file')
6
+ const { FileLike, isFileLike } = require('./file')
7
7
  const { webidl } = require('./webidl')
8
8
  const { File: NativeFile } = require('node:buffer')
9
9
  const nodeUtil = require('node:util')
10
10
 
11
11
  /** @type {globalThis['File']} */
12
- const File = NativeFile ?? UndiciFile
12
+ const File = globalThis.File ?? NativeFile
13
13
 
14
14
  // https://xhr.spec.whatwg.org/#formdata
15
15
  class FormData {
@@ -231,7 +231,7 @@ function makeEntry (name, value, filename) {
231
231
  lastModified: value.lastModified
232
232
  }
233
233
 
234
- value = (NativeFile && value instanceof NativeFile) || value instanceof UndiciFile
234
+ value = value instanceof NativeFile
235
235
  ? new File([value], filename, options)
236
236
  : new FileLike(value, filename, options)
237
237
  }
@@ -59,7 +59,7 @@ const {
59
59
  } = require('./constants')
60
60
  const EE = require('node:events')
61
61
  const { Readable, pipeline, finished } = require('node:stream')
62
- const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor, bufferToLowerCasedHeaderName } = require('../../core/util')
62
+ const { addAbortListener, isErrored, isReadable, bufferToLowerCasedHeaderName } = require('../../core/util')
63
63
  const { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = require('./data-url')
64
64
  const { getGlobalDispatcher } = require('../../global')
65
65
  const { webidl } = require('./webidl')
@@ -165,7 +165,6 @@ function fetch (input, init = undefined) {
165
165
  let responseObject = null
166
166
 
167
167
  // 8. Let relevantRealm be this’s relevant Realm.
168
- const relevantRealm = null
169
168
 
170
169
  // 9. Let locallyAborted be false.
171
170
  let locallyAborted = false
@@ -229,7 +228,7 @@ function fetch (input, init = undefined) {
229
228
 
230
229
  // 4. Set responseObject to the result of creating a Response object,
231
230
  // given response, "immutable", and relevantRealm.
232
- responseObject = fromInnerResponse(response, 'immutable', relevantRealm)
231
+ responseObject = fromInnerResponse(response, 'immutable')
233
232
 
234
233
  // 5. Resolve p with responseObject.
235
234
  p.resolve(responseObject)
@@ -310,9 +309,7 @@ function finalizeAndReportTiming (response, initiatorType = 'other') {
310
309
  }
311
310
 
312
311
  // https://w3c.github.io/resource-timing/#dfn-mark-resource-timing
313
- const markResourceTiming = (nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 2))
314
- ? performance.markResourceTiming
315
- : () => {}
312
+ const markResourceTiming = performance.markResourceTiming
316
313
 
317
314
  // https://fetch.spec.whatwg.org/#abort-fetch
318
315
  function abortFetch (p, request, responseObject, error) {
@@ -11,7 +11,7 @@ const {
11
11
  isValidHTTPToken,
12
12
  sameOrigin,
13
13
  normalizeMethod,
14
- makePolicyContainer,
14
+ environmentSettingsObject,
15
15
  normalizeMethodRecord
16
16
  } = require('./util')
17
17
  const {
@@ -25,9 +25,8 @@ const {
25
25
  requestDuplex
26
26
  } = require('./constants')
27
27
  const { kEnumerableProperty } = util
28
- const { kHeaders, kSignal, kState, kGuard, kRealm, kDispatcher } = require('./symbols')
28
+ const { kHeaders, kSignal, kState, kGuard, kDispatcher } = require('./symbols')
29
29
  const { webidl } = require('./webidl')
30
- const { getGlobalOrigin } = require('./global')
31
30
  const { URLSerializer } = require('./data-url')
32
31
  const { kHeadersList, kConstruct } = require('../../core/symbols')
33
32
  const assert = require('node:assert')
@@ -54,17 +53,6 @@ class Request {
54
53
  input = webidl.converters.RequestInfo(input)
55
54
  init = webidl.converters.RequestInit(init)
56
55
 
57
- // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object
58
- this[kRealm] = {
59
- settingsObject: {
60
- baseUrl: getGlobalOrigin(),
61
- get origin () {
62
- return this.baseUrl?.origin
63
- },
64
- policyContainer: makePolicyContainer()
65
- }
66
- }
67
-
68
56
  // 1. Let request be null.
69
57
  let request = null
70
58
 
@@ -72,7 +60,7 @@ class Request {
72
60
  let fallbackMode = null
73
61
 
74
62
  // 3. Let baseURL be this’s relevant settings object’s API base URL.
75
- const baseUrl = this[kRealm].settingsObject.baseUrl
63
+ const baseUrl = environmentSettingsObject.settingsObject.baseUrl
76
64
 
77
65
  // 4. Let signal be null.
78
66
  let signal = null
@@ -119,7 +107,7 @@ class Request {
119
107
  }
120
108
 
121
109
  // 7. Let origin be this’s relevant settings object’s origin.
122
- const origin = this[kRealm].settingsObject.origin
110
+ const origin = environmentSettingsObject.settingsObject.origin
123
111
 
124
112
  // 8. Let window be "client".
125
113
  let window = 'client'
@@ -155,7 +143,7 @@ class Request {
155
143
  // unsafe-request flag Set.
156
144
  unsafeRequest: request.unsafeRequest,
157
145
  // client This’s relevant settings object.
158
- client: this[kRealm].settingsObject,
146
+ client: environmentSettingsObject.settingsObject,
159
147
  // window window.
160
148
  window,
161
149
  // priority request’s priority.
@@ -244,7 +232,7 @@ class Request {
244
232
  // then set request’s referrer to "client".
245
233
  if (
246
234
  (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') ||
247
- (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl))
235
+ (origin && !sameOrigin(parsedReferrer, environmentSettingsObject.settingsObject.baseUrl))
248
236
  ) {
249
237
  request.referrer = 'client'
250
238
  } else {
@@ -366,7 +354,6 @@ class Request {
366
354
  // (https://dom.spec.whatwg.org/#dom-abortsignal-any)
367
355
  const ac = new AbortController()
368
356
  this[kSignal] = ac.signal
369
- this[kSignal][kRealm] = this[kRealm]
370
357
 
371
358
  // 29. If signal is not null, then make this’s signal follow signal.
372
359
  if (signal != null) {
@@ -436,7 +423,6 @@ class Request {
436
423
  this[kHeaders] = new Headers(kConstruct)
437
424
  this[kHeaders][kHeadersList] = request.headersList
438
425
  this[kHeaders][kGuard] = 'request'
439
- this[kHeaders][kRealm] = this[kRealm]
440
426
 
441
427
  // 31. If this’s request’s mode is "no-cors", then:
442
428
  if (mode === 'no-cors') {
@@ -770,7 +756,7 @@ class Request {
770
756
  }
771
757
 
772
758
  // 4. Return clonedRequestObject.
773
- return fromInnerRequest(clonedRequest, ac.signal, this[kHeaders][kGuard], this[kRealm])
759
+ return fromInnerRequest(clonedRequest, ac.signal, this[kHeaders][kGuard])
774
760
  }
775
761
 
776
762
  [nodeUtil.inspect.custom] (depth, options) {
@@ -873,19 +859,15 @@ function cloneRequest (request) {
873
859
  * @param {any} innerRequest
874
860
  * @param {AbortSignal} signal
875
861
  * @param {'request' | 'immutable' | 'request-no-cors' | 'response' | 'none'} guard
876
- * @param {any} [realm]
877
862
  * @returns {Request}
878
863
  */
879
- function fromInnerRequest (innerRequest, signal, guard, realm) {
864
+ function fromInnerRequest (innerRequest, signal, guard) {
880
865
  const request = new Request(kConstruct)
881
866
  request[kState] = innerRequest
882
- request[kRealm] = realm
883
867
  request[kSignal] = signal
884
- request[kSignal][kRealm] = realm
885
868
  request[kHeaders] = new Headers(kConstruct)
886
869
  request[kHeaders][kHeadersList] = innerRequest.headersList
887
870
  request[kHeaders][kGuard] = guard
888
- request[kHeaders][kRealm] = realm
889
871
  return request
890
872
  }
891
873
 
@@ -12,16 +12,16 @@ const {
12
12
  isBlobLike,
13
13
  serializeJavascriptValueToJSONString,
14
14
  isErrorLike,
15
- isomorphicEncode
15
+ isomorphicEncode,
16
+ environmentSettingsObject: relevantRealm
16
17
  } = require('./util')
17
18
  const {
18
19
  redirectStatusSet,
19
20
  nullBodyStatus
20
21
  } = require('./constants')
21
- const { kState, kHeaders, kGuard, kRealm } = require('./symbols')
22
+ const { kState, kHeaders, kGuard } = require('./symbols')
22
23
  const { webidl } = require('./webidl')
23
24
  const { FormData } = require('./formdata')
24
- const { getGlobalOrigin } = require('./global')
25
25
  const { URLSerializer } = require('./data-url')
26
26
  const { kHeadersList, kConstruct } = require('../../core/symbols')
27
27
  const assert = require('node:assert')
@@ -33,13 +33,10 @@ const textEncoder = new TextEncoder('utf-8')
33
33
  class Response {
34
34
  // Creates network error Response.
35
35
  static error () {
36
- // TODO
37
- const relevantRealm = { settingsObject: {} }
38
-
39
36
  // The static error() method steps are to return the result of creating a
40
37
  // Response object, given a new network error, "immutable", and this’s
41
38
  // relevant Realm.
42
- const responseObject = fromInnerResponse(makeNetworkError(), 'immutable', relevantRealm)
39
+ const responseObject = fromInnerResponse(makeNetworkError(), 'immutable')
43
40
 
44
41
  return responseObject
45
42
  }
@@ -62,8 +59,7 @@ class Response {
62
59
 
63
60
  // 3. Let responseObject be the result of creating a Response object, given a new response,
64
61
  // "response", and this’s relevant Realm.
65
- const relevantRealm = { settingsObject: {} }
66
- const responseObject = fromInnerResponse(makeResponse({}), 'response', relevantRealm)
62
+ const responseObject = fromInnerResponse(makeResponse({}), 'response')
67
63
 
68
64
  // 4. Perform initialize a response given responseObject, init, and (body, "application/json").
69
65
  initializeResponse(responseObject, init, { body: body[0], type: 'application/json' })
@@ -74,8 +70,6 @@ class Response {
74
70
 
75
71
  // Creates a redirect Response that redirects to url with status status.
76
72
  static redirect (url, status = 302) {
77
- const relevantRealm = { settingsObject: {} }
78
-
79
73
  webidl.argumentLengthCheck(arguments, 1, { header: 'Response.redirect' })
80
74
 
81
75
  url = webidl.converters.USVString(url)
@@ -87,7 +81,7 @@ class Response {
87
81
  // TODO: base-URL?
88
82
  let parsedURL
89
83
  try {
90
- parsedURL = new URL(url, getGlobalOrigin())
84
+ parsedURL = new URL(url, relevantRealm.settingsObject.baseUrl)
91
85
  } catch (err) {
92
86
  throw new TypeError(`Failed to parse URL from ${url}`, { cause: err })
93
87
  }
@@ -99,7 +93,7 @@ class Response {
99
93
 
100
94
  // 4. Let responseObject be the result of creating a Response object,
101
95
  // given a new response, "immutable", and this’s relevant Realm.
102
- const responseObject = fromInnerResponse(makeResponse({}), 'immutable', relevantRealm)
96
+ const responseObject = fromInnerResponse(makeResponse({}), 'immutable')
103
97
 
104
98
  // 5. Set responseObject’s response’s status to status.
105
99
  responseObject[kState].status = status
@@ -126,9 +120,6 @@ class Response {
126
120
 
127
121
  init = webidl.converters.ResponseInit(init)
128
122
 
129
- // TODO
130
- this[kRealm] = { settingsObject: {} }
131
-
132
123
  // 1. Set this’s response to a new response.
133
124
  this[kState] = makeResponse({})
134
125
 
@@ -138,7 +129,6 @@ class Response {
138
129
  this[kHeaders] = new Headers(kConstruct)
139
130
  this[kHeaders][kGuard] = 'response'
140
131
  this[kHeaders][kHeadersList] = this[kState].headersList
141
- this[kHeaders][kRealm] = this[kRealm]
142
132
 
143
133
  // 3. Let bodyWithType be null.
144
134
  let bodyWithType = null
@@ -251,7 +241,7 @@ class Response {
251
241
 
252
242
  // 3. Return the result of creating a Response object, given
253
243
  // clonedResponse, this’s headers’s guard, and this’s relevant Realm.
254
- return fromInnerResponse(clonedResponse, this[kHeaders][kGuard], this[kRealm])
244
+ return fromInnerResponse(clonedResponse, this[kHeaders][kGuard])
255
245
  }
256
246
 
257
247
  [nodeUtil.inspect.custom] (depth, options) {
@@ -512,17 +502,14 @@ function initializeResponse (response, init, body) {
512
502
  * @see https://fetch.spec.whatwg.org/#response-create
513
503
  * @param {any} innerResponse
514
504
  * @param {'request' | 'immutable' | 'request-no-cors' | 'response' | 'none'} guard
515
- * @param {any} [realm]
516
505
  * @returns {Response}
517
506
  */
518
- function fromInnerResponse (innerResponse, guard, realm) {
507
+ function fromInnerResponse (innerResponse, guard) {
519
508
  const response = new Response(kConstruct)
520
509
  response[kState] = innerResponse
521
- response[kRealm] = realm
522
510
  response[kHeaders] = new Headers(kConstruct)
523
511
  response[kHeaders][kHeadersList] = innerResponse.headersList
524
512
  response[kHeaders][kGuard] = guard
525
- response[kHeaders][kRealm] = realm
526
513
  return response
527
514
  }
528
515
 
@@ -6,6 +6,5 @@ module.exports = {
6
6
  kSignal: Symbol('signal'),
7
7
  kState: Symbol('state'),
8
8
  kGuard: Symbol('guard'),
9
- kRealm: Symbol('realm'),
10
9
  kDispatcher: Symbol('dispatcher')
11
10
  }
@@ -1043,7 +1043,7 @@ function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, valueInde
1043
1043
  /**
1044
1044
  * @see https://fetch.spec.whatwg.org/#body-fully-read
1045
1045
  */
1046
- async function fullyReadBody (body, processBody, processBodyError) {
1046
+ async function fullyReadBody (body, processBody, processBodyError, shouldClone) {
1047
1047
  // 1. If taskDestination is null, then set taskDestination to
1048
1048
  // the result of starting a new parallel queue.
1049
1049
 
@@ -1069,8 +1069,7 @@ async function fullyReadBody (body, processBody, processBodyError) {
1069
1069
 
1070
1070
  // 5. Read all bytes from reader, given successSteps and errorSteps.
1071
1071
  try {
1072
- const result = await readAllBytes(reader)
1073
- successSteps(result)
1072
+ successSteps(await readAllBytes(reader, shouldClone))
1074
1073
  } catch (e) {
1075
1074
  errorSteps(e)
1076
1075
  }
@@ -1098,15 +1097,15 @@ function readableStreamClose (controller) {
1098
1097
  }
1099
1098
  }
1100
1099
 
1100
+ const invalidIsomorphicEncodeValueRegex = /[^\x00-\xFF]/ // eslint-disable-line
1101
+
1101
1102
  /**
1102
1103
  * @see https://infra.spec.whatwg.org/#isomorphic-encode
1103
1104
  * @param {string} input
1104
1105
  */
1105
1106
  function isomorphicEncode (input) {
1106
1107
  // 1. Assert: input contains no code points greater than U+00FF.
1107
- for (let i = 0; i < input.length; i++) {
1108
- assert(input.charCodeAt(i) <= 0xFF)
1109
- }
1108
+ assert(!invalidIsomorphicEncodeValueRegex.test(input))
1110
1109
 
1111
1110
  // 2. Return a byte sequence whose length is equal to input’s code
1112
1111
  // point length and whose bytes have the same values as the
@@ -1118,8 +1117,9 @@ function isomorphicEncode (input) {
1118
1117
  * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes
1119
1118
  * @see https://streams.spec.whatwg.org/#read-loop
1120
1119
  * @param {ReadableStreamDefaultReader} reader
1120
+ * @param {boolean} [shouldClone]
1121
1121
  */
1122
- async function readAllBytes (reader) {
1122
+ async function readAllBytes (reader, shouldClone) {
1123
1123
  const bytes = []
1124
1124
  let byteLength = 0
1125
1125
 
@@ -1128,6 +1128,13 @@ async function readAllBytes (reader) {
1128
1128
 
1129
1129
  if (done) {
1130
1130
  // 1. Call successSteps with bytes.
1131
+ if (bytes.length === 1) {
1132
+ const { buffer, byteOffset, byteLength } = bytes[0]
1133
+ if (shouldClone === false) {
1134
+ return Buffer.from(buffer, byteOffset, byteLength)
1135
+ }
1136
+ return Buffer.from(buffer.slice(byteOffset, byteOffset + byteLength), 0, byteLength)
1137
+ }
1131
1138
  return Buffer.concat(bytes, byteLength)
1132
1139
  }
1133
1140
 
@@ -1562,6 +1569,24 @@ function utf8DecodeBytes (buffer) {
1562
1569
  return output
1563
1570
  }
1564
1571
 
1572
+ class EnvironmentSettingsObjectBase {
1573
+ get baseUrl () {
1574
+ return getGlobalOrigin()
1575
+ }
1576
+
1577
+ get origin () {
1578
+ return this.baseUrl?.origin
1579
+ }
1580
+
1581
+ policyContainer = makePolicyContainer()
1582
+ }
1583
+
1584
+ class EnvironmentSettingsObject {
1585
+ settingsObject = new EnvironmentSettingsObjectBase()
1586
+ }
1587
+
1588
+ const environmentSettingsObject = new EnvironmentSettingsObject()
1589
+
1565
1590
  module.exports = {
1566
1591
  isAborted,
1567
1592
  isCancelled,
@@ -1613,5 +1638,6 @@ module.exports = {
1613
1638
  createInflate,
1614
1639
  extractMimeType,
1615
1640
  getDecodeSplit,
1616
- utf8DecodeBytes
1641
+ utf8DecodeBytes,
1642
+ environmentSettingsObject
1617
1643
  }
@@ -211,19 +211,12 @@ const fatalDecoder = hasIntl ? new TextDecoder('utf-8', { fatal: true }) : undef
211
211
  */
212
212
  const utf8Decode = hasIntl
213
213
  ? fatalDecoder.decode.bind(fatalDecoder)
214
- : !isUtf8
215
- ? function () { // TODO: remove once node 18 or < node v18.14.0 is dropped
216
- process.emitWarning('ICU is not supported and no fallback exists. Please upgrade to at least Node v18.14.0.', {
217
- code: 'UNDICI-WS-NO-ICU'
218
- })
219
- throw new TypeError('Invalid utf-8 received.')
220
- }
221
- : function (buffer) {
222
- if (isUtf8(buffer)) {
223
- return buffer.toString('utf-8')
224
- }
225
- throw new TypeError('Invalid utf-8 received.')
226
- }
214
+ : function (buffer) {
215
+ if (isUtf8(buffer)) {
216
+ return buffer.toString('utf-8')
217
+ }
218
+ throw new TypeError('Invalid utf-8 received.')
219
+ }
227
220
 
228
221
  module.exports = {
229
222
  isConnecting,