diff --git a/deps/undici/src/README.md b/deps/undici/src/README.md index 3ba89890df6f69..cec6f032e99be3 100644 --- a/deps/undici/src/README.md +++ b/deps/undici/src/README.md @@ -180,8 +180,6 @@ Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method). * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch * https://fetch.spec.whatwg.org/#fetch-method -Only supported on Node 16.8+. - Basic usage example: ```js diff --git a/deps/undici/src/docs/api/BalancedPool.md b/deps/undici/src/docs/api/BalancedPool.md index 290c734c0225f5..183ef523185a90 100644 --- a/deps/undici/src/docs/api/BalancedPool.md +++ b/deps/undici/src/docs/api/BalancedPool.md @@ -50,7 +50,7 @@ Arguments: ### `BalancedPool.removeUpstream(upstream)` -Removes an upstream that was previously addded. +Removes an upstream that was previously added. ### `BalancedPool.close([callback])` diff --git a/deps/undici/src/docs/api/Dispatcher.md b/deps/undici/src/docs/api/Dispatcher.md index fd463bfea16737..0c678fc8623b50 100644 --- a/deps/undici/src/docs/api/Dispatcher.md +++ b/deps/undici/src/docs/api/Dispatcher.md @@ -209,6 +209,7 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo * **onConnect** `(abort: () => void, context: object) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails. * **onError** `(error: Error) => void` - Invoked when an error has occurred. May not throw. * **onUpgrade** `(statusCode: number, headers: Buffer[], socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`. +* **onResponseStarted** `() => void` (optional) - Invoked when response is received, before headers have been read. * **onHeaders** `(statusCode: number, headers: Buffer[], resume: () => void, statusText: string) => boolean` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests. * **onData** `(chunk: Buffer) => boolean` - Invoked when response payload data is received. Not required for `upgrade` requests. * **onComplete** `(trailers: Buffer[]) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests. diff --git a/deps/undici/src/docs/api/Util.md b/deps/undici/src/docs/api/Util.md new file mode 100644 index 00000000000000..2393d079dfcbf1 --- /dev/null +++ b/deps/undici/src/docs/api/Util.md @@ -0,0 +1,25 @@ +# Util + +Utility API for third-party implementations of the dispatcher API. + +## `parseHeaders(headers, [obj])` + +Receives a header object and returns the parsed value. + +Arguments: + +- **headers** `Record | (Buffer | string | (Buffer | string)[])[]` (required) - Header object. + +- **obj** `Record` (optional) - Object to specify a proxy object. The parsed value is assigned to this object. But, if **headers** is an object, it is not used. + +Returns: `Record` If **headers** is an object, it is **headers**. Otherwise, if **obj** is specified, it is equivalent to **obj**. + +## `headerNameToString(value)` + +Retrieves a header name and returns its lowercase value. + +Arguments: + +- **value** `string | Buffer` (required) - Header name. + +Returns: `string` diff --git a/deps/undici/src/index.js b/deps/undici/src/index.js index 26302cc8efa62b..5fc0d9727ef028 100644 --- a/deps/undici/src/index.js +++ b/deps/undici/src/index.js @@ -45,6 +45,10 @@ module.exports.createRedirectInterceptor = createRedirectInterceptor module.exports.buildConnector = buildConnector module.exports.errors = errors +module.exports.util = { + parseHeaders: util.parseHeaders, + headerNameToString: util.headerNameToString +} function makeDispatcher (fn) { return (url, opts, handler) => { @@ -98,58 +102,54 @@ function makeDispatcher (fn) { module.exports.setGlobalDispatcher = setGlobalDispatcher module.exports.getGlobalDispatcher = getGlobalDispatcher -if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) { - let fetchImpl = null - module.exports.fetch = async function fetch (resource) { - if (!fetchImpl) { - fetchImpl = require('./lib/fetch').fetch - } - - try { - return await fetchImpl(...arguments) - } catch (err) { - if (typeof err === 'object') { - Error.captureStackTrace(err, this) - } +let fetchImpl = null +module.exports.fetch = async function fetch (resource) { + if (!fetchImpl) { + fetchImpl = require('./lib/fetch').fetch + } - throw err + try { + return await fetchImpl(...arguments) + } catch (err) { + if (typeof err === 'object') { + Error.captureStackTrace(err, this) } + + throw err } - module.exports.Headers = require('./lib/fetch/headers').Headers - module.exports.Response = require('./lib/fetch/response').Response - module.exports.Request = require('./lib/fetch/request').Request - module.exports.FormData = require('./lib/fetch/formdata').FormData - module.exports.File = require('./lib/fetch/file').File - module.exports.FileReader = require('./lib/fileapi/filereader').FileReader +} +module.exports.Headers = require('./lib/fetch/headers').Headers +module.exports.Response = require('./lib/fetch/response').Response +module.exports.Request = require('./lib/fetch/request').Request +module.exports.FormData = require('./lib/fetch/formdata').FormData +module.exports.File = require('./lib/fetch/file').File +module.exports.FileReader = require('./lib/fileapi/filereader').FileReader - const { setGlobalOrigin, getGlobalOrigin } = require('./lib/fetch/global') +const { setGlobalOrigin, getGlobalOrigin } = require('./lib/fetch/global') - module.exports.setGlobalOrigin = setGlobalOrigin - module.exports.getGlobalOrigin = getGlobalOrigin +module.exports.setGlobalOrigin = setGlobalOrigin +module.exports.getGlobalOrigin = getGlobalOrigin - const { CacheStorage } = require('./lib/cache/cachestorage') - const { kConstruct } = require('./lib/cache/symbols') +const { CacheStorage } = require('./lib/cache/cachestorage') +const { kConstruct } = require('./lib/cache/symbols') - // Cache & CacheStorage are tightly coupled with fetch. Even if it may run - // in an older version of Node, it doesn't have any use without fetch. - module.exports.caches = new CacheStorage(kConstruct) -} +// Cache & CacheStorage are tightly coupled with fetch. Even if it may run +// in an older version of Node, it doesn't have any use without fetch. +module.exports.caches = new CacheStorage(kConstruct) -if (util.nodeMajor >= 16) { - const { deleteCookie, getCookies, getSetCookies, setCookie } = require('./lib/cookies') +const { deleteCookie, getCookies, getSetCookies, setCookie } = require('./lib/cookies') - module.exports.deleteCookie = deleteCookie - module.exports.getCookies = getCookies - module.exports.getSetCookies = getSetCookies - module.exports.setCookie = setCookie +module.exports.deleteCookie = deleteCookie +module.exports.getCookies = getCookies +module.exports.getSetCookies = getSetCookies +module.exports.setCookie = setCookie - const { parseMIMEType, serializeAMimeType } = require('./lib/fetch/dataURL') +const { parseMIMEType, serializeAMimeType } = require('./lib/fetch/dataURL') - module.exports.parseMIMEType = parseMIMEType - module.exports.serializeAMimeType = serializeAMimeType -} +module.exports.parseMIMEType = parseMIMEType +module.exports.serializeAMimeType = serializeAMimeType -if (util.nodeMajor >= 18 && hasCrypto) { +if (hasCrypto) { const { WebSocket } = require('./lib/websocket/websocket') module.exports.WebSocket = WebSocket diff --git a/deps/undici/src/lib/agent.js b/deps/undici/src/lib/agent.js index 0b18f2a91bd2fe..320d7c473d81e6 100644 --- a/deps/undici/src/lib/agent.js +++ b/deps/undici/src/lib/agent.js @@ -7,7 +7,6 @@ const Pool = require('./pool') const Client = require('./client') const util = require('./core/util') const createRedirectInterceptor = require('./interceptor/redirectInterceptor') -const { WeakRef, FinalizationRegistry } = require('./compat/dispatcher-weakref')() const kOnConnect = Symbol('onConnect') const kOnDisconnect = Symbol('onDisconnect') @@ -15,7 +14,6 @@ const kOnConnectionError = Symbol('onConnectionError') const kMaxRedirections = Symbol('maxRedirections') const kOnDrain = Symbol('onDrain') const kFactory = Symbol('factory') -const kFinalizer = Symbol('finalizer') const kOptions = Symbol('options') function defaultFactory (origin, opts) { @@ -55,12 +53,6 @@ class Agent extends DispatcherBase { this[kMaxRedirections] = maxRedirections this[kFactory] = factory this[kClients] = new Map() - this[kFinalizer] = new FinalizationRegistry(/* istanbul ignore next: gc is undeterministic */ key => { - const ref = this[kClients].get(key) - if (ref !== undefined && ref.deref() === undefined) { - this[kClients].delete(key) - } - }) const agent = this @@ -83,12 +75,8 @@ class Agent extends DispatcherBase { get [kRunning] () { let ret = 0 - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore next: gc is undeterministic */ - if (client) { - ret += client[kRunning] - } + for (const client of this[kClients].values()) { + ret += client[kRunning] } return ret } @@ -101,9 +89,8 @@ class Agent extends DispatcherBase { throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') } - const ref = this[kClients].get(key) + let dispatcher = this[kClients].get(key) - let dispatcher = ref ? ref.deref() : null if (!dispatcher) { dispatcher = this[kFactory](opts.origin, this[kOptions]) .on('drain', this[kOnDrain]) @@ -111,8 +98,10 @@ class Agent extends DispatcherBase { .on('disconnect', this[kOnDisconnect]) .on('connectionError', this[kOnConnectionError]) - this[kClients].set(key, new WeakRef(dispatcher)) - this[kFinalizer].register(dispatcher, key) + // This introduces a tiny memory leak, as dispatchers are never removed from the map. + // TODO(mcollina): remove te timer when the client/pool do not have any more + // active connections. + this[kClients].set(key, dispatcher) } return dispatcher.dispatch(opts, handler) @@ -120,26 +109,20 @@ class Agent extends DispatcherBase { async [kClose] () { const closePromises = [] - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore else: gc is undeterministic */ - if (client) { - closePromises.push(client.close()) - } + for (const client of this[kClients].values()) { + closePromises.push(client.close()) } + this[kClients].clear() await Promise.all(closePromises) } async [kDestroy] (err) { const destroyPromises = [] - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore else: gc is undeterministic */ - if (client) { - destroyPromises.push(client.destroy(err)) - } + for (const client of this[kClients].values()) { + destroyPromises.push(client.destroy(err)) } + this[kClients].clear() await Promise.all(destroyPromises) } diff --git a/deps/undici/src/lib/api/readable.js b/deps/undici/src/lib/api/readable.js index 5269dfae50cbad..8ea6d512f60e0a 100644 --- a/deps/undici/src/lib/api/readable.js +++ b/deps/undici/src/lib/api/readable.js @@ -4,11 +4,9 @@ const assert = require('assert') const { Readable } = require('stream') -const { RequestAbortedError, NotSupportedError, InvalidArgumentError } = require('../core/errors') +const { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = require('../core/errors') const util = require('../core/util') -const { ReadableStreamFrom, toUSVString } = require('../core/util') - -let Blob +const { ReadableStreamFrom } = require('../core/util') const kConsume = Symbol('kConsume') const kReading = Symbol('kReading') @@ -46,11 +44,6 @@ module.exports = class BodyReadable extends Readable { } destroy (err) { - if (this.destroyed) { - // Node < 16 - return this - } - if (!err && !this._readableState.endEmitted) { err = new RequestAbortedError() } @@ -62,15 +55,16 @@ module.exports = class BodyReadable extends Readable { return super.destroy(err) } - emit (ev, ...args) { - if (ev === 'data') { - // Node < 16.7 - this._readableState.dataEmitted = true - } else if (ev === 'error') { - // Node < 16 - this._readableState.errorEmitted = true - } - return super.emit(ev, ...args) + _destroy (err, callback) { + // Workaround for Node "bug". If the stream is destroyed in same + // tick as it is created, then a user who is waiting for a + // promise (i.e micro tick) for installing a 'error' listener will + // never get a chance and will always encounter an unhandled exception. + // - tick => process.nextTick(fn) + // - micro tick => queueMicrotask(fn) + queueMicrotask(() => { + callback(err) + }) } on (ev, ...args) { @@ -151,37 +145,31 @@ module.exports = class BodyReadable extends Readable { return this[kBody] } - dump (opts) { - let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 - const signal = opts && opts.signal - - if (signal) { - try { - if (typeof signal !== 'object' || !('aborted' in signal)) { - throw new InvalidArgumentError('signal must be an AbortSignal') - } - util.throwIfAborted(signal) - } catch (err) { - return Promise.reject(err) - } + async dump (opts) { + let limit = Number.isFinite(opts?.limit) ? opts.limit : 262144 + const signal = opts?.signal + + if (signal != null && (typeof signal !== 'object' || !('aborted' in signal))) { + throw new InvalidArgumentError('signal must be an AbortSignal') } - if (this.closed) { - return Promise.resolve(null) + signal?.throwIfAborted() + + if (this._readableState.closeEmitted) { + return null } - return new Promise((resolve, reject) => { - const signalListenerCleanup = signal - ? util.addAbortListener(signal, () => { - this.destroy() - }) - : noop + return await new Promise((resolve, reject) => { + const onAbort = () => { + this.destroy(signal.reason ?? new AbortError()) + } + signal?.addEventListener('abort', onAbort) this .on('close', function () { - signalListenerCleanup() - if (signal && signal.aborted) { - reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) + signal?.removeEventListener('abort', onAbort) + if (signal?.aborted) { + reject(signal.reason ?? new AbortError()) } else { resolve(null) } @@ -210,33 +198,44 @@ function isUnusable (self) { } async function consume (stream, type) { - if (isUnusable(stream)) { - throw new TypeError('unusable') - } - assert(!stream[kConsume]) return new Promise((resolve, reject) => { - stream[kConsume] = { - type, - stream, - resolve, - reject, - length: 0, - body: [] - } + if (isUnusable(stream)) { + const rState = stream._readableState + if (rState.destroyed && rState.closeEmitted === false) { + stream + .on('error', err => { + reject(err) + }) + .on('close', () => { + reject(new TypeError('unusable')) + }) + } else { + reject(rState.errored ?? new TypeError('unusable')) + } + } else { + stream[kConsume] = { + type, + stream, + resolve, + reject, + length: 0, + body: [] + } + + stream + .on('error', function (err) { + consumeFinish(this[kConsume], err) + }) + .on('close', function () { + if (this[kConsume].body !== null) { + consumeFinish(this[kConsume], new RequestAbortedError()) + } + }) - stream - .on('error', function (err) { - consumeFinish(this[kConsume], err) - }) - .on('close', function () { - if (this[kConsume].body !== null) { - consumeFinish(this[kConsume], new RequestAbortedError()) - } - }) - - process.nextTick(consumeStart, stream[kConsume]) + queueMicrotask(() => consumeStart(stream[kConsume])) + } }) } @@ -266,14 +265,35 @@ function consumeStart (consume) { } } +/** + * @param {Buffer[]} chunks + * @param {number} length + */ +function chunksDecode (chunks, length) { + if (chunks.length === 0 || length === 0) { + return '' + } + const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, length) + + const start = + buffer.length >= 3 && + // Skip BOM. + buffer[0] === 0xef && + buffer[1] === 0xbb && + buffer[2] === 0xbf + ? 3 + : 0 + return buffer.utf8Slice(start, buffer.length - start) +} + function consumeEnd (consume) { const { type, body, resolve, stream, length } = consume try { if (type === 'text') { - resolve(toUSVString(Buffer.concat(body))) + resolve(chunksDecode(body, length)) } else if (type === 'json') { - resolve(JSON.parse(Buffer.concat(body))) + resolve(JSON.parse(chunksDecode(body, length))) } else if (type === 'arrayBuffer') { const dst = new Uint8Array(length) @@ -285,9 +305,6 @@ function consumeEnd (consume) { resolve(dst.buffer) } else if (type === 'blob') { - if (!Blob) { - Blob = require('buffer').Blob - } resolve(new Blob(body, { type: stream[kContentType] })) } diff --git a/deps/undici/src/lib/client.js b/deps/undici/src/lib/client.js index 22cb39039da7fb..bd4a400ad721ff 100644 --- a/deps/undici/src/lib/client.js +++ b/deps/undici/src/lib/client.js @@ -249,7 +249,7 @@ class Client extends DispatcherBase { } if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { - throw new InvalidArgumentError('maxConcurrentStreams must be a possitive integer, greater than 0') + throw new InvalidArgumentError('maxConcurrentStreams must be a positive integer, greater than 0') } if (typeof connect !== 'function') { @@ -296,7 +296,7 @@ class Client extends DispatcherBase { ? null : { // streams: null, // Fixed queue of streams - For future support of `push` - openStreams: 0, // Keep track of them to decide wether or not unref the session + openStreams: 0, // Keep track of them to decide whether or not unref the session maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server } this[kHost] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}` @@ -740,6 +740,7 @@ class Parser { if (!request) { return -1 } + request.onResponseStarted() } onHeaderField (buf) { @@ -765,11 +766,14 @@ class Parser { } const key = this.headers[len - 2] - if (key.length === 10 && key.toString().toLowerCase() === 'keep-alive') { - this.keepAlive += buf.toString() - } else if (key.length === 10 && key.toString().toLowerCase() === 'connection') { - this.connection += buf.toString() - } else if (key.length === 14 && key.toString().toLowerCase() === 'content-length') { + if (key.length === 10) { + const headerName = util.bufferToLowerCasedHeaderName(key) + if (headerName === 'keep-alive') { + this.keepAlive += buf.toString() + } else if (headerName === 'connection') { + this.connection += buf.toString() + } + } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === 'content-length') { this.contentLength += buf.toString() } @@ -1706,7 +1710,7 @@ function writeH2 (client, session, request) { } // https://tools.ietf.org/html/rfc7540#section-8.3 - // :path and :scheme headers must be omited when sending CONNECT + // :path and :scheme headers must be omitted when sending CONNECT headers[HTTP2_HEADER_PATH] = path headers[HTTP2_HEADER_SCHEME] = 'https' @@ -1783,6 +1787,7 @@ function writeH2 (client, session, request) { stream.once('response', headers => { const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers + request.onResponseStarted() if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), '') === false) { stream.pause() @@ -1833,7 +1838,7 @@ function writeH2 (client, session, request) { // }) // stream.on('push', headers => { - // // TODO(HTTP/2): Suppor push + // // TODO(HTTP/2): Support push // }) // stream.on('trailers', headers => { @@ -1963,12 +1968,19 @@ function writeStream ({ h2stream, body, client, request, socket, contentLength, body.resume() } } - const onAbort = function () { - if (finished) { - return + const onClose = function () { + // 'close' might be emitted *before* 'error' for + // broken streams. Wait a tick to avoid this case. + queueMicrotask(() => { + // It's only safe to remove 'error' listener after + // 'close'. + body.removeListener('error', onFinished) + }) + + if (!finished) { + const err = new RequestAbortedError() + queueMicrotask(() => onFinished(err)) } - const err = new RequestAbortedError() - queueMicrotask(() => onFinished(err)) } const onFinished = function (err) { if (finished) { @@ -1986,8 +1998,7 @@ function writeStream ({ h2stream, body, client, request, socket, contentLength, body .removeListener('data', onData) .removeListener('end', onFinished) - .removeListener('error', onFinished) - .removeListener('close', onAbort) + .removeListener('close', onClose) if (!err) { try { @@ -2010,7 +2021,7 @@ function writeStream ({ h2stream, body, client, request, socket, contentLength, .on('data', onData) .on('end', onFinished) .on('error', onFinished) - .on('close', onAbort) + .on('close', onClose) if (body.resume) { body.resume() diff --git a/deps/undici/src/lib/compat/dispatcher-weakref.js b/deps/undici/src/lib/compat/dispatcher-weakref.js index 8cb99e21501dea..a2fd0020416c62 100644 --- a/deps/undici/src/lib/compat/dispatcher-weakref.js +++ b/deps/undici/src/lib/compat/dispatcher-weakref.js @@ -1,7 +1,5 @@ 'use strict' -/* istanbul ignore file: only for Node 12 */ - const { kConnected, kSize } = require('../core/symbols') class CompatWeakRef { @@ -41,8 +39,5 @@ module.exports = function () { FinalizationRegistry: CompatFinalizer } } - return { - WeakRef: global.WeakRef || CompatWeakRef, - FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer - } + return { WeakRef, FinalizationRegistry } } diff --git a/deps/undici/src/lib/core/connect.js b/deps/undici/src/lib/core/connect.js index 33091173fa8dbc..2d2521dcfbd068 100644 --- a/deps/undici/src/lib/core/connect.js +++ b/deps/undici/src/lib/core/connect.js @@ -15,7 +15,7 @@ let tls // include tls conditionally since it is not always available let SessionCache // FIXME: remove workaround when the Node bug is fixed // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 -if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) { +if (global.FinalizationRegistry && !(process.env.NODE_V8_COVERAGE || process.env.UNDICI_NO_FG)) { SessionCache = class WeakSessionCache { constructor (maxCachedSessions) { this._maxCachedSessions = maxCachedSessions @@ -183,7 +183,11 @@ function setupTimeout (onConnectTimeout, timeout) { } function onConnectTimeout (socket) { - util.destroy(socket, new ConnectTimeoutError()) + let message = 'Connect Timeout Error' + if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { + message = +` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')})` + } + util.destroy(socket, new ConnectTimeoutError(message)) } module.exports = buildConnector diff --git a/deps/undici/src/lib/core/constants.js b/deps/undici/src/lib/core/constants.js new file mode 100644 index 00000000000000..6ec770dd533449 --- /dev/null +++ b/deps/undici/src/lib/core/constants.js @@ -0,0 +1,118 @@ +'use strict' + +/** @type {Record} */ +const headerNameLowerCasedRecord = {} + +// https://developer.mozilla.org/docs/Web/HTTP/Headers +const wellknownHeaderNames = [ + 'Accept', + 'Accept-Encoding', + 'Accept-Language', + 'Accept-Ranges', + 'Access-Control-Allow-Credentials', + 'Access-Control-Allow-Headers', + 'Access-Control-Allow-Methods', + 'Access-Control-Allow-Origin', + 'Access-Control-Expose-Headers', + 'Access-Control-Max-Age', + 'Access-Control-Request-Headers', + 'Access-Control-Request-Method', + 'Age', + 'Allow', + 'Alt-Svc', + 'Alt-Used', + 'Authorization', + 'Cache-Control', + 'Clear-Site-Data', + 'Connection', + 'Content-Disposition', + 'Content-Encoding', + 'Content-Language', + 'Content-Length', + 'Content-Location', + 'Content-Range', + 'Content-Security-Policy', + 'Content-Security-Policy-Report-Only', + 'Content-Type', + 'Cookie', + 'Cross-Origin-Embedder-Policy', + 'Cross-Origin-Opener-Policy', + 'Cross-Origin-Resource-Policy', + 'Date', + 'Device-Memory', + 'Downlink', + 'ECT', + 'ETag', + 'Expect', + 'Expect-CT', + 'Expires', + 'Forwarded', + 'From', + 'Host', + 'If-Match', + 'If-Modified-Since', + 'If-None-Match', + 'If-Range', + 'If-Unmodified-Since', + 'Keep-Alive', + 'Last-Modified', + 'Link', + 'Location', + 'Max-Forwards', + 'Origin', + 'Permissions-Policy', + 'Pragma', + 'Proxy-Authenticate', + 'Proxy-Authorization', + 'RTT', + 'Range', + 'Referer', + 'Referrer-Policy', + 'Refresh', + 'Retry-After', + 'Sec-WebSocket-Accept', + 'Sec-WebSocket-Extensions', + 'Sec-WebSocket-Key', + 'Sec-WebSocket-Protocol', + 'Sec-WebSocket-Version', + 'Server', + 'Server-Timing', + 'Service-Worker-Allowed', + 'Service-Worker-Navigation-Preload', + 'Set-Cookie', + 'SourceMap', + 'Strict-Transport-Security', + 'Supports-Loading-Mode', + 'TE', + 'Timing-Allow-Origin', + 'Trailer', + 'Transfer-Encoding', + 'Upgrade', + 'Upgrade-Insecure-Requests', + 'User-Agent', + 'Vary', + 'Via', + 'WWW-Authenticate', + 'X-Content-Type-Options', + 'X-DNS-Prefetch-Control', + 'X-Frame-Options', + 'X-Permitted-Cross-Domain-Policies', + 'X-Powered-By', + 'X-Requested-With', + 'X-XSS-Protection' +] + +for (let i = 0; i < wellknownHeaderNames.length; ++i) { + const key = wellknownHeaderNames[i] + const lowerCasedKey = key.toLowerCase() + headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] = + lowerCasedKey +} + +// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. +Object.setPrototypeOf(headerNameLowerCasedRecord, null) + +module.exports = { + wellknownHeaderNames, + headerNameLowerCasedRecord +} diff --git a/deps/undici/src/lib/core/errors.js b/deps/undici/src/lib/core/errors.js index 7af704b462a41e..0d0b7f60bc298b 100644 --- a/deps/undici/src/lib/core/errors.js +++ b/deps/undici/src/lib/core/errors.js @@ -11,7 +11,6 @@ class UndiciError extends Error { class ConnectTimeoutError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, ConnectTimeoutError) this.name = 'ConnectTimeoutError' this.message = message || 'Connect Timeout Error' this.code = 'UND_ERR_CONNECT_TIMEOUT' @@ -21,7 +20,6 @@ class ConnectTimeoutError extends UndiciError { class HeadersTimeoutError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, HeadersTimeoutError) this.name = 'HeadersTimeoutError' this.message = message || 'Headers Timeout Error' this.code = 'UND_ERR_HEADERS_TIMEOUT' @@ -31,7 +29,6 @@ class HeadersTimeoutError extends UndiciError { class HeadersOverflowError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, HeadersOverflowError) this.name = 'HeadersOverflowError' this.message = message || 'Headers Overflow Error' this.code = 'UND_ERR_HEADERS_OVERFLOW' @@ -41,7 +38,6 @@ class HeadersOverflowError extends UndiciError { class BodyTimeoutError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, BodyTimeoutError) this.name = 'BodyTimeoutError' this.message = message || 'Body Timeout Error' this.code = 'UND_ERR_BODY_TIMEOUT' @@ -51,7 +47,6 @@ class BodyTimeoutError extends UndiciError { class ResponseStatusCodeError extends UndiciError { constructor (message, statusCode, headers, body) { super(message) - Error.captureStackTrace(this, ResponseStatusCodeError) this.name = 'ResponseStatusCodeError' this.message = message || 'Response Status Code Error' this.code = 'UND_ERR_RESPONSE_STATUS_CODE' @@ -65,7 +60,6 @@ class ResponseStatusCodeError extends UndiciError { class InvalidArgumentError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, InvalidArgumentError) this.name = 'InvalidArgumentError' this.message = message || 'Invalid Argument Error' this.code = 'UND_ERR_INVALID_ARG' @@ -75,17 +69,23 @@ class InvalidArgumentError extends UndiciError { class InvalidReturnValueError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, InvalidReturnValueError) this.name = 'InvalidReturnValueError' this.message = message || 'Invalid Return Value Error' this.code = 'UND_ERR_INVALID_RETURN_VALUE' } } -class RequestAbortedError extends UndiciError { +class AbortError extends UndiciError { + constructor (message) { + super(message) + this.name = 'AbortError' + this.message = message || 'The operation was aborted' + } +} + +class RequestAbortedError extends AbortError { constructor (message) { super(message) - Error.captureStackTrace(this, RequestAbortedError) this.name = 'AbortError' this.message = message || 'Request aborted' this.code = 'UND_ERR_ABORTED' @@ -95,7 +95,6 @@ class RequestAbortedError extends UndiciError { class InformationalError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, InformationalError) this.name = 'InformationalError' this.message = message || 'Request information' this.code = 'UND_ERR_INFO' @@ -105,7 +104,6 @@ class InformationalError extends UndiciError { class RequestContentLengthMismatchError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, RequestContentLengthMismatchError) this.name = 'RequestContentLengthMismatchError' this.message = message || 'Request body length does not match content-length header' this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' @@ -115,7 +113,6 @@ class RequestContentLengthMismatchError extends UndiciError { class ResponseContentLengthMismatchError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, ResponseContentLengthMismatchError) this.name = 'ResponseContentLengthMismatchError' this.message = message || 'Response body length does not match content-length header' this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' @@ -125,7 +122,6 @@ class ResponseContentLengthMismatchError extends UndiciError { class ClientDestroyedError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, ClientDestroyedError) this.name = 'ClientDestroyedError' this.message = message || 'The client is destroyed' this.code = 'UND_ERR_DESTROYED' @@ -135,7 +131,6 @@ class ClientDestroyedError extends UndiciError { class ClientClosedError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, ClientClosedError) this.name = 'ClientClosedError' this.message = message || 'The client is closed' this.code = 'UND_ERR_CLOSED' @@ -145,7 +140,6 @@ class ClientClosedError extends UndiciError { class SocketError extends UndiciError { constructor (message, socket) { super(message) - Error.captureStackTrace(this, SocketError) this.name = 'SocketError' this.message = message || 'Socket error' this.code = 'UND_ERR_SOCKET' @@ -156,7 +150,6 @@ class SocketError extends UndiciError { class NotSupportedError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, NotSupportedError) this.name = 'NotSupportedError' this.message = message || 'Not supported error' this.code = 'UND_ERR_NOT_SUPPORTED' @@ -166,7 +159,6 @@ class NotSupportedError extends UndiciError { class BalancedPoolMissingUpstreamError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, NotSupportedError) this.name = 'MissingUpstreamError' this.message = message || 'No upstream has been added to the BalancedPool' this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' @@ -176,7 +168,6 @@ class BalancedPoolMissingUpstreamError extends UndiciError { class HTTPParserError extends Error { constructor (message, code, data) { super(message) - Error.captureStackTrace(this, HTTPParserError) this.name = 'HTTPParserError' this.code = code ? `HPE_${code}` : undefined this.data = data ? data.toString() : undefined @@ -186,7 +177,6 @@ class HTTPParserError extends Error { class ResponseExceededMaxSizeError extends UndiciError { constructor (message) { super(message) - Error.captureStackTrace(this, ResponseExceededMaxSizeError) this.name = 'ResponseExceededMaxSizeError' this.message = message || 'Response content exceeded max size' this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' @@ -196,7 +186,6 @@ class ResponseExceededMaxSizeError extends UndiciError { class RequestRetryError extends UndiciError { constructor (message, code, { headers, data }) { super(message) - Error.captureStackTrace(this, RequestRetryError) this.name = 'RequestRetryError' this.message = message || 'Request retry error' this.code = 'UND_ERR_REQ_RETRY' @@ -207,6 +196,7 @@ class RequestRetryError extends UndiciError { } module.exports = { + AbortError, HTTPParserError, UndiciError, HeadersTimeoutError, diff --git a/deps/undici/src/lib/core/request.js b/deps/undici/src/lib/core/request.js index 3697e6a3acccd5..fe63434ea98b74 100644 --- a/deps/undici/src/lib/core/request.js +++ b/deps/undici/src/lib/core/request.js @@ -7,17 +7,11 @@ const { const assert = require('assert') const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = require('./symbols') const util = require('./util') +const { headerNameLowerCasedRecord } = require('./constants') -// tokenRegExp and headerCharRegex have been lifted from +// headerCharRegex have been lifted from // https://github.com/nodejs/node/blob/main/lib/_http_common.js -/** - * Verifies that the given val is a valid HTTP token - * per the rules defined in RFC 7230 - * See https://tools.ietf.org/html/rfc7230#section-3.2.6 - */ -const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/ - /** * Matches if val contains an invalid field-vchar * field-value = *( field-content / obs-fold ) @@ -80,7 +74,7 @@ class Request { if (typeof method !== 'string') { throw new InvalidArgumentError('method must be a string') - } else if (tokenRegExp.exec(method) === null) { + } else if (!util.isValidHTTPToken(method)) { throw new InvalidArgumentError('invalid request method') } @@ -196,10 +190,6 @@ class Request { } if (util.isFormDataLike(this.body)) { - if (util.nodeMajor < 16 || (util.nodeMajor === 16 && util.nodeMinor < 8)) { - throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.') - } - if (!extractBody) { extractBody = require('../fetch/body.js').extractBody } @@ -263,6 +253,10 @@ class Request { } } + onResponseStarted () { + return this[kHandler].onResponseStarted?.() + } + onHeaders (statusCode, headers, resume, statusText) { assert(!this.aborted) assert(!this.completed) @@ -420,65 +414,41 @@ function processHeader (request, key, val, skipAppend = false) { return } - if ( - request.host === null && - key.length === 4 && - key.toLowerCase() === 'host' - ) { + let headerName = headerNameLowerCasedRecord[key] + + if (headerName === undefined) { + headerName = key.toLowerCase() + if (headerNameLowerCasedRecord[headerName] === undefined && !util.isValidHTTPToken(headerName)) { + throw new InvalidArgumentError('invalid header key') + } + } + + if (request.host === null && headerName === 'host') { if (headerCharRegex.exec(val) !== null) { throw new InvalidArgumentError(`invalid ${key} header`) } // Consumed by Client request.host = val - } else if ( - request.contentLength === null && - key.length === 14 && - key.toLowerCase() === 'content-length' - ) { + } else if (request.contentLength === null && headerName === 'content-length') { request.contentLength = parseInt(val, 10) if (!Number.isFinite(request.contentLength)) { throw new InvalidArgumentError('invalid content-length header') } - } else if ( - request.contentType === null && - key.length === 12 && - key.toLowerCase() === 'content-type' - ) { + } else if (request.contentType === null && headerName === 'content-type') { request.contentType = val if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) else request.headers += processHeaderValue(key, val) - } else if ( - key.length === 17 && - key.toLowerCase() === 'transfer-encoding' - ) { - throw new InvalidArgumentError('invalid transfer-encoding header') - } else if ( - key.length === 10 && - key.toLowerCase() === 'connection' - ) { + } else if (headerName === 'transfer-encoding' || headerName === 'keep-alive' || headerName === 'upgrade') { + throw new InvalidArgumentError(`invalid ${headerName} header`) + } else if (headerName === 'connection') { const value = typeof val === 'string' ? val.toLowerCase() : null if (value !== 'close' && value !== 'keep-alive') { throw new InvalidArgumentError('invalid connection header') } else if (value === 'close') { request.reset = true } - } else if ( - key.length === 10 && - key.toLowerCase() === 'keep-alive' - ) { - throw new InvalidArgumentError('invalid keep-alive header') - } else if ( - key.length === 7 && - key.toLowerCase() === 'upgrade' - ) { - throw new InvalidArgumentError('invalid upgrade header') - } else if ( - key.length === 6 && - key.toLowerCase() === 'expect' - ) { + } else if (headerName === 'expect') { throw new NotSupportedError('expect header not supported') - } else if (tokenRegExp.exec(key) === null) { - throw new InvalidArgumentError('invalid header key') } else { if (Array.isArray(val)) { for (let i = 0; i < val.length; i++) { diff --git a/deps/undici/src/lib/core/tree.js b/deps/undici/src/lib/core/tree.js new file mode 100644 index 00000000000000..a61de9efbd98a9 --- /dev/null +++ b/deps/undici/src/lib/core/tree.js @@ -0,0 +1,134 @@ +'use strict' + +const { + wellknownHeaderNames, + headerNameLowerCasedRecord +} = require('./constants') + +class TstNode { + /** @type {any} */ + value = null + /** @type {null | TstNode} */ + left = null + /** @type {null | TstNode} */ + middle = null + /** @type {null | TstNode} */ + right = null + /** @type {number} */ + code + /** + * @param {Uint8Array} key + * @param {any} value + * @param {number} index + */ + constructor (key, value, index) { + if (index === undefined || index >= key.length) { + throw new TypeError('Unreachable') + } + this.code = key[index] + if (key.length !== ++index) { + this.middle = new TstNode(key, value, index) + } else { + this.value = value + } + } + + /** + * @param {Uint8Array} key + * @param {any} value + * @param {number} index + */ + add (key, value, index) { + if (index === undefined || index >= key.length) { + throw new TypeError('Unreachable') + } + const code = key[index] + if (this.code === code) { + if (key.length === ++index) { + this.value = value + } else if (this.middle !== null) { + this.middle.add(key, value, index) + } else { + this.middle = new TstNode(key, value, index) + } + } else if (this.code < code) { + if (this.left !== null) { + this.left.add(key, value, index) + } else { + this.left = new TstNode(key, value, index) + } + } else { + if (this.right !== null) { + this.right.add(key, value, index) + } else { + this.right = new TstNode(key, value, index) + } + } + } + + /** + * @param {Uint8Array} key + * @return {TstNode | null} + */ + search (key) { + const keylength = key.length + let index = 0 + let node = this + while (node !== null && index < keylength) { + let code = key[index] + // A-Z + if (code >= 0x41 && code <= 0x5a) { + // Lowercase for uppercase. + code |= 32 + } + while (node !== null) { + if (code === node.code) { + if (keylength === ++index) { + // Returns Node since it is the last key. + return node + } + node = node.middle + break + } + node = node.code < code ? node.left : node.right + } + } + return null + } +} + +class TernarySearchTree { + /** @type {TstNode | null} */ + node = null + + /** + * @param {Uint8Array} key + * @param {any} value + * */ + insert (key, value) { + if (this.node === null) { + this.node = new TstNode(key, value, 0) + } else { + this.node.add(key, value, 0) + } + } + + /** + * @param {Uint8Array} key + */ + lookup (key) { + return this.node?.search(key)?.value ?? null + } +} + +const tree = new TernarySearchTree() + +for (let i = 0; i < wellknownHeaderNames.length; ++i) { + const key = headerNameLowerCasedRecord[wellknownHeaderNames[i]] + tree.insert(Buffer.from(key), key) +} + +module.exports = { + TernarySearchTree, + tree +} diff --git a/deps/undici/src/lib/core/util.js b/deps/undici/src/lib/core/util.js index 8d5450ba0c0c0c..7cd411d9f3efc8 100644 --- a/deps/undici/src/lib/core/util.js +++ b/deps/undici/src/lib/core/util.js @@ -9,6 +9,8 @@ const { InvalidArgumentError } = require('./errors') const { Blob } = require('buffer') const nodeUtil = require('util') const { stringify } = require('querystring') +const { headerNameLowerCasedRecord } = require('./constants') +const { tree } = require('./tree') const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)) @@ -218,22 +220,49 @@ function parseKeepAliveTimeout (val) { return m ? parseInt(m[1], 10) * 1000 : null } -function parseHeaders (headers, obj = {}) { +/** + * Retrieves a header name and returns its lowercase value. + * @param {string | Buffer} value Header name + * @returns {string} + */ +function headerNameToString (value) { + return typeof value === 'string' + ? headerNameLowerCasedRecord[value] ?? value.toLowerCase() + : tree.lookup(value) ?? value.toString('latin1').toLowerCase() +} + +/** + * Receive the buffer as a string and return its lowercase value. + * @param {Buffer} value Header name + * @returns {string} + */ +function bufferToLowerCasedHeaderName (value) { + return tree.lookup(value) ?? value.toString('latin1').toLowerCase() +} + +/** + * @param {Record | (Buffer | string | (Buffer | string)[])[]} headers + * @param {Record} [obj] + * @returns {Record} + */ +function parseHeaders (headers, obj) { // For H2 support if (!Array.isArray(headers)) return headers + if (obj === undefined) obj = {} for (let i = 0; i < headers.length; i += 2) { - const key = headers[i].toString().toLowerCase() + const key = headerNameToString(headers[i]) let val = obj[key] if (!val) { - if (Array.isArray(headers[i + 1])) { - obj[key] = headers[i + 1].map(x => x.toString('utf8')) + const headersValue = headers[i + 1] + if (typeof headersValue === 'string') { + obj[key] = headersValue } else { - obj[key] = headers[i + 1].toString('utf8') + obj[key] = Array.isArray(headersValue) ? headersValue.map(x => x.toString('utf8')) : headersValue.toString('utf8') } } else { - if (!Array.isArray(val)) { + if (typeof val === 'string') { val = [val] obj[key] = val } @@ -331,19 +360,11 @@ function isDisturbed (body) { } function isErrored (body) { - return !!(body && ( - stream.isErrored - ? stream.isErrored(body) - : /state: 'errored'/.test(nodeUtil.inspect(body) - ))) + return !!(body && stream.isErrored(body)) } function isReadable (body) { - return !!(body && ( - stream.isReadable - ? stream.isReadable(body) - : /state: 'readable'/.test(nodeUtil.inspect(body) - ))) + return !!(body && stream.isReadable(body)) } function getSocketInfo (socket) { @@ -359,21 +380,9 @@ function getSocketInfo (socket) { } } -async function * convertIterableToBuffer (iterable) { - for await (const chunk of iterable) { - yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) - } -} - -let ReadableStream +/** @type {globalThis['ReadableStream']} */ function ReadableStreamFrom (iterable) { - if (!ReadableStream) { - ReadableStream = require('stream/web').ReadableStream - } - - if (ReadableStream.from) { - return ReadableStream.from(convertIterableToBuffer(iterable)) - } + // We cannot use ReadableStream.from here because it does not return a byte stream. let iterator return new ReadableStream( @@ -386,18 +395,21 @@ function ReadableStreamFrom (iterable) { if (done) { queueMicrotask(() => { controller.close() + controller.byobRequest?.respond(0) }) } else { const buf = Buffer.isBuffer(value) ? value : Buffer.from(value) - controller.enqueue(new Uint8Array(buf)) + if (buf.byteLength) { + controller.enqueue(new Uint8Array(buf)) + } } return controller.desiredSize > 0 }, async cancel (reason) { await iterator.return() - } - }, - 0 + }, + type: 'bytes' + } ) } @@ -417,20 +429,6 @@ function isFormDataLike (object) { ) } -function throwIfAborted (signal) { - if (!signal) { return } - if (typeof signal.throwIfAborted === 'function') { - signal.throwIfAborted() - } else { - if (signal.aborted) { - // DOMException not available < v17.0.0 - const err = new Error('The operation was aborted') - err.name = 'AbortError' - throw err - } - } -} - function addAbortListener (signal, listener) { if ('addEventListener' in signal) { signal.addEventListener('abort', listener, { once: true }) @@ -455,6 +453,52 @@ function toUSVString (val) { return `${val}` } +/** + * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 + * @param {number} c + */ +function isTokenCharCode (c) { + switch (c) { + case 0x22: + case 0x28: + case 0x29: + case 0x2c: + case 0x2f: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x40: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x7b: + case 0x7d: + // DQUOTE and "(),/:;<=>?@[\]{}" + return false + default: + // VCHAR %x21-7E + return c >= 0x21 && c <= 0x7e + } +} + +/** + * @param {string} characters + */ +function isValidHTTPToken (characters) { + if (characters.length === 0) { + return false + } + for (let i = 0; i < characters.length; ++i) { + if (!isTokenCharCode(characters.charCodeAt(i))) { + return false + } + } + return true +} + // Parsed accordingly to RFC 9110 // https://www.rfc-editor.org/rfc/rfc9110#field.content-range function parseRangeHeader (range) { @@ -489,6 +533,8 @@ module.exports = { isIterable, isAsyncIterable, isDestroyed, + headerNameToString, + bufferToLowerCasedHeaderName, parseRawHeaders, parseHeaders, parseKeepAliveTimeout, @@ -501,8 +547,9 @@ module.exports = { getSocketInfo, isFormDataLike, buildURL, - throwIfAborted, addAbortListener, + isValidHTTPToken, + isTokenCharCode, parseRangeHeader, nodeMajor, nodeMinor, diff --git a/deps/undici/src/lib/fetch/body.js b/deps/undici/src/lib/fetch/body.js index fd8481b796d847..6202887289a02d 100644 --- a/deps/undici/src/lib/fetch/body.js +++ b/deps/undici/src/lib/fetch/body.js @@ -13,7 +13,6 @@ const { const { FormData } = require('./formdata') const { kState } = require('./symbols') const { webidl } = require('./webidl') -const { DOMException, structuredClone } = require('./constants') const { Blob, File: NativeFile } = require('buffer') const { kBodyUsed } = require('../core/symbols') const assert = require('assert') @@ -22,8 +21,6 @@ const { isUint8Array, isArrayBuffer } = require('util/types') const { File: UndiciFile } = require('./file') const { parseMIMEType, serializeAMimeType } = require('./dataURL') -let ReadableStream = globalThis.ReadableStream - /** @type {globalThis['File']} */ const File = NativeFile ?? UndiciFile const textEncoder = new TextEncoder() @@ -31,10 +28,6 @@ const textDecoder = new TextDecoder() // https://fetch.spec.whatwg.org/#concept-bodyinit-extract function extractBody (object, keepalive = false) { - if (!ReadableStream) { - ReadableStream = require('stream/web').ReadableStream - } - // 1. Let stream be null. let stream = null @@ -47,16 +40,19 @@ function extractBody (object, keepalive = false) { stream = object.stream() } else { // 4. Otherwise, set stream to a new ReadableStream object, and set - // up stream. + // up stream with byte reading support. stream = new ReadableStream({ async pull (controller) { - controller.enqueue( - typeof source === 'string' ? textEncoder.encode(source) : source - ) + const buffer = typeof source === 'string' ? textEncoder.encode(source) : source + + if (buffer.byteLength) { + controller.enqueue(buffer) + } + queueMicrotask(() => readableStreamClose(controller)) }, start () {}, - type: undefined + type: 'bytes' }) } @@ -223,13 +219,17 @@ function extractBody (object, keepalive = false) { // When running action is done, close stream. queueMicrotask(() => { controller.close() + controller.byobRequest?.respond(0) }) } else { // Whenever one or more bytes are available and stream is not errored, // enqueue a Uint8Array wrapping an ArrayBuffer containing the available // bytes into stream. if (!isErrored(stream)) { - controller.enqueue(new Uint8Array(value)) + const buffer = new Uint8Array(value) + if (buffer.byteLength) { + controller.enqueue(buffer) + } } } return controller.desiredSize > 0 @@ -237,7 +237,7 @@ function extractBody (object, keepalive = false) { async cancel (reason) { await iterator.return() }, - type: undefined + type: 'bytes' }) } @@ -251,11 +251,6 @@ function extractBody (object, keepalive = false) { // https://fetch.spec.whatwg.org/#bodyinit-safely-extract function safelyExtractBody (object, keepalive = false) { - if (!ReadableStream) { - // istanbul ignore next - ReadableStream = require('stream/web').ReadableStream - } - // To safely extract a body and a `Content-Type` value from // a byte sequence or BodyInit object object, run these steps: @@ -379,7 +374,7 @@ function bodyMixinMethods (instance) { // If mimeType’s essence is "multipart/form-data", then: if (/multipart\/form-data/.test(contentType)) { const headers = {} - for (const [key, value] of this.headers) headers[key.toLowerCase()] = value + for (const [key, value] of this.headers) headers[key] = value const responseFormData = new FormData() diff --git a/deps/undici/src/lib/fetch/constants.js b/deps/undici/src/lib/fetch/constants.js index 218fcbee4da4c7..ada622feed58ad 100644 --- a/deps/undici/src/lib/fetch/constants.js +++ b/deps/undici/src/lib/fetch/constants.js @@ -1,7 +1,5 @@ 'use strict' -const { MessageChannel, receiveMessageOnPort } = require('worker_threads') - const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] const corsSafeListedMethodsSet = new Set(corsSafeListedMethods) @@ -92,41 +90,7 @@ const subresource = [ ] const subresourceSet = new Set(subresource) -/** @type {globalThis['DOMException']} */ -const DOMException = globalThis.DOMException ?? (() => { - // DOMException was only made a global in Node v17.0.0, - // but fetch supports >= v16.8. - try { - atob('~') - } catch (err) { - return Object.getPrototypeOf(err).constructor - } -})() - -let channel - -/** @type {globalThis['structuredClone']} */ -const structuredClone = - globalThis.structuredClone ?? - // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js - // structuredClone was added in v17.0.0, but fetch supports v16.8 - function structuredClone (value, options = undefined) { - if (arguments.length === 0) { - throw new TypeError('missing argument') - } - - if (!channel) { - channel = new MessageChannel() - } - channel.port1.unref() - channel.port2.unref() - channel.port1.postMessage(value, options?.transfer) - return receiveMessageOnPort(channel.port2).message - } - module.exports = { - DOMException, - structuredClone, subresource, forbiddenMethods, requestBodyHeader, diff --git a/deps/undici/src/lib/fetch/dataURL.js b/deps/undici/src/lib/fetch/dataURL.js index 7b6a606106dd69..762017c8cc9917 100644 --- a/deps/undici/src/lib/fetch/dataURL.js +++ b/deps/undici/src/lib/fetch/dataURL.js @@ -1,5 +1,4 @@ const assert = require('assert') -const { atob } = require('buffer') const { isomorphicDecode } = require('./util') const encoder = new TextEncoder() @@ -8,7 +7,8 @@ const encoder = new TextEncoder() * @see https://mimesniff.spec.whatwg.org/#http-token-code-point */ const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ -const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line +const HTTP_WHITESPACE_REGEX = /[\u000A|\u000D|\u0009|\u0020]/ // eslint-disable-line +const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g // eslint-disable-line /** * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point */ @@ -126,7 +126,13 @@ function URLSerializer (url, excludeFragment = false) { const href = url.href const hashLength = url.hash.length - return hashLength === 0 ? href : href.substring(0, href.length - hashLength) + const serialized = hashLength === 0 ? href : href.substring(0, href.length - hashLength) + + if (!hashLength && href.endsWith('#')) { + return serialized.slice(0, -1) + } + + return serialized } // https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points @@ -182,20 +188,26 @@ function stringPercentDecode (input) { return percentDecode(bytes) } +function isHexCharByte (byte) { + // 0-9 A-F a-f + return (byte >= 0x30 && byte <= 0x39) || (byte >= 0x41 && byte <= 0x46) || (byte >= 0x61 && byte <= 0x66) +} + // https://url.spec.whatwg.org/#percent-decode /** @param {Uint8Array} input */ function percentDecode (input) { + const length = input.length // 1. Let output be an empty byte sequence. - /** @type {number[]} */ - const output = [] - + /** @type {Uint8Array} */ + const output = new Uint8Array(length) + let j = 0 // 2. For each byte byte in input: - for (let i = 0; i < input.length; i++) { + for (let i = 0; i < length; ++i) { const byte = input[i] // 1. If byte is not 0x25 (%), then append byte to output. if (byte !== 0x25) { - output.push(byte) + output[j++] = byte // 2. Otherwise, if byte is 0x25 (%) and the next two bytes // after byte in input are not in the ranges @@ -204,9 +216,9 @@ function percentDecode (input) { // to output. } else if ( byte === 0x25 && - !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2])) + !(isHexCharByte(input[i + 1]) && isHexCharByte(input[i + 2])) ) { - output.push(0x25) + output[j++] = 0x25 // 3. Otherwise: } else { @@ -216,7 +228,7 @@ function percentDecode (input) { const bytePoint = Number.parseInt(nextTwoBytes, 16) // 2. Append a byte whose value is bytePoint to output. - output.push(bytePoint) + output[j++] = bytePoint // 3. Skip the next two bytes in input. i += 2 @@ -224,7 +236,7 @@ function percentDecode (input) { } // 3. Return output. - return Uint8Array.from(output) + return length === j ? output : output.subarray(0, j) } // https://mimesniff.spec.whatwg.org/#parse-a-mime-type @@ -404,19 +416,25 @@ function parseMIMEType (input) { /** @param {string} data */ function forgivingBase64 (data) { // 1. Remove all ASCII whitespace from data. - data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line + data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, '') // eslint-disable-line + let dataLength = data.length // 2. If data’s code point length divides by 4 leaving // no remainder, then: - if (data.length % 4 === 0) { + if (dataLength % 4 === 0) { // 1. If data ends with one or two U+003D (=) code points, // then remove them from data. - data = data.replace(/=?=$/, '') + if (data.charCodeAt(dataLength - 1) === 0x003D) { + --dataLength + if (data.charCodeAt(dataLength - 1) === 0x003D) { + --dataLength + } + } } // 3. If data’s code point length divides by 4 leaving // a remainder of 1, then return failure. - if (data.length % 4 === 1) { + if (dataLength % 4 === 1) { return 'failure' } @@ -425,18 +443,12 @@ function forgivingBase64 (data) { // U+002F (/) // ASCII alphanumeric // then return failure. - if (/[^+/0-9A-Za-z]/.test(data)) { + if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : data.substring(0, dataLength))) { return 'failure' } - const binary = atob(data) - const bytes = new Uint8Array(binary.length) - - for (let byte = 0; byte < binary.length; byte++) { - bytes[byte] = binary.charCodeAt(byte) - } - - return bytes + const buffer = Buffer.from(data, 'base64') + return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) } // https://fetch.spec.whatwg.org/#collect-an-http-quoted-string @@ -543,7 +555,7 @@ function serializeAMimeType (mimeType) { // 4. If value does not solely contain HTTP token code // points or value is the empty string, then: if (!HTTP_TOKEN_CODEPOINTS.test(value)) { - // 1. Precede each occurence of U+0022 (") or + // 1. Precede each occurrence of U+0022 (") or // U+005C (\) in value with U+005C (\). value = value.replace(/(\\|")/g, '\\$1') @@ -564,55 +576,54 @@ function serializeAMimeType (mimeType) { /** * @see https://fetch.spec.whatwg.org/#http-whitespace - * @param {string} char + * @param {number} char */ function isHTTPWhiteSpace (char) { - return char === '\r' || char === '\n' || char === '\t' || char === ' ' + // "\r\n\t " + return char === 0x00d || char === 0x00a || char === 0x009 || char === 0x020 } /** * @see https://fetch.spec.whatwg.org/#http-whitespace * @param {string} str + * @param {boolean} [leading=true] + * @param {boolean} [trailing=true] */ function removeHTTPWhitespace (str, leading = true, trailing = true) { - let lead = 0 - let trail = str.length - 1 - + let i = 0; let j = str.length if (leading) { - for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++); + while (j > i && isHTTPWhiteSpace(str.charCodeAt(i))) --i } - if (trailing) { - for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--); + while (j > i && isHTTPWhiteSpace(str.charCodeAt(j - 1))) --j } - - return str.slice(lead, trail + 1) + return i === 0 && j === str.length ? str : str.substring(i, j) } /** * @see https://infra.spec.whatwg.org/#ascii-whitespace - * @param {string} char + * @param {number} char */ function isASCIIWhitespace (char) { - return char === '\r' || char === '\n' || char === '\t' || char === '\f' || char === ' ' + // "\r\n\t\f " + return char === 0x00d || char === 0x00a || char === 0x009 || char === 0x00c || char === 0x020 } /** * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace + * @param {string} str + * @param {boolean} [leading=true] + * @param {boolean} [trailing=true] */ function removeASCIIWhitespace (str, leading = true, trailing = true) { - let lead = 0 - let trail = str.length - 1 - + let i = 0; let j = str.length if (leading) { - for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++); + while (j > i && isASCIIWhitespace(str.charCodeAt(i))) --i } - if (trailing) { - for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--); + while (j > i && isASCIIWhitespace(str.charCodeAt(j - 1))) --j } - - return str.slice(lead, trail + 1) + return i === 0 && j === str.length ? str : str.substring(i, j) } module.exports = { diff --git a/deps/undici/src/lib/fetch/headers.js b/deps/undici/src/lib/fetch/headers.js index 2f1c0be5a47309..a905baef49919b 100644 --- a/deps/undici/src/lib/fetch/headers.js +++ b/deps/undici/src/lib/fetch/headers.js @@ -114,7 +114,7 @@ function appendHeader (headers, name, value) { // forbidden response-header name, return. // 7. Append (name, value) to headers’s header list. - return headers[kHeadersList].append(name, value) + return headers[kHeadersList].append(name, value, false) // 8. If headers’s guard is "request-no-cors", then remove // privileged no-CORS request headers from headers @@ -135,14 +135,17 @@ class HeadersList { } } - // https://fetch.spec.whatwg.org/#header-list-contains - contains (name) { + /** + * @see https://fetch.spec.whatwg.org/#header-list-contains + * @param {string} name + * @param {boolean} isLowerCase + */ + contains (name, isLowerCase) { // A header list list contains a header name name if list // contains a header whose name is a byte-case-insensitive // match for name. - name = name.toLowerCase() - return this[kHeadersMap].has(name) + return this[kHeadersMap].has(isLowerCase ? name : name.toLowerCase()) } clear () { @@ -151,13 +154,18 @@ class HeadersList { this.cookies = null } - // https://fetch.spec.whatwg.org/#concept-header-list-append - append (name, value) { + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-append + * @param {string} name + * @param {string} value + * @param {boolean} isLowerCase + */ + append (name, value, isLowerCase) { this[kHeadersSortedMap] = null // 1. If list contains name, then set name to the first such // header’s name. - const lowercaseName = name.toLowerCase() + const lowercaseName = isLowerCase ? name : name.toLowerCase() const exists = this[kHeadersMap].get(lowercaseName) // 2. Append (name, value) to list. @@ -172,15 +180,19 @@ class HeadersList { } if (lowercaseName === 'set-cookie') { - this.cookies ??= [] - this.cookies.push(value) + (this.cookies ??= []).push(value) } } - // https://fetch.spec.whatwg.org/#concept-header-list-set - set (name, value) { + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-set + * @param {string} name + * @param {string} value + * @param {boolean} isLowerCase + */ + set (name, value, isLowerCase) { this[kHeadersSortedMap] = null - const lowercaseName = name.toLowerCase() + const lowercaseName = isLowerCase ? name : name.toLowerCase() if (lowercaseName === 'set-cookie') { this.cookies = [value] @@ -193,11 +205,14 @@ class HeadersList { this[kHeadersMap].set(lowercaseName, { name, value }) } - // https://fetch.spec.whatwg.org/#concept-header-list-delete - delete (name) { + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-delete + * @param {string} name + * @param {boolean} isLowerCase + */ + delete (name, isLowerCase) { this[kHeadersSortedMap] = null - - name = name.toLowerCase() + if (!isLowerCase) name = name.toLowerCase() if (name === 'set-cookie') { this.cookies = null @@ -206,15 +221,18 @@ class HeadersList { this[kHeadersMap].delete(name) } - // https://fetch.spec.whatwg.org/#concept-header-list-get - get (name) { - const value = this[kHeadersMap].get(name.toLowerCase()) - + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-get + * @param {string} name + * @param {boolean} isLowerCase + * @returns {string | null} + */ + get (name, isLowerCase) { // 1. If list does not contain name, then return null. // 2. Return the values of all headers in list whose name // is a byte-case-insensitive match for name, // separated from each other by 0x2C 0x20, in order. - return value === undefined ? null : value.value + return this[kHeadersMap].get(isLowerCase ? name : name.toLowerCase())?.value ?? null } * [Symbol.iterator] () { @@ -304,14 +322,14 @@ class Headers { // 6. If this’s header list does not contain name, then // return. - if (!this[kHeadersList].contains(name)) { + if (!this[kHeadersList].contains(name, false)) { return } // 7. Delete name from this’s header list. // 8. If this’s guard is "request-no-cors", then remove // privileged no-CORS request headers from this. - this[kHeadersList].delete(name) + this[kHeadersList].delete(name, false) } // https://fetch.spec.whatwg.org/#dom-headers-get @@ -333,7 +351,7 @@ class Headers { // 2. Return the result of getting name from this’s header // list. - return this[kHeadersList].get(name) + return this[kHeadersList].get(name, false) } // https://fetch.spec.whatwg.org/#dom-headers-has @@ -355,7 +373,7 @@ class Headers { // 2. Return true if this’s header list contains name; // otherwise false. - return this[kHeadersList].contains(name) + return this[kHeadersList].contains(name, false) } // https://fetch.spec.whatwg.org/#dom-headers-set @@ -404,7 +422,7 @@ class Headers { // 7. Set (name, value) in this’s header list. // 8. If this’s guard is "request-no-cors", then remove // privileged no-CORS request headers from this - this[kHeadersList].set(name, value) + this[kHeadersList].set(name, value, false) } // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie diff --git a/deps/undici/src/lib/fetch/index.js b/deps/undici/src/lib/fetch/index.js index 17c3d87ea62727..d64dd90596c9da 100644 --- a/deps/undici/src/lib/fetch/index.js +++ b/deps/undici/src/lib/fetch/index.js @@ -9,7 +9,7 @@ const { filterResponse, makeResponse } = require('./response') -const { Headers } = require('./headers') +const { Headers, HeadersList } = require('./headers') const { Request, makeRequest } = require('./request') const zlib = require('zlib') const { @@ -40,25 +40,26 @@ const { isomorphicEncode, urlIsLocal, urlIsHttpHttpsScheme, - urlHasHttpsScheme + urlHasHttpsScheme, + clampAndCoursenConnectionTimingInfo, + simpleRangeHeaderValue, + buildContentRange } = require('./util') const { kState, kHeaders, kGuard, kRealm } = require('./symbols') const assert = require('assert') -const { safelyExtractBody } = require('./body') +const { safelyExtractBody, extractBody } = require('./body') const { redirectStatusSet, nullBodyStatus, safeMethodsSet, requestBodyHeader, - subresourceSet, - DOMException + subresourceSet } = require('./constants') -const { kHeadersList } = require('../core/symbols') +const { kHeadersList, kConstruct } = require('../core/symbols') const EE = require('events') const { Readable, pipeline } = require('stream') -const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = require('../core/util') -const { dataURLProcessor, serializeAMimeType } = require('./dataURL') -const { TransformStream } = require('stream/web') +const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor, bufferToLowerCasedHeaderName } = require('../core/util') +const { dataURLProcessor, serializeAMimeType, parseMIMEType } = require('./dataURL') const { getGlobalDispatcher } = require('../global') const { webidl } = require('./webidl') const { STATUS_CODES } = require('http') @@ -66,7 +67,6 @@ const GET_OR_HEAD = ['GET', 'HEAD'] /** @type {import('buffer').resolveObjectURL} */ let resolveObjectURL -let ReadableStream = globalThis.ReadableStream class Fetch extends EE { constructor (dispatcher) { @@ -232,9 +232,10 @@ function fetch (input, init = {}) { // 4. Set responseObject to the result of creating a Response object, // given response, "immutable", and relevantRealm. - responseObject = new Response() + responseObject = new Response(kConstruct) responseObject[kState] = response responseObject[kRealm] = relevantRealm + responseObject[kHeaders] = new Headers(kConstruct) responseObject[kHeaders][kHeadersList] = response.headersList responseObject[kHeaders][kGuard] = 'immutable' responseObject[kHeaders][kRealm] = relevantRealm @@ -404,9 +405,9 @@ function fetching ({ // 5. Let timingInfo be a new fetch timing info whose start time and // post-redirect start time are the coarsened shared current time given // crossOriginIsolatedCapability. - const currenTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability) + const currentTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability) const timingInfo = createOpaqueTimingInfo({ - startTime: currenTime + startTime: currentTime }) // 6. Let fetchParams be a new fetch params whose @@ -475,7 +476,7 @@ function fetching ({ } // 12. If request’s header list does not contain `Accept`, then: - if (!request.headersList.contains('accept')) { + if (!request.headersList.contains('accept', true)) { // 1. Let value be `*/*`. const value = '*/*' @@ -492,14 +493,14 @@ function fetching ({ // TODO // 3. Append `Accept`/value to request’s header list. - request.headersList.append('accept', value) + request.headersList.append('accept', value, true) } // 13. If request’s header list does not contain `Accept-Language`, then // user agents should append `Accept-Language`/an appropriate value to // request’s header list. - if (!request.headersList.contains('accept-language')) { - request.headersList.append('accept-language', '*') + if (!request.headersList.contains('accept-language', true)) { + request.headersList.append('accept-language', '*', true) } // 14. If request’s priority is null, then use request’s initiator and @@ -718,7 +719,7 @@ async function mainFetch (fetchParams, recursive = false) { response.type === 'opaque' && internalResponse.status === 206 && internalResponse.rangeRequested && - !request.headers.contains('range') + !request.headers.contains('range', true) ) { response = internalResponse = makeNetworkError() } @@ -815,38 +816,118 @@ function schemeFetch (fetchParams) { return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) } - const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()) + const blob = resolveObjectURL(blobURLEntry.toString()) // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s // object is not a Blob object, then return a network error. - if (request.method !== 'GET' || !isBlobLike(blobURLEntryObject)) { + if (request.method !== 'GET' || !isBlobLike(blob)) { return Promise.resolve(makeNetworkError('invalid method')) } - // 3. Let bodyWithType be the result of safely extracting blobURLEntry’s object. - const bodyWithType = safelyExtractBody(blobURLEntryObject) + // 3. Let blob be blobURLEntry’s object. + // Note: done above - // 4. Let body be bodyWithType’s body. - const body = bodyWithType[0] + // 4. Let response be a new response. + const response = makeResponse() - // 5. Let length be body’s length, serialized and isomorphic encoded. - const length = isomorphicEncode(`${body.length}`) + // 5. Let fullLength be blob’s size. + const fullLength = blob.size - // 6. Let type be bodyWithType’s type if it is non-null; otherwise the empty byte sequence. - const type = bodyWithType[1] ?? '' + // 6. Let serializedFullLength be fullLength, serialized and isomorphic encoded. + const serializedFullLength = isomorphicEncode(`${fullLength}`) - // 7. Return a new response whose status message is `OK`, header list is - // « (`Content-Length`, length), (`Content-Type`, type) », and body is body. - const response = makeResponse({ - statusText: 'OK', - headersList: [ - ['content-length', { name: 'Content-Length', value: length }], - ['content-type', { name: 'Content-Type', value: type }] - ] - }) + // 7. Let type be blob’s type. + const type = blob.type + + // 8. If request’s header list does not contain `Range`: + // 9. Otherwise: + if (!request.headersList.contains('range', true)) { + // 1. Let bodyWithType be the result of safely extracting blob. + // Note: in the FileAPI a blob "object" is a Blob *or* a MediaSource. + // In node, this can only ever be a Blob. Therefore we can safely + // use extractBody directly. + const bodyWithType = extractBody(blob) + + // 2. Set response’s status message to `OK`. + response.statusText = 'OK' + + // 3. Set response’s body to bodyWithType’s body. + response.body = bodyWithType[0] + + // 4. Set response’s header list to « (`Content-Length`, serializedFullLength), (`Content-Type`, type) ». + response.headersList.set('content-length', serializedFullLength, true) + response.headersList.set('content-type', type, true) + } else { + // 1. Set response’s range-requested flag. + response.rangeRequested = true + + // 2. Let rangeHeader be the result of getting `Range` from request’s header list. + const rangeHeader = request.headersList.get('range', true) + + // 3. Let rangeValue be the result of parsing a single range header value given rangeHeader and true. + const rangeValue = simpleRangeHeaderValue(rangeHeader, true) + + // 4. If rangeValue is failure, then return a network error. + if (rangeValue === 'failure') { + return Promise.resolve(makeNetworkError('failed to fetch the data URL')) + } + + // 5. Let (rangeStart, rangeEnd) be rangeValue. + let { rangeStartValue: rangeStart, rangeEndValue: rangeEnd } = rangeValue + + // 6. If rangeStart is null: + // 7. Otherwise: + if (rangeStart === null) { + // 1. Set rangeStart to fullLength − rangeEnd. + rangeStart = fullLength - rangeEnd + + // 2. Set rangeEnd to rangeStart + rangeEnd − 1. + rangeEnd = rangeStart + rangeEnd - 1 + } else { + // 1. If rangeStart is greater than or equal to fullLength, then return a network error. + if (rangeStart >= fullLength) { + return Promise.resolve(makeNetworkError('Range start is greater than the blob\'s size.')) + } + + // 2. If rangeEnd is null or rangeEnd is greater than or equal to fullLength, then set + // rangeEnd to fullLength − 1. + if (rangeEnd === null || rangeEnd >= fullLength) { + rangeEnd = fullLength - 1 + } + } + + // 8. Let slicedBlob be the result of invoking slice blob given blob, rangeStart, + // rangeEnd + 1, and type. + const slicedBlob = blob.slice(rangeStart, rangeEnd, type) + + // 9. Let slicedBodyWithType be the result of safely extracting slicedBlob. + // Note: same reason as mentioned above as to why we use extractBody + const slicedBodyWithType = extractBody(slicedBlob) + + // 10. Set response’s body to slicedBodyWithType’s body. + response.body = slicedBodyWithType[0] + + // 11. Let serializedSlicedLength be slicedBlob’s size, serialized and isomorphic encoded. + const serializedSlicedLength = isomorphicEncode(`${slicedBlob.size}`) + + // 12. Let contentRange be the result of invoking build a content range given rangeStart, + // rangeEnd, and fullLength. + const contentRange = buildContentRange(rangeStart, rangeEnd, fullLength) - response.body = body + // 13. Set response’s status to 206. + response.status = 206 + // 14. Set response’s status message to `Partial Content`. + response.statusText = 'Partial Content' + + // 15. Set response’s header list to « (`Content-Length`, serializedSlicedLength), + // (`Content-Type`, type), (`Content-Range`, contentRange) ». + response.headersList.set('content-length', serializedSlicedLength, true) + response.headersList.set('content-type', type, true) + response.headersList.set('content-range', contentRange, true) + } + + // 10. Return response. return Promise.resolve(response) } case 'data:': { @@ -908,92 +989,147 @@ function finalizeResponse (fetchParams, response) { // https://fetch.spec.whatwg.org/#fetch-finale function fetchFinale (fetchParams, response) { - // 1. If response is a network error, then: - if (response.type === 'error') { - // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ». - response.urlList = [fetchParams.request.urlList[0]] - - // 2. Set response’s timing info to the result of creating an opaque timing - // info for fetchParams’s timing info. - response.timingInfo = createOpaqueTimingInfo({ - startTime: fetchParams.timingInfo.startTime - }) - } + // 1. Let timingInfo be fetchParams’s timing info. + let timingInfo = fetchParams.timingInfo + + // 2. If response is not a network error and fetchParams’s request’s client is a secure context, + // then set timingInfo’s server-timing headers to the result of getting, decoding, and splitting + // `Server-Timing` from response’s internal response’s header list. + // TODO - // 2. Let processResponseEndOfBody be the following steps: + // 3. Let processResponseEndOfBody be the following steps: const processResponseEndOfBody = () => { - // 1. Set fetchParams’s request’s done flag. - fetchParams.request.done = true - - // If fetchParams’s process response end-of-body is not null, - // then queue a fetch task to run fetchParams’s process response - // end-of-body given response with fetchParams’s task destination. - if (fetchParams.processResponseEndOfBody != null) { - queueMicrotask(() => fetchParams.processResponseEndOfBody(response)) + // 1. Let unsafeEndTime be the unsafe shared current time. + const unsafeEndTime = Date.now() // ? + + // 2. If fetchParams’s request’s destination is "document", then set fetchParams’s controller’s + // full timing info to fetchParams’s timing info. + if (fetchParams.request.destination === 'document') { + fetchParams.controller.fullTimingInfo = timingInfo } + + // 3. Set fetchParams’s controller’s report timing steps to the following steps given a global object global: + fetchParams.controller.reportTimingSteps = () => { + // 1. If fetchParams’s request’s URL’s scheme is not an HTTP(S) scheme, then return. + if (fetchParams.request.url.protocol !== 'https:') { + return + } + + // 2. Set timingInfo’s end time to the relative high resolution time given unsafeEndTime and global. + timingInfo.endTime = unsafeEndTime + + // 3. Let cacheState be response’s cache state. + let cacheState = response.cacheState + + // 4. Let bodyInfo be response’s body info. + const bodyInfo = response.bodyInfo + + // 5. If response’s timing allow passed flag is not set, then set timingInfo to the result of creating an + // opaque timing info for timingInfo and set cacheState to the empty string. + if (!response.timingAllowPassed) { + timingInfo = createOpaqueTimingInfo(timingInfo) + + cacheState = '' + } + + // 6. Let responseStatus be 0. + let responseStatus = 0 + + // 7. If fetchParams’s request’s mode is not "navigate" or response’s has-cross-origin-redirects is false: + if (fetchParams.request.mode !== 'navigator' || !response.hasCrossOriginRedirects) { + // 1. Set responseStatus to response’s status. + responseStatus = response.status + + // 2. Let mimeType be the result of extracting a MIME type from response’s header list. + const mimeType = parseMIMEType(response.headersList.get('content-type', true)) // TODO: fix + + // 3. If mimeType is not failure, then set bodyInfo’s content type to the result of minimizing a supported MIME type given mimeType. + if (mimeType !== 'failure') { + // TODO + } + } + + // 8. If fetchParams’s request’s initiator type is non-null, then mark resource timing given timingInfo, + // fetchParams’s request’s URL, fetchParams’s request’s initiator type, global, cacheState, bodyInfo, + // and responseStatus. + if (fetchParams.request.initiatorType != null) { + // TODO: update markresourcetiming + markResourceTiming(timingInfo, fetchParams.request.url, fetchParams.request.initiatorType, globalThis, cacheState, bodyInfo, responseStatus) + } + } + + // 4. Let processResponseEndOfBodyTask be the following steps: + const processResponseEndOfBodyTask = () => { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true + + // 2. If fetchParams’s process response end-of-body is non-null, then run fetchParams’s process + // response end-of-body given response. + if (fetchParams.processResponseEndOfBody != null) { + queueMicrotask(() => fetchParams.processResponseEndOfBody(response)) + } + + // 3. If fetchParams’s request’s initiator type is non-null and fetchParams’s request’s client’s + // global object is fetchParams’s task destination, then run fetchParams’s controller’s report + // timing steps given fetchParams’s request’s client’s global object. + if (fetchParams.request.initiatorType != null) { + fetchParams.controller.reportTimingSteps() + } + } + + // 5. Queue a fetch task to run processResponseEndOfBodyTask with fetchParams’s task destination + queueMicrotask(() => processResponseEndOfBodyTask()) } - // 3. If fetchParams’s process response is non-null, then queue a fetch task - // to run fetchParams’s process response given response, with fetchParams’s - // task destination. + // 4. If fetchParams’s process response is non-null, then queue a fetch task to run fetchParams’s + // process response given response, with fetchParams’s task destination. if (fetchParams.processResponse != null) { queueMicrotask(() => fetchParams.processResponse(response)) } - // 4. If response’s body is null, then run processResponseEndOfBody. - if (response.body == null) { + // 5. Let internalResponse be response, if response is a network error; otherwise response’s internal response. + const internalResponse = response.type === 'error' ? response : (response.internalResponse ?? response) + + // 6. If internalResponse’s body is null, then run processResponseEndOfBody. + // 7. Otherwise: + if (internalResponse.body == null) { processResponseEndOfBody() } else { - // 5. Otherwise: - - // 1. Let transformStream be a new a TransformStream. - - // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, - // enqueues chunk in transformStream. - const identityTransformAlgorithm = (chunk, controller) => { - controller.enqueue(chunk) - } - - // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm - // and flushAlgorithm set to processResponseEndOfBody. + // 1. Let transformStream be a new TransformStream. + // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, enqueues chunk in transformStream. + // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm and flushAlgorithm + // set to processResponseEndOfBody. const transformStream = new TransformStream({ start () {}, - transform: identityTransformAlgorithm, + transform (chunk, controller) { + controller.enqueue(chunk) + }, flush: processResponseEndOfBody - }, { - size () { - return 1 - } - }, { - size () { - return 1 - } }) - // 4. Set response’s body to the result of piping response’s body through transformStream. - response.body = { stream: response.body.stream.pipeThrough(transformStream) } - } + // 4. Set internalResponse’s body’s stream to the result of internalResponse’s body’s stream piped through transformStream. + internalResponse.body.stream.pipeThrough(transformStream) - // 6. If fetchParams’s process response consume body is non-null, then: - if (fetchParams.processResponseConsumeBody != null) { - // 1. Let processBody given nullOrBytes be this step: run fetchParams’s - // process response consume body given response and nullOrBytes. - const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes) + const byteStream = new ReadableStream({ + readableStream: transformStream.readable, + async start (controller) { + const reader = this.readableStream.getReader() - // 2. Let processBodyError be this step: run fetchParams’s process - // response consume body given response and failure. - const processBodyError = (failure) => fetchParams.processResponseConsumeBody(response, failure) + while (true) { + const { done, value } = await reader.read() - // 3. If response’s body is null, then queue a fetch task to run processBody - // given null, with fetchParams’s task destination. - if (response.body == null) { - queueMicrotask(() => processBody(null)) - } else { - // 4. Otherwise, fully read response’s body given processBody, processBodyError, - // and fetchParams’s task destination. - return fullyReadBody(response.body, processBody, processBodyError) - } - return Promise.resolve() + if (done) { + queueMicrotask(() => readableStreamClose(controller)) + break + } + + controller.enqueue(value) + } + }, + type: 'bytes' + }) + + internalResponse.body.stream = byteStream } } @@ -1201,11 +1337,11 @@ function httpRedirectFetch (fetchParams, response) { // delete headerName from request’s header list. if (!sameOrigin(requestCurrentURL(request), locationURL)) { // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name - request.headersList.delete('authorization') + request.headersList.delete('authorization', true) // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. - request.headersList.delete('cookie') - request.headersList.delete('host') + request.headersList.delete('cookie', true) + request.headersList.delete('host', true) } // 14. If request’s body is non-null, then set request’s body to the first return @@ -1321,7 +1457,7 @@ async function httpNetworkOrCacheFetch ( // `Content-Length`/contentLengthHeaderValue to httpRequest’s header // list. if (contentLengthHeaderValue != null) { - httpRequest.headersList.append('content-length', contentLengthHeaderValue) + httpRequest.headersList.append('content-length', contentLengthHeaderValue, true) } // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, @@ -1337,7 +1473,7 @@ async function httpNetworkOrCacheFetch ( // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, // to httpRequest’s header list. if (httpRequest.referrer instanceof URL) { - httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href)) + httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href), true) } // 12. Append a request `Origin` header for httpRequest. @@ -1349,8 +1485,8 @@ async function httpNetworkOrCacheFetch ( // 14. If httpRequest’s header list does not contain `User-Agent`, then // user agents should append `User-Agent`/default `User-Agent` value to // httpRequest’s header list. - if (!httpRequest.headersList.contains('user-agent')) { - httpRequest.headersList.append('user-agent', typeof esbuildDetection === 'undefined' ? 'undici' : 'node') + if (!httpRequest.headersList.contains('user-agent', true)) { + httpRequest.headersList.append('user-agent', typeof esbuildDetection === 'undefined' ? 'undici' : 'node', true) } // 15. If httpRequest’s cache mode is "default" and httpRequest’s header @@ -1359,11 +1495,11 @@ async function httpNetworkOrCacheFetch ( // httpRequest’s cache mode to "no-store". if ( httpRequest.cache === 'default' && - (httpRequest.headersList.contains('if-modified-since') || - httpRequest.headersList.contains('if-none-match') || - httpRequest.headersList.contains('if-unmodified-since') || - httpRequest.headersList.contains('if-match') || - httpRequest.headersList.contains('if-range')) + (httpRequest.headersList.contains('if-modified-since', true) || + httpRequest.headersList.contains('if-none-match', true) || + httpRequest.headersList.contains('if-unmodified-since', true) || + httpRequest.headersList.contains('if-match', true) || + httpRequest.headersList.contains('if-range', true)) ) { httpRequest.cache = 'no-store' } @@ -1375,44 +1511,44 @@ async function httpNetworkOrCacheFetch ( if ( httpRequest.cache === 'no-cache' && !httpRequest.preventNoCacheCacheControlHeaderModification && - !httpRequest.headersList.contains('cache-control') + !httpRequest.headersList.contains('cache-control', true) ) { - httpRequest.headersList.append('cache-control', 'max-age=0') + httpRequest.headersList.append('cache-control', 'max-age=0', true) } // 17. If httpRequest’s cache mode is "no-store" or "reload", then: if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') { // 1. If httpRequest’s header list does not contain `Pragma`, then append // `Pragma`/`no-cache` to httpRequest’s header list. - if (!httpRequest.headersList.contains('pragma')) { - httpRequest.headersList.append('pragma', 'no-cache') + if (!httpRequest.headersList.contains('pragma', true)) { + httpRequest.headersList.append('pragma', 'no-cache', true) } // 2. If httpRequest’s header list does not contain `Cache-Control`, // then append `Cache-Control`/`no-cache` to httpRequest’s header list. - if (!httpRequest.headersList.contains('cache-control')) { - httpRequest.headersList.append('cache-control', 'no-cache') + if (!httpRequest.headersList.contains('cache-control', true)) { + httpRequest.headersList.append('cache-control', 'no-cache', true) } } // 18. If httpRequest’s header list contains `Range`, then append // `Accept-Encoding`/`identity` to httpRequest’s header list. - if (httpRequest.headersList.contains('range')) { - httpRequest.headersList.append('accept-encoding', 'identity') + if (httpRequest.headersList.contains('range', true)) { + httpRequest.headersList.append('accept-encoding', 'identity', true) } // 19. Modify httpRequest’s header list per HTTP. Do not append a given // header if httpRequest’s header list contains that header’s name. // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 - if (!httpRequest.headersList.contains('accept-encoding')) { + if (!httpRequest.headersList.contains('accept-encoding', true)) { if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { - httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate') + httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate', true) } else { - httpRequest.headersList.append('accept-encoding', 'gzip, deflate') + httpRequest.headersList.append('accept-encoding', 'gzip, deflate', true) } } - httpRequest.headersList.delete('host') + httpRequest.headersList.delete('host', true) // 20. If includeCredentials is true, then: if (includeCredentials) { @@ -1495,7 +1631,7 @@ async function httpNetworkOrCacheFetch ( // 12. If httpRequest’s header list contains `Range`, then set response’s // range-requested flag. - if (httpRequest.headersList.contains('range')) { + if (httpRequest.headersList.contains('range', true)) { response.rangeRequested = true } @@ -1795,13 +1931,8 @@ async function httpNetworkFetch ( // TODO // 15. Let stream be a new ReadableStream. - // 16. Set up stream with pullAlgorithm set to pullAlgorithm, - // cancelAlgorithm set to cancelAlgorithm, highWaterMark set to - // highWaterMark, and sizeAlgorithm set to sizeAlgorithm. - if (!ReadableStream) { - ReadableStream = require('stream/web').ReadableStream - } - + // 16. Set up stream with byte reading support with pullAlgorithm set to pullAlgorithm, + // cancelAlgorithm set to cancelAlgorithm. const stream = new ReadableStream( { async start (controller) { @@ -1812,13 +1943,8 @@ async function httpNetworkFetch ( }, async cancel (reason) { await cancelAlgorithm(reason) - } - }, - { - highWaterMark: 0, - size () { - return 1 - } + }, + type: 'bytes' } ) @@ -1898,7 +2024,10 @@ async function httpNetworkFetch ( // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes // into stream. - fetchParams.controller.controller.enqueue(new Uint8Array(bytes)) + const buffer = new Uint8Array(bytes) + if (buffer.byteLength) { + fetchParams.controller.controller.enqueue(buffer) + } // 8. If stream is errored, then terminate the ongoing fetch. if (isErrored(stream)) { @@ -1947,7 +2076,7 @@ async function httpNetworkFetch ( // 20. Return response. return response - async function dispatch ({ body }) { + function dispatch ({ body }) { const url = requestCurrentURL(request) /** @type {import('../..').Agent} */ const agent = fetchParams.controller.dispatcher @@ -1957,7 +2086,7 @@ async function httpNetworkFetch ( path: url.pathname + url.search, origin: url.origin, method: request.method, - body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, + body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body, headers: request.headersList.entries, maxRedirections: 0, upgrade: request.mode === 'websocket' ? 'websocket' : undefined @@ -1970,67 +2099,83 @@ async function httpNetworkFetch ( // TODO (fix): Do we need connection here? const { connection } = fetchParams.controller + // Set timingInfo’s final connection timing info to the result of calling clamp and coarsen + // connection timing info with connection’s timing info, timingInfo’s post-redirect start + // time, and fetchParams’s cross-origin isolated capability. + // TODO: implement connection timing + timingInfo.finalConnectionTimingInfo = clampAndCoursenConnectionTimingInfo(undefined, timingInfo.postRedirectStartTime, fetchParams.crossOriginIsolatedCapability) + if (connection.destroyed) { abort(new DOMException('The operation was aborted.', 'AbortError')) } else { fetchParams.controller.on('terminated', abort) this.abort = connection.abort = abort } + + // Set timingInfo’s final network-request start time to the coarsened shared current time given + // fetchParams’s cross-origin isolated capability. + timingInfo.finalNetworkRequestStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) + }, + + onResponseStarted () { + // Set timingInfo’s final network-response start time to the coarsened shared current + // time given fetchParams’s cross-origin isolated capability, immediately after the + // user agent’s HTTP parser receives the first byte of the response (e.g., frame header + // bytes for HTTP/2 or response status line for HTTP/1.x). + timingInfo.finalNetworkResponseStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) }, - onHeaders (status, headersList, resume, statusText) { + onHeaders (status, rawHeaders, resume, statusText) { if (status < 200) { return } + /** @type {string[]} */ let codings = [] let location = '' - const headers = new Headers() + const headersList = new HeadersList() - // For H2, the headers are a plain JS object + // For H2, the rawHeaders are a plain JS object // We distinguish between them and iterate accordingly - if (Array.isArray(headersList)) { - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString('latin1') - const val = headersList[n + 1].toString('latin1') - if (key.toLowerCase() === 'content-encoding') { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = val.toLowerCase().split(',').map((x) => x.trim()) - } else if (key.toLowerCase() === 'location') { - location = val - } - - headers[kHeadersList].append(key, val) + if (Array.isArray(rawHeaders)) { + for (let i = 0; i < rawHeaders.length; i += 2) { + headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true) } + const contentEncoding = headersList.get('content-encoding', true) + if (contentEncoding) { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = contentEncoding.toLowerCase().split(',').map((x) => x.trim()) + } + location = headersList.get('location', true) } else { - const keys = Object.keys(headersList) - for (const key of keys) { - const val = headersList[key] - if (key.toLowerCase() === 'content-encoding') { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = val.toLowerCase().split(',').map((x) => x.trim()).reverse() - } else if (key.toLowerCase() === 'location') { - location = val - } - - headers[kHeadersList].append(key, val) + const keys = Object.keys(rawHeaders) + for (let i = 0; i < keys.length; ++i) { + headersList.append(keys[i], rawHeaders[keys[i]]) } + // For H2, The header names are already in lowercase, + // so we can avoid the `HeadersList#get` call here. + const contentEncoding = rawHeaders['content-encoding'] + if (contentEncoding) { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = contentEncoding.toLowerCase().split(',').map((x) => x.trim()).reverse() + } + location = rawHeaders.location } this.body = new Readable({ read: resume }) const decoders = [] - const willFollow = request.redirect === 'follow' && - location && + const willFollow = location && request.redirect === 'follow' && redirectStatusSet.has(status) // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { - for (const coding of codings) { + for (let i = 0; i < codings.length; ++i) { + const coding = codings[i] // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 if (coding === 'x-gzip' || coding === 'gzip') { decoders.push(zlib.createGunzip({ @@ -2055,7 +2200,7 @@ async function httpNetworkFetch ( resolve({ status, statusText, - headersList: headers[kHeadersList], + headersList, body: decoders.length ? pipeline(this.body, ...decoders, () => { }) : this.body.on('error', () => {}) @@ -2109,24 +2254,21 @@ async function httpNetworkFetch ( reject(error) }, - onUpgrade (status, headersList, socket) { + onUpgrade (status, rawHeaders, socket) { if (status !== 101) { return } - const headers = new Headers() - - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString('latin1') - const val = headersList[n + 1].toString('latin1') + const headersList = new HeadersList() - headers[kHeadersList].append(key, val) + for (let i = 0; i < rawHeaders.length; i += 2) { + headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true) } resolve({ status, statusText: STATUS_CODES[status], - headersList: headers[kHeadersList], + headersList, socket }) diff --git a/deps/undici/src/lib/fetch/request.js b/deps/undici/src/lib/fetch/request.js index 6fe4dff64c4472..85b8bb0df2f886 100644 --- a/deps/undici/src/lib/fetch/request.js +++ b/deps/undici/src/lib/fetch/request.js @@ -32,8 +32,6 @@ const { kHeadersList, kConstruct } = require('../core/symbols') const assert = require('assert') const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = require('events') -let TransformStream = globalThis.TransformStream - const kAbortController = Symbol('abortController') const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { @@ -516,10 +514,6 @@ class Request { } // 2. Set finalBody to the result of creating a proxy for inputBody. - if (!TransformStream) { - TransformStream = require('stream/web').TransformStream - } - // https://streams.spec.whatwg.org/#readablestream-create-a-proxy const identityTransform = new TransformStream() inputBody.stream.pipeThrough(identityTransform) diff --git a/deps/undici/src/lib/fetch/response.js b/deps/undici/src/lib/fetch/response.js index 73386123e33c8d..f8894b692ebc58 100644 --- a/deps/undici/src/lib/fetch/response.js +++ b/deps/undici/src/lib/fetch/response.js @@ -15,8 +15,7 @@ const { } = require('./util') const { redirectStatusSet, - nullBodyStatus, - DOMException + nullBodyStatus } = require('./constants') const { kState, kHeaders, kGuard, kRealm } = require('./symbols') const { webidl } = require('./webidl') @@ -27,7 +26,6 @@ const { kHeadersList, kConstruct } = require('../core/symbols') const assert = require('assert') const { types } = require('util') -const ReadableStream = globalThis.ReadableStream || require('stream/web').ReadableStream const textEncoder = new TextEncoder('utf-8') // https://fetch.spec.whatwg.org/#response-class @@ -40,9 +38,10 @@ class Response { // The static error() method steps are to return the result of creating a // Response object, given a new network error, "immutable", and this’s // relevant Realm. - const responseObject = new Response() + const responseObject = new Response(kConstruct) responseObject[kState] = makeNetworkError() responseObject[kRealm] = relevantRealm + responseObject[kHeaders] = new Headers(kConstruct) responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList responseObject[kHeaders][kGuard] = 'immutable' responseObject[kHeaders][kRealm] = relevantRealm @@ -68,8 +67,11 @@ class Response { // 3. Let responseObject be the result of creating a Response object, given a new response, // "response", and this’s relevant Realm. const relevantRealm = { settingsObject: {} } - const responseObject = new Response() + const responseObject = new Response(kConstruct) + responseObject[kState] = makeResponse({}) responseObject[kRealm] = relevantRealm + responseObject[kHeaders] = new Headers(kConstruct) + responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList responseObject[kHeaders][kGuard] = 'response' responseObject[kHeaders][kRealm] = relevantRealm @@ -109,8 +111,11 @@ class Response { // 4. Let responseObject be the result of creating a Response object, // given a new response, "immutable", and this’s relevant Realm. - const responseObject = new Response() + const responseObject = new Response(kConstruct) + responseObject[kState] = makeResponse({}) responseObject[kRealm] = relevantRealm + responseObject[kHeaders] = new Headers(kConstruct) + responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList responseObject[kHeaders][kGuard] = 'immutable' responseObject[kHeaders][kRealm] = relevantRealm @@ -121,7 +126,7 @@ class Response { const value = isomorphicEncode(URLSerializer(parsedURL)) // 7. Append `Location`/value to responseObject’s response’s header list. - responseObject[kState].headersList.append('location', value) + responseObject[kState].headersList.append('location', value, true) // 8. Return responseObject. return responseObject @@ -129,6 +134,10 @@ class Response { // https://fetch.spec.whatwg.org/#dom-response constructor (body = null, init = {}) { + if (body === kConstruct) { + return + } + if (body !== null) { body = webidl.converters.BodyInit(body) } @@ -260,9 +269,10 @@ class Response { // 3. Return the result of creating a Response object, given // clonedResponse, this’s headers’s guard, and this’s relevant Realm. - const clonedResponseObject = new Response() + const clonedResponseObject = new Response(kConstruct) clonedResponseObject[kState] = clonedResponse clonedResponseObject[kRealm] = this[kRealm] + clonedResponseObject[kHeaders] = new Headers(kConstruct) clonedResponseObject[kHeaders][kHeadersList] = clonedResponse.headersList clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard] clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm] @@ -335,10 +345,10 @@ function makeResponse (init) { cacheState: '', statusText: '', ...init, - headersList: init.headersList - ? new HeadersList(init.headersList) + headersList: init?.headersList + ? new HeadersList(init?.headersList) : new HeadersList(), - urlList: init.urlList ? [...init.urlList] : [] + urlList: init?.urlList ? [...init.urlList] : [] } } @@ -486,8 +496,8 @@ function initializeResponse (response, init, body) { // 3. If body's type is non-null and response's header list does not contain // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. - if (body.type != null && !response[kState].headersList.contains('Content-Type')) { - response[kState].headersList.append('content-type', body.type) + if (body.type != null && !response[kState].headersList.contains('content-type', true)) { + response[kState].headersList.append('content-type', body.type, true) } } } diff --git a/deps/undici/src/lib/fetch/util.js b/deps/undici/src/lib/fetch/util.js index b12142c7f42505..32983720cc0581 100644 --- a/deps/undici/src/lib/fetch/util.js +++ b/deps/undici/src/lib/fetch/util.js @@ -3,7 +3,7 @@ const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require('./constants') const { getGlobalOrigin } = require('./global') const { performance } = require('perf_hooks') -const { isBlobLike, toUSVString, ReadableStreamFrom } = require('../core/util') +const { isBlobLike, toUSVString, ReadableStreamFrom, isValidHTTPToken } = require('../core/util') const assert = require('assert') const { isUint8Array } = require('util/types') @@ -35,7 +35,7 @@ function responseLocationURL (response, requestFragment) { // 2. Let location be the result of extracting header list values given // `Location` and response’s header list. - let location = response.headersList.get('location') + let location = response.headersList.get('location', true) // 3. If location is a header value, then set location to the result of // parsing location with response’s URL. @@ -103,52 +103,6 @@ function isValidReasonPhrase (statusText) { return true } -/** - * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 - * @param {number} c - */ -function isTokenCharCode (c) { - switch (c) { - case 0x22: - case 0x28: - case 0x29: - case 0x2c: - case 0x2f: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - case 0x40: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x7b: - case 0x7d: - // DQUOTE and "(),/:;<=>?@[\]{}" - return false - default: - // VCHAR %x21-7E - return c >= 0x21 && c <= 0x7e - } -} - -/** - * @param {string} characters - */ -function isValidHTTPToken (characters) { - if (characters.length === 0) { - return false - } - for (let i = 0; i < characters.length; ++i) { - if (!isTokenCharCode(characters.charCodeAt(i))) { - return false - } - } - return true -} - /** * @see https://fetch.spec.whatwg.org/#header-name * @param {string} potentialValue @@ -199,7 +153,7 @@ function setRequestReferrerPolicyOnRedirect (request, actualResponse) { // 2. Let policy be the empty string. // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. // 4. Return policy. - const policyHeader = (headersList.get('referrer-policy') ?? '').split(',') + const policyHeader = (headersList.get('referrer-policy', true) ?? '').split(',') // Note: As the referrer-policy can contain multiple policies // separated by comma, we need to loop through all of them @@ -258,7 +212,7 @@ function appendFetchMetadata (httpRequest) { header = httpRequest.mode // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. - httpRequest.headersList.set('sec-fetch-mode', header) + httpRequest.headersList.set('sec-fetch-mode', header, true) // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header // TODO @@ -275,7 +229,7 @@ function appendRequestOriginHeader (request) { // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list. if (request.responseTainting === 'cors' || request.mode === 'websocket') { if (serializedOrigin) { - request.headersList.append('origin', serializedOrigin) + request.headersList.append('origin', serializedOrigin, true) } // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: @@ -306,14 +260,43 @@ function appendRequestOriginHeader (request) { if (serializedOrigin) { // 2. Append (`Origin`, serializedOrigin) to request’s header list. - request.headersList.append('origin', serializedOrigin) + request.headersList.append('origin', serializedOrigin, true) } } } -function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { +// https://w3c.github.io/hr-time/#dfn-coarsen-time +function coarsenTime (timestamp, crossOriginIsolatedCapability) { // TODO - return performance.now() + return timestamp +} + +// https://fetch.spec.whatwg.org/#clamp-and-coarsen-connection-timing-info +function clampAndCoursenConnectionTimingInfo (connectionTimingInfo, defaultStartTime, crossOriginIsolatedCapability) { + if (!connectionTimingInfo?.startTime || connectionTimingInfo.startTime < defaultStartTime) { + return { + domainLookupStartTime: defaultStartTime, + domainLookupEndTime: defaultStartTime, + connectionStartTime: defaultStartTime, + connectionEndTime: defaultStartTime, + secureConnectionStartTime: defaultStartTime, + ALPNNegotiatedProtocol: connectionTimingInfo?.ALPNNegotiatedProtocol + } + } + + return { + domainLookupStartTime: coarsenTime(connectionTimingInfo.domainLookupStartTime, crossOriginIsolatedCapability), + domainLookupEndTime: coarsenTime(connectionTimingInfo.domainLookupEndTime, crossOriginIsolatedCapability), + connectionStartTime: coarsenTime(connectionTimingInfo.connectionStartTime, crossOriginIsolatedCapability), + connectionEndTime: coarsenTime(connectionTimingInfo.connectionEndTime, crossOriginIsolatedCapability), + secureConnectionStartTime: coarsenTime(connectionTimingInfo.secureConnectionStartTime, crossOriginIsolatedCapability), + ALPNNegotiatedProtocol: connectionTimingInfo.ALPNNegotiatedProtocol + } +} + +// https://w3c.github.io/hr-time/#dfn-coarsened-shared-current-time +function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { + return coarsenTime(performance.now(), crossOriginIsolatedCapability) } // https://fetch.spec.whatwg.org/#create-an-opaque-timing-info @@ -890,36 +873,34 @@ async function fullyReadBody (body, processBody, processBodyError) { } } -/** @type {ReadableStream} */ -let ReadableStream = globalThis.ReadableStream - function isReadableStreamLike (stream) { - if (!ReadableStream) { - ReadableStream = require('stream/web').ReadableStream - } - return stream instanceof ReadableStream || ( stream[Symbol.toStringTag] === 'ReadableStream' && typeof stream.tee === 'function' ) } -const MAXIMUM_ARGUMENT_LENGTH = 65535 - /** * @see https://infra.spec.whatwg.org/#isomorphic-decode - * @param {number[]|Uint8Array} input + * @param {Uint8Array} input */ function isomorphicDecode (input) { // 1. To isomorphic decode a byte sequence input, return a string whose code point // length is equal to input’s length and whose code points have the same values // as the values of input’s bytes, in the same order. - - if (input.length < MAXIMUM_ARGUMENT_LENGTH) { - return String.fromCharCode(...input) + const length = input.length + if ((2 << 15) - 1 > length) { + return String.fromCharCode.apply(null, input) } - - return input.reduce((previous, current) => previous + String.fromCharCode(current), '') + let result = ''; let i = 0 + let addition = (2 << 15) - 1 + while (i < length) { + if (i + addition > length) { + addition = length - i + } + result += String.fromCharCode.apply(null, input.subarray(i, i += addition)) + } + return result } /** @@ -928,9 +909,10 @@ function isomorphicDecode (input) { function readableStreamClose (controller) { try { controller.close() + controller.byobRequest?.respond(0) } catch (err) { // TODO: add comment explaining why this error occurs. - if (!err.message.includes('Controller is already closed')) { + if (!err.message.includes('Controller is already closed') && !err.message.includes('ReadableStream is already closed')) { throw err } } @@ -1018,10 +1000,172 @@ function urlIsHttpHttpsScheme (url) { return protocol === 'http:' || protocol === 'https:' } +/** @type {import('./dataURL')['collectASequenceOfCodePoints']} */ +let collectASequenceOfCodePoints + /** - * Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0. + * @see https://fetch.spec.whatwg.org/#simple-range-header-value + * @param {string} value + * @param {boolean} allowWhitespace */ -const hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)) +function simpleRangeHeaderValue (value, allowWhitespace) { + // Note: avoid circular require + collectASequenceOfCodePoints ??= require('./dataURL').collectASequenceOfCodePoints + + // 1. Let data be the isomorphic decoding of value. + // Note: isomorphic decoding takes a sequence of bytes (ie. a Uint8Array) and turns it into a string, + // nothing more. We obviously don't need to do that if value is a string already. + const data = value + + // 2. If data does not start with "bytes", then return failure. + if (!data.startsWith('bytes')) { + return 'failure' + } + + // 3. Let position be a position variable for data, initially pointing at the 5th code point of data. + const position = { position: 5 } + + // 4. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, + // from data given position. + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === '\t' || char === ' ', + data, + position + ) + } + + // 5. If the code point at position within data is not U+003D (=), then return failure. + if (data.charCodeAt(position.position) !== 0x3D) { + return 'failure' + } + + // 6. Advance position by 1. + position.position++ + + // 7. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, from + // data given position. + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === '\t' || char === ' ', + data, + position + ) + } + + // 8. Let rangeStart be the result of collecting a sequence of code points that are ASCII digits, + // from data given position. + const rangeStart = collectASequenceOfCodePoints( + (char) => { + const code = char.charCodeAt(0) + + return code >= 0x30 && code <= 0x39 + }, + data, + position + ) + + // 9. Let rangeStartValue be rangeStart, interpreted as decimal number, if rangeStart is not the + // empty string; otherwise null. + const rangeStartValue = rangeStart.length ? Number(rangeStart) : null + + // 10. If allowWhitespace is true, collect a sequence of code points that are HTTP tab or space, + // from data given position. + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === '\t' || char === ' ', + data, + position + ) + } + + // 11. If the code point at position within data is not U+002D (-), then return failure. + if (data.charCodeAt(position.position) !== 0x2D) { + return 'failure' + } + + // 12. Advance position by 1. + position.position++ + + // 13. If allowWhitespace is true, collect a sequence of code points that are HTTP tab + // or space, from data given position. + // Note from Khafra: its the same fucking step again lol + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === '\t' || char === ' ', + data, + position + ) + } + + // 14. Let rangeEnd be the result of collecting a sequence of code points that are + // ASCII digits, from data given position. + // Note from Khafra: you wouldn't guess it, but this is also the same step as #8 + const rangeEnd = collectASequenceOfCodePoints( + (char) => { + const code = char.charCodeAt(0) + + return code >= 0x30 && code <= 0x39 + }, + data, + position + ) + + // 15. Let rangeEndValue be rangeEnd, interpreted as decimal number, if rangeEnd + // is not the empty string; otherwise null. + // Note from Khafra: THE SAME STEP, AGAIN!!! + // Note: why interpret as a decimal if we only collect ascii digits? + const rangeEndValue = rangeEnd.length ? Number(rangeEnd) : null + + // 16. If position is not past the end of data, then return failure. + if (position.position < data.length) { + return 'failure' + } + + // 17. If rangeEndValue and rangeStartValue are null, then return failure. + if (rangeEndValue === null && rangeStartValue === null) { + return 'failure' + } + + // 18. If rangeStartValue and rangeEndValue are numbers, and rangeStartValue is + // greater than rangeEndValue, then return failure. + // Note: ... when can they not be numbers? + if (rangeStartValue > rangeEndValue) { + return 'failure' + } + + // 19. Return (rangeStartValue, rangeEndValue). + return { rangeStartValue, rangeEndValue } +} + +/** + * @see https://fetch.spec.whatwg.org/#build-a-content-range + * @param {number} rangeStart + * @param {number} rangeEnd + * @param {number} fullLength + */ +function buildContentRange (rangeStart, rangeEnd, fullLength) { + // 1. Let contentRange be `bytes `. + let contentRange = 'bytes ' + + // 2. Append rangeStart, serialized and isomorphic encoded, to contentRange. + contentRange += isomorphicEncode(`${rangeStart}`) + + // 3. Append 0x2D (-) to contentRange. + contentRange += '-' + + // 4. Append rangeEnd, serialized and isomorphic encoded to contentRange. + contentRange += isomorphicEncode(`${rangeEnd}`) + + // 5. Append 0x2F (/) to contentRange. + contentRange += '/' + + // 6. Append fullLength, serialized and isomorphic encoded to contentRange. + contentRange += isomorphicEncode(`${fullLength}`) + + // 7. Return contentRange. + return contentRange +} module.exports = { isAborted, @@ -1030,6 +1174,7 @@ module.exports = { ReadableStreamFrom, toUSVString, tryUpgradeRequestToAPotentiallyTrustworthyURL, + clampAndCoursenConnectionTimingInfo, coarsenedSharedCurrentTime, determineRequestsReferrer, makePolicyContainer, @@ -1055,7 +1200,6 @@ module.exports = { makeIterator, isValidHeaderName, isValidHeaderValue, - hasOwn, isErrorLike, fullyReadBody, bytesMatch, @@ -1067,5 +1211,7 @@ module.exports = { urlHasHttpsScheme, urlIsHttpHttpsScheme, readAllBytes, - normalizeMethodRecord + normalizeMethodRecord, + simpleRangeHeaderValue, + buildContentRange } diff --git a/deps/undici/src/lib/fetch/webidl.js b/deps/undici/src/lib/fetch/webidl.js index 6fcf2ab6ad4c49..ca1019221d9ab3 100644 --- a/deps/undici/src/lib/fetch/webidl.js +++ b/deps/undici/src/lib/fetch/webidl.js @@ -1,7 +1,7 @@ 'use strict' const { types } = require('util') -const { hasOwn, toUSVString } = require('./util') +const { toUSVString } = require('./util') /** @type {import('../../types/webidl').Webidl} */ const webidl = {} @@ -346,7 +346,7 @@ webidl.dictionaryConverter = function (converters) { const { key, defaultValue, required, converter } = options if (required === true) { - if (!hasOwn(dictionary, key)) { + if (!Object.hasOwn(dictionary, key)) { throw webidl.errors.exception({ header: 'Dictionary', message: `Missing required key "${key}".` @@ -355,7 +355,7 @@ webidl.dictionaryConverter = function (converters) { } let value = dictionary[key] - const hasDefault = hasOwn(options, 'defaultValue') + const hasDefault = Object.hasOwn(options, 'defaultValue') // Only use defaultValue if value is undefined and // a defaultValue options was provided. diff --git a/deps/undici/src/lib/fileapi/util.js b/deps/undici/src/lib/fileapi/util.js index 1d10899cee8291..a29423d9d14370 100644 --- a/deps/undici/src/lib/fileapi/util.js +++ b/deps/undici/src/lib/fileapi/util.js @@ -9,7 +9,6 @@ const { } = require('./symbols') const { ProgressEvent } = require('./progressevent') const { getEncoding } = require('./encoding') -const { DOMException } = require('../fetch/constants') const { serializeAMimeType, parseMIMEType } = require('../fetch/dataURL') const { types } = require('util') const { StringDecoder } = require('string_decoder') diff --git a/deps/undici/src/lib/handler/RedirectHandler.js b/deps/undici/src/lib/handler/RedirectHandler.js index baca27ed147347..d8e96ddd844dd3 100644 --- a/deps/undici/src/lib/handler/RedirectHandler.js +++ b/deps/undici/src/lib/handler/RedirectHandler.js @@ -135,7 +135,7 @@ class RedirectHandler { For status 300, which is "Multiple Choices", the spec mentions both generating a Location response header AND a response body with the other possible location to follow. - Since the spec explicitily chooses not to specify a format for such body and leave it to + Since the spec explicitly chooses not to specify a format for such body and leave it to servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. */ } else { @@ -151,7 +151,7 @@ class RedirectHandler { TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections and neither are useful if present. - See comment on onData method above for more detailed informations. + See comment on onData method above for more detailed information. */ this.location = null @@ -176,7 +176,7 @@ function parseLocation (statusCode, headers) { } for (let i = 0; i < headers.length; i += 2) { - if (headers[i].toString().toLowerCase() === 'location') { + if (headers[i].length === 8 && util.headerNameToString(headers[i]) === 'location') { return headers[i + 1] } } @@ -184,12 +184,17 @@ function parseLocation (statusCode, headers) { // https://tools.ietf.org/html/rfc7231#section-6.4.4 function shouldRemoveHeader (header, removeContent, unknownOrigin) { - return ( - (header.length === 4 && header.toString().toLowerCase() === 'host') || - (removeContent && header.toString().toLowerCase().indexOf('content-') === 0) || - (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') || - (unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie') - ) + if (header.length === 4) { + return util.headerNameToString(header) === 'host' + } + if (removeContent && util.headerNameToString(header).startsWith('content-')) { + return true + } + if (unknownOrigin && (header.length === 13 || header.length === 6)) { + const name = util.headerNameToString(header) + return name === 'authorization' || name === 'cookie' + } + return false } // https://tools.ietf.org/html/rfc7231#section-6.4 diff --git a/deps/undici/src/lib/handler/RetryHandler.js b/deps/undici/src/lib/handler/RetryHandler.js index 371044719fd33d..da35d256baab06 100644 --- a/deps/undici/src/lib/handler/RetryHandler.js +++ b/deps/undici/src/lib/handler/RetryHandler.js @@ -172,13 +172,22 @@ class RetryHandler { this.retryCount += 1 if (statusCode >= 300) { - this.abort( - new RequestRetryError('Request failed', statusCode, { - headers, - count: this.retryCount - }) - ) - return false + if (this.retryOpts.statusCodes.includes(statusCode) === false) { + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } else { + this.abort( + new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } } // Checkpoint for resume from where we left it diff --git a/deps/undici/src/lib/mock/mock-agent.js b/deps/undici/src/lib/mock/mock-agent.js index 828e8af174d5f2..4b29cd0112fb79 100644 --- a/deps/undici/src/lib/mock/mock-agent.js +++ b/deps/undici/src/lib/mock/mock-agent.js @@ -21,16 +21,6 @@ const Dispatcher = require('../dispatcher') const Pluralizer = require('./pluralizer') const PendingInterceptorsFormatter = require('./pending-interceptors-formatter') -class FakeWeakRef { - constructor (value) { - this.value = value - } - - deref () { - return this.value - } -} - class MockAgent extends Dispatcher { constructor (opts) { super(opts) @@ -103,7 +93,7 @@ class MockAgent extends Dispatcher { } [kMockAgentSet] (origin, dispatcher) { - this[kClients].set(origin, new FakeWeakRef(dispatcher)) + this[kClients].set(origin, dispatcher) } [kFactory] (origin) { @@ -115,9 +105,9 @@ class MockAgent extends Dispatcher { [kMockAgentGet] (origin) { // First check if we can immediately find it - const ref = this[kClients].get(origin) - if (ref) { - return ref.deref() + const client = this[kClients].get(origin) + if (client) { + return client } // If the origin is not a string create a dummy parent pool and return to user @@ -128,8 +118,7 @@ class MockAgent extends Dispatcher { } // If we match, create a pool and assign the same dispatches - for (const [keyMatcher, nonExplicitRef] of Array.from(this[kClients])) { - const nonExplicitDispatcher = nonExplicitRef.deref() + for (const [keyMatcher, nonExplicitDispatcher] of Array.from(this[kClients])) { if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { const dispatcher = this[kFactory](origin) this[kMockAgentSet](origin, dispatcher) @@ -147,7 +136,7 @@ class MockAgent extends Dispatcher { const mockAgentClients = this[kClients] return Array.from(mockAgentClients.entries()) - .flatMap(([origin, scope]) => scope.deref()[kDispatches].map(dispatch => ({ ...dispatch, origin }))) + .flatMap(([origin, scope]) => scope[kDispatches].map(dispatch => ({ ...dispatch, origin }))) .filter(({ pending }) => pending) } diff --git a/deps/undici/src/lib/websocket/connection.js b/deps/undici/src/lib/websocket/connection.js index e0fa69726b4054..4bc60b3b90be6b 100644 --- a/deps/undici/src/lib/websocket/connection.js +++ b/deps/undici/src/lib/websocket/connection.js @@ -261,6 +261,7 @@ function onSocketClose () { // attribute initialized to the result of applying UTF-8 // decode without BOM to the WebSocket connection close // reason. + // TODO: process.nextTick fireEvent('close', ws, CloseEvent, { wasClean, code, reason }) diff --git a/deps/undici/src/lib/websocket/util.js b/deps/undici/src/lib/websocket/util.js index 6c59b2c238065b..d15a63cde92f8f 100644 --- a/deps/undici/src/lib/websocket/util.js +++ b/deps/undici/src/lib/websocket/util.js @@ -182,6 +182,7 @@ function failWebsocketConnection (ws, reason) { } if (reason) { + // TODO: process.nextTick fireEvent('error', ws, ErrorEvent, { error: new Error(reason) }) diff --git a/deps/undici/src/lib/websocket/websocket.js b/deps/undici/src/lib/websocket/websocket.js index e4aa58f52fc589..1eac67b7828144 100644 --- a/deps/undici/src/lib/websocket/websocket.js +++ b/deps/undici/src/lib/websocket/websocket.js @@ -1,7 +1,6 @@ 'use strict' const { webidl } = require('../fetch/webidl') -const { DOMException } = require('../fetch/constants') const { URLSerializer } = require('../fetch/dataURL') const { getGlobalOrigin } = require('../fetch/global') const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = require('./constants') diff --git a/deps/undici/src/package-lock.json b/deps/undici/src/package-lock.json index a9f655fb0bf7ab..1f94d7f37f4afa 100644 --- a/deps/undici/src/package-lock.json +++ b/deps/undici/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "undici", - "version": "5.28.2", + "version": "6.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "undici", - "version": "5.28.2", + "version": "6.2.1", "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" @@ -33,8 +33,8 @@ "jest": "^29.0.2", "jsdom": "^23.0.0", "jsfuzz": "^1.0.15", + "mitata": "^0.1.6", "mocha": "^10.0.0", - "mockttp": "^3.9.2", "p-timeout": "^3.2.0", "pre-commit": "^1.2.2", "proxy": "^1.0.2", @@ -51,7 +51,7 @@ "ws": "^8.11.0" }, "engines": { - "node": ">=14.0" + "node": ">=18.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -176,21 +176,21 @@ } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -238,12 +238,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -253,14 +253,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -403,14 +403,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz", + "integrity": "sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" @@ -502,9 +502,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -691,9 +691,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", - "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.7.tgz", + "integrity": "sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -717,20 +717,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -761,9 +761,9 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -851,9 +851,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -896,9 +896,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", - "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -911,70 +911,6 @@ "node": ">=14" } }, - "node_modules/@graphql-tools/merge": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.1.tgz", - "integrity": "sha512-BMm99mqdNZbEYeTPK3it9r9S6rsZsQKtlqJsSBknAclXq2pGEfOxjcIZi+kBSkHZKPKCRrYDd5vY0+rUmIHVLg==", - "dev": true, - "dependencies": { - "@graphql-tools/utils": "8.9.0", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", - "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", - "dev": true, - "dependencies": { - "tslib": "^2.4.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/schema": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.1.tgz", - "integrity": "sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==", - "dev": true, - "dependencies": { - "@graphql-tools/merge": "8.3.1", - "@graphql-tools/utils": "8.9.0", - "tslib": "^2.4.0", - "value-or-promise": "1.0.11" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", - "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", - "dev": true, - "dependencies": { - "tslib": "^2.4.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/utils": { - "version": "8.13.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz", - "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==", - "dev": true, - "dependencies": { - "tslib": "^2.4.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -990,56 +926,6 @@ "@hapi/hoek": "^9.0.0" } }, - "node_modules/@httptoolkit/httpolyglot": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@httptoolkit/httpolyglot/-/httpolyglot-2.1.1.tgz", - "integrity": "sha512-TvJOb/9dYmOD1U8sErFKCy5BxQc7kbLuvvRLfsTr+NN9kQGNGRNyenC00mJxUn2ld/WtxPMNup3JICHPUOPXDg==", - "dev": true, - "dependencies": { - "@types/node": "^16.7.10" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@httptoolkit/httpolyglot/node_modules/@types/node": { - "version": "16.18.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.66.tgz", - "integrity": "sha512-sePmD/imfKvC4re/Wwos1NEcXYm6O96CAG5gQVY53nmDb8ePQ4qPku6uruN7n6TJ0t5FhcoUc2+yvE2/UZVDZw==", - "dev": true - }, - "node_modules/@httptoolkit/subscriptions-transport-ws": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@httptoolkit/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.2.tgz", - "integrity": "sha512-YB+gYYVjgYUeJrGkfS91ABeNWCFU7EVcn9Cflf2UXjsIiPJEI6yPxujPcjKv9wIJpM+33KQW/qVEmc+BdIDK2w==", - "dev": true, - "dependencies": { - "backo2": "^1.0.2", - "eventemitter3": "^3.1.0", - "iterall": "^1.2.1", - "symbol-observable": "^1.0.4", - "ws": "^8.8.0" - }, - "peerDependencies": { - "graphql": "^15.7.2 || ^16.0.0" - } - }, - "node_modules/@httptoolkit/websocket-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@httptoolkit/websocket-stream/-/websocket-stream-6.0.1.tgz", - "integrity": "sha512-A0NOZI+Glp3Xgcz6Na7i7o09+/+xm2m0UCU8gdtM2nIv6/cjLmhMZMqehSpTlgbx9omtLmV8LVqOskPEyWnmZQ==", - "dev": true, - "dependencies": { - "@types/ws": "*", - "duplexify": "^3.5.1", - "inherits": "^2.0.1", - "isomorphic-ws": "^4.0.1", - "readable-stream": "^2.3.3", - "safe-buffer": "^5.1.2", - "ws": "*", - "xtend": "^4.0.0" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -1598,12 +1484,6 @@ "node": ">=6" } }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true - }, "node_modules/@tsd/typescript": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.2.2.tgz", @@ -1627,9 +1507,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -1646,23 +1526,14 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" } }, - "node_modules/@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/escodegen": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.6.tgz", @@ -1755,18 +1626,18 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.19.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.1.tgz", - "integrity": "sha512-mZJ9V11gG5Vp0Ox2oERpeFDl+JvCwK24PGy76vVY/UgBtjwJWc5rYBThFxmbnYOm9UPZNm6wEl/sxHt2SU7x9A==", + "version": "18.19.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.4.tgz", + "integrity": "sha512-xNzlUhzoHotIsnFoXmJB+yWmBvFZgKCI9TtPIEdYIMM1KWfwuY8zh7wvc1u1OAXlC7dlf6mZVx/s+Y5KfFz19A==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/node-forge": { - "version": "1.3.10", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", - "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", "dev": true, "dependencies": { "@types/node": "*" @@ -1784,15 +1655,6 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/yargs": { "version": "17.0.32", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", @@ -1826,23 +1688,10 @@ "node": ">=6.5" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1861,12 +1710,12 @@ } }, "node_modules/acquerello": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/acquerello/-/acquerello-1.1.2.tgz", - "integrity": "sha512-V/ynq+ekRAls3iWOQMxA8G9pi40aTL9mheHHxA8x8oowZVjY7bROD99t+TSOKKp3BviACYOsNMlL+b+8jZ7ImQ==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/acquerello/-/acquerello-1.0.12.tgz", + "integrity": "sha512-6yCYGUNctkYqF7DLmm0D/CxlRmM/OrzyuHOU+mbaO6VRxHmRg4EV0phvyBexRt6jTyDtEQIb09YFiwu5LExXsA==", "dev": true, "engines": { - "node": ">= 18.18.0" + "node": ">=14.15.0" } }, "node_modules/agent-base": { @@ -2147,12 +1996,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, "node_modules/array-includes": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", @@ -2288,18 +2131,6 @@ "node": "*" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -2309,15 +2140,6 @@ "node": ">=8" } }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, "node_modules/async-hook-domain": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.4.tgz", @@ -2364,12 +2186,12 @@ } }, "node_modules/axios": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", - "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", + "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -2490,27 +2312,12 @@ "@babel/core": "^7.0.0" } }, - "node_modules/backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", - "dev": true - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha512-437oANT9tP582zZMwSvZGy2nmSeAb8DW2me3y+Uv1Wp2Rulr8Mqlyrv3E7MLxmsiaPSMMDmiDVzgE+e8zlMx9g==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -2537,15 +2344,6 @@ "integrity": "sha512-Y7OBvWn+JnW45JWHLY6ybYub2k9cXCMrtCyO1Hds2s6eqClqWhPnOQpgXUPjAiMHj+A8TEPIQQ1dYENnJoBOHQ==", "dev": true }, - "node_modules/basic-ftp": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", - "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2564,42 +2362,6 @@ "node": ">=10" } }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", @@ -2678,12 +2440,6 @@ "node": ">=8" } }, - "node_modules/brotli-wasm": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/brotli-wasm/-/brotli-wasm-1.3.1.tgz", - "integrity": "sha512-Vp+v3QXddvy39Ycbmvd3/Y1kUvKhwtnprzeABcKWN4jmyg6W3W5MhGPCfXBMHeSQnizgpV59iWmkSRp7ykOnDQ==", - "dev": true - }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -2691,9 +2447,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "funding": [ { @@ -2710,9 +2466,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, "bin": { @@ -2746,24 +2502,6 @@ "semver": "^7.0.0" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, "node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -2849,15 +2587,6 @@ "node": ">=6" } }, - "node_modules/caching-transform/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/caching-transform/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -2927,19 +2656,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/camelcase-keys/node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/caniuse-lite": { - "version": "1.0.30001565", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", - "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", + "version": "1.0.30001574", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz", + "integrity": "sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg==", "dev": true, "funding": [ { @@ -2957,9 +2677,9 @@ ] }, "node_modules/chai": { - "version": "4.3.10", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", - "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.0.tgz", + "integrity": "sha512-x9cHNq1uvkCdU+5xTkNh5WtgD4e4yDFCsp9jVc7N7qVeKeftv3gO/ZrviX5d+3ZfxdYnZXZYujjRInu1RogU6A==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", @@ -3203,15 +2923,6 @@ "node": ">= 0.8" } }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -3239,6 +2950,42 @@ "typedarray": "^0.0.6" } }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/concurrently": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", @@ -3328,73 +3075,18 @@ "node": "*" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cors-gate": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cors-gate/-/cors-gate-1.1.3.tgz", - "integrity": "sha512-RFqvbbpj02lqKDhqasBEkgzmT3RseCH3DKy5sT2W9S1mhctABKQP3ktKcnKN0h8t4pJ2SneI3hPl3TGNi/VmZA==", - "dev": true - }, "node_modules/cp-file": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", @@ -3432,26 +3124,17 @@ } }, "node_modules/cronometro": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cronometro/-/cronometro-1.2.0.tgz", - "integrity": "sha512-QeNGCuvNFimu4IJhZSL4oNopAmxfjRkSqh4rci4PZuNWKLRhqPC0oemw6gdbfgz0evqxOOS3uwtSt2FMR8dDXw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/cronometro/-/cronometro-1.1.5.tgz", + "integrity": "sha512-uotkltVBg4WLAeCgbSsLhqpEyvYTn1J++bYcsq0i/RPNMHkMp4sN/7Hx+0O3UaCqIWJ4AG1dNrzDSkzt69jwQQ==", "dev": true, "dependencies": { - "acquerello": "^1.1.2", + "acquerello": "^1.0.12", "hdr-histogram-js": "^3.0.0", "table": "^6.8.1" }, "engines": { - "node": ">= 18.18.0" - } - }, - "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "dev": true, - "dependencies": { - "node-fetch": "^2.6.12" + "node": ">=14.15.0" } }, "node_modules/cross-spawn": { @@ -3478,24 +3161,15 @@ } }, "node_modules/cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", "dev": true, "dependencies": { "rrweb-cssom": "^0.6.0" }, "engines": { - "node": ">=14" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", - "dev": true, - "engines": { - "node": ">= 14" + "node": ">=18" } }, "node_modules/data-urls": { @@ -3716,54 +3390,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/degenerator/node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/degenerator/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", "dev": true, "engines": { "node": ">=10" @@ -3800,18 +3430,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/destroyable-server": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/destroyable-server/-/destroyable-server-1.0.0.tgz", - "integrity": "sha512-78rUr9j0b4bRWO0eBtqKqmb43htBwNbofRRukpo+R7PZqHD6llb7aQoNVt81U9NQGhINRKBHz7lkrxZJj9vyog==", - "dev": true, - "dependencies": { - "@types/node": "*" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -4146,18 +3764,6 @@ "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", "dev": true }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4165,9 +3771,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.601", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz", - "integrity": "sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==", + "version": "1.4.623", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz", + "integrity": "sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A==", "dev": true }, "node_modules/emittery": { @@ -4420,15 +4026,15 @@ } }, "node_modules/eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", - "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.55.0", + "@eslint/js": "8.56.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4651,9 +4257,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", - "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { "array-includes": "^3.1.7", @@ -4672,7 +4278,7 @@ "object.groupby": "^1.0.1", "object.values": "^1.1.7", "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -4953,9 +4559,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5186,12 +4792,6 @@ "node": ">=6" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true - }, "node_modules/events-to-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", @@ -5246,126 +4846,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5401,9 +4881,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -5573,15 +5053,6 @@ "node": ">=4" } }, - "node_modules/find-cache-dir/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/find-cache-dir/node_modules/pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", @@ -5667,9 +5138,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true, "funding": [ { @@ -5766,15 +5237,6 @@ "node": ">= 18" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -5989,44 +5451,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-uri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", - "dev": true, - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.0", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/get-uri/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/get-uri/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -6176,54 +5600,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", - "dev": true, - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/graphql-http": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/graphql-http/-/graphql-http-1.22.0.tgz", - "integrity": "sha512-9RBUlGJWBFqz9LwfpmAbjJL/8j/HCNkZwPBU5+Bfmwez+1Ay43DocMNQYpIWsWqH0Ftv6PTNAh2aRnnMCBJgLw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "graphql": ">=0.11 <=16" - } - }, - "node_modules/graphql-subscriptions": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.1.tgz", - "integrity": "sha512-95yD/tKi24q8xYa7Q9rhQN16AYj5wPbrb8tmHGM3WRc9EBmWrG/0kkMl+tQG8wcEuE9ibR4zyOM31p5Sdr2v4g==", - "dev": true, - "dependencies": { - "iterall": "^1.3.0" - }, - "peerDependencies": { - "graphql": "^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" - } - }, - "node_modules/graphql-tag": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" - } - }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -6442,17 +5818,6 @@ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, - "node_modules/http-encoding": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/http-encoding/-/http-encoding-1.5.1.tgz", - "integrity": "sha512-2m4JnG1Z5RX5pRMdccyp6rX1jVo4LO+ussQzWdwR4AmrWhtX0KP1NyslVAFAspQwMxt2P00CCWXIBKj7ILZLpQ==", - "dev": true, - "dependencies": { - "brotli-wasm": "^1.1.0", - "pify": "^5.0.0", - "zstd-codec": "^0.1.4" - } - }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -6514,19 +5879,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/https-pem": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/https-pem/-/https-pem-3.0.0.tgz", @@ -6598,12 +5950,12 @@ } }, "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" @@ -6722,21 +6074,6 @@ "integrity": "sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ==", "dev": true }, - "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", - "dev": true - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/irregular-plurals": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", @@ -7243,9 +6580,9 @@ "dev": true }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "node_modules/isexe": { @@ -7254,15 +6591,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "dev": true, - "peerDependencies": { - "ws": "*" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -7332,6 +6660,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/istanbul-lib-processinfo/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", @@ -7423,12 +6760,6 @@ "node": ">=8" } }, - "node_modules/iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", - "dev": true - }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -8027,12 +7358,12 @@ } }, "node_modules/jsdom": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.0.1.tgz", - "integrity": "sha512-2i27vgvlUsGEBO9+/kJQRbtqtm+191b5zAZrU/UezVmnC2dlDAFLgDYJvAEi94T4kjsRKkezEtLQTgsNEsW2lQ==", + "version": "23.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.1.0.tgz", + "integrity": "sha512-wRscu8dBFxi7O65Cvi0jFRDv0Qa7XEHPix8Qg/vlXHLAMQsRWV1EDeQHBermzXf4Dt7JtFgBLbva3iTcBZDXEQ==", "dev": true, "dependencies": { - "cssstyle": "^3.0.0", + "cssstyle": "^4.0.1", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", @@ -8051,7 +7382,7 @@ "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.14.2", + "ws": "^8.16.0", "xml-name-validator": "^5.0.0" }, "engines": { @@ -8549,15 +7880,6 @@ "node": ">=4" } }, - "node_modules/load-json-file/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/load-json-file/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -8730,15 +8052,6 @@ "node": ">= 8.16.2" } }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/medium-zoom": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.1.0.tgz", @@ -8784,10 +8097,13 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-source-map": { "version": "1.1.0", @@ -8813,15 +8129,6 @@ "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -8948,6 +8255,12 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/mitata": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mitata/-/mitata-0.1.6.tgz", + "integrity": "sha512-VKQ0r3jriTOU9E2Z+mwbZrUmbg4Li4QyFfi7kfHKl6reZhGzL0AYlu3wE0VPXzIwA5xnFzmEQoBwCcNT8stUkA==", + "dev": true + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -9173,116 +8486,6 @@ "node": ">=10" } }, - "node_modules/mockttp": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/mockttp/-/mockttp-3.9.4.tgz", - "integrity": "sha512-EagdyT83RqAKWB2c+g3NdL1hEBcXl4Oeg6zIWDk9mq6JCAqsaIHySE78lvgGja2QjWOgosQaS1YtCaWkKaCFkw==", - "dev": true, - "dependencies": { - "@graphql-tools/schema": "^8.5.0", - "@graphql-tools/utils": "^8.8.0", - "@httptoolkit/httpolyglot": "^2.1.1", - "@httptoolkit/subscriptions-transport-ws": "^0.11.2", - "@httptoolkit/websocket-stream": "^6.0.1", - "@types/cors": "^2.8.6", - "@types/node": "*", - "base64-arraybuffer": "^0.1.5", - "body-parser": "^1.15.2", - "cacheable-lookup": "^6.0.0", - "common-tags": "^1.8.0", - "connect": "^3.7.0", - "cors": "^2.8.4", - "cors-gate": "^1.1.3", - "cross-fetch": "^3.1.5", - "destroyable-server": "^1.0.0", - "express": "^4.14.0", - "graphql": "^14.0.2 || ^15.5", - "graphql-http": "^1.22.0", - "graphql-subscriptions": "^1.1.0", - "graphql-tag": "^2.12.6", - "http-encoding": "^1.5.1", - "http2-wrapper": "^2.2.0", - "https-proxy-agent": "^5.0.1", - "isomorphic-ws": "^4.0.1", - "lodash": "^4.16.4", - "lru-cache": "^7.14.0", - "native-duplexpair": "^1.0.0", - "node-forge": "^1.2.1", - "pac-proxy-agent": "^7.0.0", - "parse-multipart-data": "^1.4.0", - "performance-now": "^2.1.0", - "portfinder": "1.0.28", - "read-tls-client-hello": "^1.0.0", - "semver": "^7.5.3", - "socks-proxy-agent": "^7.0.0", - "typed-error": "^3.0.2", - "uuid": "^8.3.2", - "ws": "^8.8.0" - }, - "bin": { - "mockttp": "dist/admin/admin-bin.js" - }, - "engines": { - "node": ">=14.14.0" - } - }, - "node_modules/mockttp/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/mockttp/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mockttp/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/mockttp/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/mockttp/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/module-not-found-error": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", @@ -9316,42 +8519,18 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/native-duplexpair": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/native-duplexpair/-/native-duplexpair-1.0.0.tgz", - "integrity": "sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA==", - "dev": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/nested-error-stacks": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", "dev": true }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/nise": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", @@ -9392,21 +8571,6 @@ "type-detect": "4.0.8" } }, - "node_modules/nise/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "node_modules/nise/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "dependencies": { - "isarray": "0.0.1" - } - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -9925,15 +9089,6 @@ "node": ">=4" } }, - "node_modules/nyc/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/nyc/node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -10032,16 +9187,6 @@ "node": ">=6" } }, - "node_modules/nyc/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/nyc/node_modules/wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", @@ -10454,76 +9599,6 @@ "node": ">=6" } }, - "node_modules/pac-proxy-agent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", - "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", - "dev": true, - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "pac-resolver": "^7.0.0", - "socks-proxy-agent": "^8.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/pac-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/pac-proxy-agent/node_modules/socks-proxy-agent": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", - "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", - "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", - "dev": true, - "dependencies": { - "degenerator": "^5.0.0", - "ip": "^1.1.8", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", @@ -10608,12 +9683,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-multipart-data": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/parse-multipart-data/-/parse-multipart-data-1.5.0.tgz", - "integrity": "sha512-ck5zaMF0ydjGfejNMnlo5YU2oJ+pT+80Jb1y4ybanT27j+zbVP/jkYmCrUGsEln0Ox/hZmuvgy8Ra7AxbXP2Mw==", - "dev": true - }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -10669,10 +9738,13 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } }, "node_modules/path-type": { "version": "4.0.0", @@ -10692,12 +9764,6 @@ "node": "*" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -10729,15 +9795,12 @@ } }, "node_modules/pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, "node_modules/pirates": { @@ -10850,35 +9913,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dev": true, - "dependencies": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "engines": { - "node": ">= 0.12.0" - } - }, - "node_modules/portfinder/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/portfinder/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/pre-commit": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", @@ -11066,19 +10100,6 @@ "proxy": "bin/proxy.js" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -11178,21 +10199,6 @@ } ] }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -11220,15 +10226,12 @@ ] }, "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/randombytes": { @@ -11249,21 +10252,6 @@ "node": ">= 0.6" } }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -11371,39 +10359,20 @@ "node": ">=8" } }, - "node_modules/read-tls-client-hello": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-tls-client-hello/-/read-tls-client-hello-1.0.1.tgz", - "integrity": "sha512-OvSzfVv6Y656ekUxB7aDhWkLW7y1ck16ChfLFNJhKNADFNweH2fvyiEZkGmmdtXbOtlNuH2zVXZoFCW349M+GA==", - "dev": true, - "dependencies": { - "@types/node": "*" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -11430,9 +10399,9 @@ } }, "node_modules/reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", + "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", "dev": true }, "node_modules/reflect.getprototypeof": { @@ -11456,9 +10425,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true }, "node_modules/regexp.prototype.flags": { @@ -11573,12 +10542,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -12073,16 +11036,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, "node_modules/snazzy": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/snazzy/-/snazzy-9.0.0.tgz", @@ -12115,89 +11068,6 @@ "snazzy": "bin/cmd.js" } }, - "node_modules/snazzy/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "dev": true, - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dev": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/socks-proxy-agent/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/socks-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socks-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/socks/node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -12412,20 +11282,6 @@ "typedarray": "^0.0.6" } }, - "node_modules/standard-json/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -12435,27 +11291,15 @@ "node": ">= 0.6" } }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -12654,15 +11498,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -12708,9 +11543,9 @@ "dev": true }, "node_modules/tap": { - "version": "16.3.9", - "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.9.tgz", - "integrity": "sha512-KKmu12hRJhb/kGvVV/UKBOJ90sNoGbcXF0E+VmNqej1DqaCmZHyOXR8R7E66qg2Wor33XhSHGrku5MPYWSRNWw==", + "version": "16.3.10", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.10.tgz", + "integrity": "sha512-q5Am+PpGHS6JSjk/Zn4bCRBihmZVM15v/MYXUy60wenw5HDe7pVrevLCEoMEz7tuw6jaPOJJqni1y8apN23IGw==", "bundleDependencies": [ "ink", "treport", @@ -12880,19 +11715,20 @@ } }, "node_modules/tap/node_modules/@babel/code-frame": { - "version": "7.22.5", + "version": "7.23.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/compat-data": { - "version": "7.22.9", + "version": "7.23.5", "dev": true, "inBundle": true, "license": "MIT", @@ -12901,25 +11737,25 @@ } }, "node_modules/tap/node_modules/@babel/core": { - "version": "7.22.9", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { @@ -12931,12 +11767,12 @@ } }, "node_modules/tap/node_modules/@babel/generator": { - "version": "7.22.9", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -12958,26 +11794,23 @@ } }, "node_modules/tap/node_modules/@babel/helper-compilation-targets": { - "version": "7.22.9", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/tap/node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", + "version": "7.22.20", "dev": true, "inBundle": true, "license": "MIT", @@ -12986,13 +11819,13 @@ } }, "node_modules/tap/node_modules/@babel/helper-function-name": { - "version": "7.22.5", + "version": "7.23.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -13011,28 +11844,28 @@ } }, "node_modules/tap/node_modules/@babel/helper-module-imports": { - "version": "7.22.5", + "version": "7.22.15", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", + "version": "7.23.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -13075,7 +11908,7 @@ } }, "node_modules/tap/node_modules/@babel/helper-string-parser": { - "version": "7.22.5", + "version": "7.23.4", "dev": true, "inBundle": true, "license": "MIT", @@ -13084,7 +11917,7 @@ } }, "node_modules/tap/node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", + "version": "7.22.20", "dev": true, "inBundle": true, "license": "MIT", @@ -13093,7 +11926,7 @@ } }, "node_modules/tap/node_modules/@babel/helper-validator-option": { - "version": "7.22.5", + "version": "7.23.5", "dev": true, "inBundle": true, "license": "MIT", @@ -13102,27 +11935,27 @@ } }, "node_modules/tap/node_modules/@babel/helpers": { - "version": "7.22.6", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/highlight": { - "version": "7.22.5", + "version": "7.23.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -13130,7 +11963,7 @@ } }, "node_modules/tap/node_modules/@babel/parser": { - "version": "7.22.7", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", @@ -13161,7 +11994,7 @@ } }, "node_modules/tap/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.22.5", + "version": "7.23.3", "dev": true, "inBundle": true, "license": "MIT", @@ -13188,7 +12021,7 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.5", + "version": "7.23.3", "dev": true, "inBundle": true, "license": "MIT", @@ -13203,7 +12036,7 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.5", + "version": "7.23.3", "dev": true, "inBundle": true, "license": "MIT", @@ -13218,16 +12051,16 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.22.5", + "version": "7.23.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" }, "engines": { "node": ">=6.9.0" @@ -13237,34 +12070,34 @@ } }, "node_modules/tap/node_modules/@babel/template": { - "version": "7.22.5", + "version": "7.22.15", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/traverse": { - "version": "7.22.8", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.7", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -13272,13 +12105,13 @@ } }, "node_modules/tap/node_modules/@babel/types": { - "version": "7.22.5", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -13320,7 +12153,7 @@ } }, "node_modules/tap/node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", + "version": "3.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -13344,29 +12177,23 @@ "license": "MIT" }, "node_modules/tap/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", + "version": "0.3.20", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/tap/node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/tap/node_modules/@types/prop-types": { - "version": "15.7.5", + "version": "15.7.11", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/tap/node_modules/@types/react": { - "version": "17.0.62", + "version": "17.0.73", "dev": true, "inBundle": true, "license": "MIT", @@ -13377,7 +12204,7 @@ } }, "node_modules/tap/node_modules/@types/scheduler": { - "version": "0.16.3", + "version": "0.16.8", "dev": true, "inBundle": true, "license": "MIT" @@ -13492,7 +12319,7 @@ } }, "node_modules/tap/node_modules/browserslist": { - "version": "4.21.9", + "version": "4.22.2", "dev": true, "funding": [ { @@ -13511,10 +12338,10 @@ "inBundle": true, "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -13572,7 +12399,7 @@ } }, "node_modules/tap/node_modules/caniuse-lite": { - "version": "1.0.30001517", + "version": "1.0.30001570", "dev": true, "funding": [ { @@ -13715,7 +12542,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/convert-source-map": { - "version": "1.9.0", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "MIT" @@ -13730,7 +12557,7 @@ } }, "node_modules/tap/node_modules/csstype": { - "version": "3.1.2", + "version": "3.1.3", "dev": true, "inBundle": true, "license": "MIT" @@ -13768,7 +12595,7 @@ } }, "node_modules/tap/node_modules/electron-to-chromium": { - "version": "1.4.477", + "version": "1.4.614", "dev": true, "inBundle": true, "license": "ISC" @@ -14265,7 +13092,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/node-releases": { - "version": "2.0.13", + "version": "2.0.14", "dev": true, "inBundle": true, "license": "MIT" @@ -14311,6 +13138,12 @@ "node": ">=8.9" } }, + "node_modules/tap/node_modules/nyc/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/tap/node_modules/nyc/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -14450,7 +13283,7 @@ } }, "node_modules/tap/node_modules/punycode": { - "version": "2.3.0", + "version": "2.3.1", "dev": true, "inBundle": true, "license": "MIT", @@ -14472,7 +13305,7 @@ } }, "node_modules/tap/node_modules/react-devtools-core": { - "version": "4.28.0", + "version": "4.28.5", "dev": true, "inBundle": true, "license": "MIT", @@ -14854,7 +13687,7 @@ } }, "node_modules/tap/node_modules/update-browserslist-db": { - "version": "1.0.11", + "version": "1.0.13", "dev": true, "funding": [ { @@ -15220,9 +14053,9 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", @@ -15318,19 +14151,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", @@ -15396,16 +14216,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typed-error": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/typed-error/-/typed-error-3.2.2.tgz", - "integrity": "sha512-Z48LU67/qJ+vyA7lh3ozELqpTp3pvQoY5RtLi5wQ/UGSrEidBhlVSqhjr8B3iqbGpjqAoJYrtSYXWMDtidWGkA==", - "dev": true, - "engines": { - "node": ">=6.0.0", - "npm": ">=3.0.0" - } - }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -15422,9 +14232,9 @@ } }, "node_modules/typescript": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", - "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -15623,12 +14433,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { - "uuid": "dist/bin/uuid" + "uuid": "bin/uuid" } }, "node_modules/v8-to-istanbul": { @@ -15655,24 +14466,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "node_modules/value-or-promise": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", - "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/version-guard": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/version-guard/-/version-guard-1.1.1.tgz", @@ -15743,18 +14536,6 @@ "node": ">=18" } }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/whatwg-mimetype": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", @@ -15944,9 +14725,9 @@ } }, "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -15988,15 +14769,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -16205,12 +14977,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zstd-codec": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/zstd-codec/-/zstd-codec-0.1.4.tgz", - "integrity": "sha512-KYnWoFWgGtWyQEKNnUcb3u8ZtKO8dn5d8u+oGpxPlopqsPyv60U8suDyfk7Z7UtAO6Sk5i1aVcAs9RbaB1n36A==", - "dev": true } } } diff --git a/deps/undici/src/package.json b/deps/undici/src/package.json index 2b64daf41e2822..197a968b392f15 100644 --- a/deps/undici/src/package.json +++ b/deps/undici/src/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "5.28.2", + "version": "6.2.1", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { @@ -117,8 +117,8 @@ "jest": "^29.0.2", "jsdom": "^23.0.0", "jsfuzz": "^1.0.15", + "mitata": "^0.1.6", "mocha": "^10.0.0", - "mockttp": "^3.9.2", "p-timeout": "^3.2.0", "pre-commit": "^1.2.2", "proxy": "^1.0.2", @@ -135,7 +135,7 @@ "ws": "^8.11.0" }, "engines": { - "node": ">=14.0" + "node": ">=18.0" }, "standard": { "env": [ diff --git a/deps/undici/src/types/dispatcher.d.ts b/deps/undici/src/types/dispatcher.d.ts index efc53eea79114e..24bf1519a257b8 100644 --- a/deps/undici/src/types/dispatcher.d.ts +++ b/deps/undici/src/types/dispatcher.d.ts @@ -210,6 +210,8 @@ declare namespace Dispatcher { onError?(err: Error): void; /** Invoked when request is upgraded either due to a `Upgrade` header or `CONNECT` method. */ onUpgrade?(statusCode: number, headers: Buffer[] | string[] | null, socket: Duplex): void; + /** Invoked when response is received, before headers have been read. **/ + onResponseStarted?(): void; /** Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. */ onHeaders?(statusCode: number, headers: Buffer[] | string[] | null, resume: () => void, statusText: string): boolean; /** Invoked when response payload data is received. */ diff --git a/deps/undici/src/types/index.d.ts b/deps/undici/src/types/index.d.ts index 0ea8bdc217dbc5..8b35475219b22c 100644 --- a/deps/undici/src/types/index.d.ts +++ b/deps/undici/src/types/index.d.ts @@ -17,6 +17,7 @@ import ProxyAgent from'./proxy-agent' import RetryHandler from'./retry-handler' import { request, pipeline, stream, connect, upgrade } from './api' +export * from './util' export * from './cookies' export * from './fetch' export * from './file' diff --git a/deps/undici/src/types/util.d.ts b/deps/undici/src/types/util.d.ts new file mode 100644 index 00000000000000..2a604148fd813f --- /dev/null +++ b/deps/undici/src/types/util.d.ts @@ -0,0 +1,31 @@ +export namespace util { + /** + * Retrieves a header name and returns its lowercase value. + * @param value Header name + */ + export function headerNameToString(value: string | Buffer): string; + + /** + * Receives a header object and returns the parsed value. + * @param headers Header object + */ + export function parseHeaders( + headers: + | Record + | (Buffer | string | (Buffer | string)[])[] + ): Record; + /** + * Receives a header object and returns the parsed value. + * @param headers Header object + * @param obj Object to specify a proxy object. Used to assign parsed values. But, if `headers` is an object, it is not used. + * @returns If `headers` is an object, it is `headers`. Otherwise, if `obj` is specified, it is equivalent to `obj`. + */ + export function parseHeaders< + H extends + | Record + | (Buffer | string | (Buffer | string)[])[] + >( + headers: H, + obj?: H extends any[] ? Record : never + ): Record; +} diff --git a/deps/undici/undici.js b/deps/undici/undici.js index 847a8814336f5a..5508ae0fed78c9 100644 --- a/deps/undici/undici.js +++ b/deps/undici/undici.js @@ -104,61 +104,56 @@ var require_errors = __commonJS({ this.code = "UND_ERR"; } }; - var ConnectTimeoutError = class _ConnectTimeoutError extends UndiciError { + var ConnectTimeoutError = class extends UndiciError { static { __name(this, "ConnectTimeoutError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _ConnectTimeoutError); this.name = "ConnectTimeoutError"; this.message = message || "Connect Timeout Error"; this.code = "UND_ERR_CONNECT_TIMEOUT"; } }; - var HeadersTimeoutError = class _HeadersTimeoutError extends UndiciError { + var HeadersTimeoutError = class extends UndiciError { static { __name(this, "HeadersTimeoutError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _HeadersTimeoutError); this.name = "HeadersTimeoutError"; this.message = message || "Headers Timeout Error"; this.code = "UND_ERR_HEADERS_TIMEOUT"; } }; - var HeadersOverflowError = class _HeadersOverflowError extends UndiciError { + var HeadersOverflowError = class extends UndiciError { static { __name(this, "HeadersOverflowError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _HeadersOverflowError); this.name = "HeadersOverflowError"; this.message = message || "Headers Overflow Error"; this.code = "UND_ERR_HEADERS_OVERFLOW"; } }; - var BodyTimeoutError = class _BodyTimeoutError extends UndiciError { + var BodyTimeoutError = class extends UndiciError { static { __name(this, "BodyTimeoutError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _BodyTimeoutError); this.name = "BodyTimeoutError"; this.message = message || "Body Timeout Error"; this.code = "UND_ERR_BODY_TIMEOUT"; } }; - var ResponseStatusCodeError = class _ResponseStatusCodeError extends UndiciError { + var ResponseStatusCodeError = class extends UndiciError { static { __name(this, "ResponseStatusCodeError"); } constructor(message, statusCode, headers, body) { super(message); - Error.captureStackTrace(this, _ResponseStatusCodeError); this.name = "ResponseStatusCodeError"; this.message = message || "Response Status Code Error"; this.code = "UND_ERR_RESPONSE_STATUS_CODE"; @@ -168,122 +163,122 @@ var require_errors = __commonJS({ this.headers = headers; } }; - var InvalidArgumentError = class _InvalidArgumentError extends UndiciError { + var InvalidArgumentError = class extends UndiciError { static { __name(this, "InvalidArgumentError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _InvalidArgumentError); this.name = "InvalidArgumentError"; this.message = message || "Invalid Argument Error"; this.code = "UND_ERR_INVALID_ARG"; } }; - var InvalidReturnValueError = class _InvalidReturnValueError extends UndiciError { + var InvalidReturnValueError = class extends UndiciError { static { __name(this, "InvalidReturnValueError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _InvalidReturnValueError); this.name = "InvalidReturnValueError"; this.message = message || "Invalid Return Value Error"; this.code = "UND_ERR_INVALID_RETURN_VALUE"; } }; - var RequestAbortedError = class _RequestAbortedError extends UndiciError { + var AbortError = class extends UndiciError { + static { + __name(this, "AbortError"); + } + constructor(message) { + super(message); + this.name = "AbortError"; + this.message = message || "The operation was aborted"; + } + }; + var RequestAbortedError = class extends AbortError { static { __name(this, "RequestAbortedError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _RequestAbortedError); this.name = "AbortError"; this.message = message || "Request aborted"; this.code = "UND_ERR_ABORTED"; } }; - var InformationalError = class _InformationalError extends UndiciError { + var InformationalError = class extends UndiciError { static { __name(this, "InformationalError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _InformationalError); this.name = "InformationalError"; this.message = message || "Request information"; this.code = "UND_ERR_INFO"; } }; - var RequestContentLengthMismatchError = class _RequestContentLengthMismatchError extends UndiciError { + var RequestContentLengthMismatchError = class extends UndiciError { static { __name(this, "RequestContentLengthMismatchError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _RequestContentLengthMismatchError); this.name = "RequestContentLengthMismatchError"; this.message = message || "Request body length does not match content-length header"; this.code = "UND_ERR_REQ_CONTENT_LENGTH_MISMATCH"; } }; - var ResponseContentLengthMismatchError = class _ResponseContentLengthMismatchError extends UndiciError { + var ResponseContentLengthMismatchError = class extends UndiciError { static { __name(this, "ResponseContentLengthMismatchError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _ResponseContentLengthMismatchError); this.name = "ResponseContentLengthMismatchError"; this.message = message || "Response body length does not match content-length header"; this.code = "UND_ERR_RES_CONTENT_LENGTH_MISMATCH"; } }; - var ClientDestroyedError = class _ClientDestroyedError extends UndiciError { + var ClientDestroyedError = class extends UndiciError { static { __name(this, "ClientDestroyedError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _ClientDestroyedError); this.name = "ClientDestroyedError"; this.message = message || "The client is destroyed"; this.code = "UND_ERR_DESTROYED"; } }; - var ClientClosedError = class _ClientClosedError extends UndiciError { + var ClientClosedError = class extends UndiciError { static { __name(this, "ClientClosedError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _ClientClosedError); this.name = "ClientClosedError"; this.message = message || "The client is closed"; this.code = "UND_ERR_CLOSED"; } }; - var SocketError = class _SocketError extends UndiciError { + var SocketError = class extends UndiciError { static { __name(this, "SocketError"); } constructor(message, socket) { super(message); - Error.captureStackTrace(this, _SocketError); this.name = "SocketError"; this.message = message || "Socket error"; this.code = "UND_ERR_SOCKET"; this.socket = socket; } }; - var NotSupportedError = class _NotSupportedError extends UndiciError { + var NotSupportedError = class extends UndiciError { static { __name(this, "NotSupportedError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _NotSupportedError); this.name = "NotSupportedError"; this.message = message || "Not supported error"; this.code = "UND_ERR_NOT_SUPPORTED"; @@ -295,43 +290,39 @@ var require_errors = __commonJS({ } constructor(message) { super(message); - Error.captureStackTrace(this, NotSupportedError); this.name = "MissingUpstreamError"; this.message = message || "No upstream has been added to the BalancedPool"; this.code = "UND_ERR_BPL_MISSING_UPSTREAM"; } }; - var HTTPParserError = class _HTTPParserError extends Error { + var HTTPParserError = class extends Error { static { __name(this, "HTTPParserError"); } constructor(message, code, data) { super(message); - Error.captureStackTrace(this, _HTTPParserError); this.name = "HTTPParserError"; this.code = code ? `HPE_${code}` : void 0; this.data = data ? data.toString() : void 0; } }; - var ResponseExceededMaxSizeError = class _ResponseExceededMaxSizeError extends UndiciError { + var ResponseExceededMaxSizeError = class extends UndiciError { static { __name(this, "ResponseExceededMaxSizeError"); } constructor(message) { super(message); - Error.captureStackTrace(this, _ResponseExceededMaxSizeError); this.name = "ResponseExceededMaxSizeError"; this.message = message || "Response content exceeded max size"; this.code = "UND_ERR_RES_EXCEEDED_MAX_SIZE"; } }; - var RequestRetryError = class _RequestRetryError extends UndiciError { + var RequestRetryError = class extends UndiciError { static { __name(this, "RequestRetryError"); } constructor(message, code, { headers, data }) { super(message); - Error.captureStackTrace(this, _RequestRetryError); this.name = "RequestRetryError"; this.message = message || "Request retry error"; this.code = "UND_ERR_REQ_RETRY"; @@ -341,6 +332,7 @@ var require_errors = __commonJS({ } }; module2.exports = { + AbortError, HTTPParserError, UndiciError, HeadersTimeoutError, @@ -365,6 +357,254 @@ var require_errors = __commonJS({ } }); +// lib/core/constants.js +var require_constants = __commonJS({ + "lib/core/constants.js"(exports2, module2) { + "use strict"; + var headerNameLowerCasedRecord = {}; + var wellknownHeaderNames = [ + "Accept", + "Accept-Encoding", + "Accept-Language", + "Accept-Ranges", + "Access-Control-Allow-Credentials", + "Access-Control-Allow-Headers", + "Access-Control-Allow-Methods", + "Access-Control-Allow-Origin", + "Access-Control-Expose-Headers", + "Access-Control-Max-Age", + "Access-Control-Request-Headers", + "Access-Control-Request-Method", + "Age", + "Allow", + "Alt-Svc", + "Alt-Used", + "Authorization", + "Cache-Control", + "Clear-Site-Data", + "Connection", + "Content-Disposition", + "Content-Encoding", + "Content-Language", + "Content-Length", + "Content-Location", + "Content-Range", + "Content-Security-Policy", + "Content-Security-Policy-Report-Only", + "Content-Type", + "Cookie", + "Cross-Origin-Embedder-Policy", + "Cross-Origin-Opener-Policy", + "Cross-Origin-Resource-Policy", + "Date", + "Device-Memory", + "Downlink", + "ECT", + "ETag", + "Expect", + "Expect-CT", + "Expires", + "Forwarded", + "From", + "Host", + "If-Match", + "If-Modified-Since", + "If-None-Match", + "If-Range", + "If-Unmodified-Since", + "Keep-Alive", + "Last-Modified", + "Link", + "Location", + "Max-Forwards", + "Origin", + "Permissions-Policy", + "Pragma", + "Proxy-Authenticate", + "Proxy-Authorization", + "RTT", + "Range", + "Referer", + "Referrer-Policy", + "Refresh", + "Retry-After", + "Sec-WebSocket-Accept", + "Sec-WebSocket-Extensions", + "Sec-WebSocket-Key", + "Sec-WebSocket-Protocol", + "Sec-WebSocket-Version", + "Server", + "Server-Timing", + "Service-Worker-Allowed", + "Service-Worker-Navigation-Preload", + "Set-Cookie", + "SourceMap", + "Strict-Transport-Security", + "Supports-Loading-Mode", + "TE", + "Timing-Allow-Origin", + "Trailer", + "Transfer-Encoding", + "Upgrade", + "Upgrade-Insecure-Requests", + "User-Agent", + "Vary", + "Via", + "WWW-Authenticate", + "X-Content-Type-Options", + "X-DNS-Prefetch-Control", + "X-Frame-Options", + "X-Permitted-Cross-Domain-Policies", + "X-Powered-By", + "X-Requested-With", + "X-XSS-Protection" + ]; + for (let i = 0; i < wellknownHeaderNames.length; ++i) { + const key = wellknownHeaderNames[i]; + const lowerCasedKey = key.toLowerCase(); + headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] = lowerCasedKey; + } + Object.setPrototypeOf(headerNameLowerCasedRecord, null); + module2.exports = { + wellknownHeaderNames, + headerNameLowerCasedRecord + }; + } +}); + +// lib/core/tree.js +var require_tree = __commonJS({ + "lib/core/tree.js"(exports2, module2) { + "use strict"; + var { + wellknownHeaderNames, + headerNameLowerCasedRecord + } = require_constants(); + var TstNode = class _TstNode { + static { + __name(this, "TstNode"); + } + /** @type {any} */ + value = null; + /** @type {null | TstNode} */ + left = null; + /** @type {null | TstNode} */ + middle = null; + /** @type {null | TstNode} */ + right = null; + /** @type {number} */ + code; + /** + * @param {Uint8Array} key + * @param {any} value + * @param {number} index + */ + constructor(key, value, index) { + if (index === void 0 || index >= key.length) { + throw new TypeError("Unreachable"); + } + this.code = key[index]; + if (key.length !== ++index) { + this.middle = new _TstNode(key, value, index); + } else { + this.value = value; + } + } + /** + * @param {Uint8Array} key + * @param {any} value + * @param {number} index + */ + add(key, value, index) { + if (index === void 0 || index >= key.length) { + throw new TypeError("Unreachable"); + } + const code = key[index]; + if (this.code === code) { + if (key.length === ++index) { + this.value = value; + } else if (this.middle !== null) { + this.middle.add(key, value, index); + } else { + this.middle = new _TstNode(key, value, index); + } + } else if (this.code < code) { + if (this.left !== null) { + this.left.add(key, value, index); + } else { + this.left = new _TstNode(key, value, index); + } + } else { + if (this.right !== null) { + this.right.add(key, value, index); + } else { + this.right = new _TstNode(key, value, index); + } + } + } + /** + * @param {Uint8Array} key + * @return {TstNode | null} + */ + search(key) { + const keylength = key.length; + let index = 0; + let node = this; + while (node !== null && index < keylength) { + let code = key[index]; + if (code >= 65 && code <= 90) { + code |= 32; + } + while (node !== null) { + if (code === node.code) { + if (keylength === ++index) { + return node; + } + node = node.middle; + break; + } + node = node.code < code ? node.left : node.right; + } + } + return null; + } + }; + var TernarySearchTree = class { + static { + __name(this, "TernarySearchTree"); + } + /** @type {TstNode | null} */ + node = null; + /** + * @param {Uint8Array} key + * @param {any} value + * */ + insert(key, value) { + if (this.node === null) { + this.node = new TstNode(key, value, 0); + } else { + this.node.add(key, value, 0); + } + } + /** + * @param {Uint8Array} key + */ + lookup(key) { + return this.node?.search(key)?.value ?? null; + } + }; + var tree = new TernarySearchTree(); + for (let i = 0; i < wellknownHeaderNames.length; ++i) { + const key = headerNameLowerCasedRecord[wellknownHeaderNames[i]]; + tree.insert(Buffer.from(key), key); + } + module2.exports = { + TernarySearchTree, + tree + }; + } +}); + // lib/core/util.js var require_util = __commonJS({ "lib/core/util.js"(exports2, module2) { @@ -378,6 +618,8 @@ var require_util = __commonJS({ var { Blob: Blob2 } = require("buffer"); var nodeUtil = require("util"); var { stringify } = require("querystring"); + var { headerNameLowerCasedRecord } = require_constants(); + var { tree } = require_tree(); var [nodeMajor, nodeMinor] = process.versions.node.split(".").map((v) => Number(v)); function nop() { } @@ -537,20 +779,31 @@ var require_util = __commonJS({ return m ? parseInt(m[1], 10) * 1e3 : null; } __name(parseKeepAliveTimeout, "parseKeepAliveTimeout"); - function parseHeaders(headers, obj = {}) { + function headerNameToString(value) { + return typeof value === "string" ? headerNameLowerCasedRecord[value] ?? value.toLowerCase() : tree.lookup(value) ?? value.toString("latin1").toLowerCase(); + } + __name(headerNameToString, "headerNameToString"); + function bufferToLowerCasedHeaderName(value) { + return tree.lookup(value) ?? value.toString("latin1").toLowerCase(); + } + __name(bufferToLowerCasedHeaderName, "bufferToLowerCasedHeaderName"); + function parseHeaders(headers, obj) { if (!Array.isArray(headers)) return headers; + if (obj === void 0) + obj = {}; for (let i = 0; i < headers.length; i += 2) { - const key = headers[i].toString().toLowerCase(); + const key = headerNameToString(headers[i]); let val = obj[key]; if (!val) { - if (Array.isArray(headers[i + 1])) { - obj[key] = headers[i + 1].map((x) => x.toString("utf8")); + const headersValue = headers[i + 1]; + if (typeof headersValue === "string") { + obj[key] = headersValue; } else { - obj[key] = headers[i + 1].toString("utf8"); + obj[key] = Array.isArray(headersValue) ? headersValue.map((x) => x.toString("utf8")) : headersValue.toString("utf8"); } } else { - if (!Array.isArray(val)) { + if (typeof val === "string") { val = [val]; obj[key] = val; } @@ -624,15 +877,11 @@ var require_util = __commonJS({ } __name(isDisturbed, "isDisturbed"); function isErrored(body) { - return !!(body && (stream.isErrored ? stream.isErrored(body) : /state: 'errored'/.test( - nodeUtil.inspect(body) - ))); + return !!(body && stream.isErrored(body)); } __name(isErrored, "isErrored"); function isReadable(body) { - return !!(body && (stream.isReadable ? stream.isReadable(body) : /state: 'readable'/.test( - nodeUtil.inspect(body) - ))); + return !!(body && stream.isReadable(body)); } __name(isReadable, "isReadable"); function getSocketInfo(socket) { @@ -648,20 +897,7 @@ var require_util = __commonJS({ }; } __name(getSocketInfo, "getSocketInfo"); - async function* convertIterableToBuffer(iterable) { - for await (const chunk of iterable) { - yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); - } - } - __name(convertIterableToBuffer, "convertIterableToBuffer"); - var ReadableStream; function ReadableStreamFrom(iterable) { - if (!ReadableStream) { - ReadableStream = require("stream/web").ReadableStream; - } - if (ReadableStream.from) { - return ReadableStream.from(convertIterableToBuffer(iterable)); - } let iterator; return new ReadableStream( { @@ -673,18 +909,21 @@ var require_util = __commonJS({ if (done) { queueMicrotask(() => { controller.close(); + controller.byobRequest?.respond(0); }); } else { const buf = Buffer.isBuffer(value) ? value : Buffer.from(value); - controller.enqueue(new Uint8Array(buf)); + if (buf.byteLength) { + controller.enqueue(new Uint8Array(buf)); + } } return controller.desiredSize > 0; }, async cancel(reason) { await iterator.return(); - } - }, - 0 + }, + type: "bytes" + } ); } __name(ReadableStreamFrom, "ReadableStreamFrom"); @@ -692,21 +931,6 @@ var require_util = __commonJS({ return object && typeof object === "object" && typeof object.append === "function" && typeof object.delete === "function" && typeof object.get === "function" && typeof object.getAll === "function" && typeof object.has === "function" && typeof object.set === "function" && object[Symbol.toStringTag] === "FormData"; } __name(isFormDataLike, "isFormDataLike"); - function throwIfAborted(signal) { - if (!signal) { - return; - } - if (typeof signal.throwIfAborted === "function") { - signal.throwIfAborted(); - } else { - if (signal.aborted) { - const err = new Error("The operation was aborted"); - err.name = "AbortError"; - throw err; - } - } - } - __name(throwIfAborted, "throwIfAborted"); function addAbortListener(signal, listener) { if ("addEventListener" in signal) { signal.addEventListener("abort", listener, { once: true }); @@ -726,6 +950,43 @@ var require_util = __commonJS({ return `${val}`; } __name(toUSVString, "toUSVString"); + function isTokenCharCode(c) { + switch (c) { + case 34: + case 40: + case 41: + case 44: + case 47: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 91: + case 92: + case 93: + case 123: + case 125: + return false; + default: + return c >= 33 && c <= 126; + } + } + __name(isTokenCharCode, "isTokenCharCode"); + function isValidHTTPToken(characters) { + if (characters.length === 0) { + return false; + } + for (let i = 0; i < characters.length; ++i) { + if (!isTokenCharCode(characters.charCodeAt(i))) { + return false; + } + } + return true; + } + __name(isValidHTTPToken, "isValidHTTPToken"); function parseRangeHeader(range) { if (range == null || range === "") return { start: 0, end: null, size: null }; @@ -755,6 +1016,8 @@ var require_util = __commonJS({ isIterable, isAsyncIterable, isDestroyed, + headerNameToString, + bufferToLowerCasedHeaderName, parseRawHeaders, parseHeaders, parseKeepAliveTimeout, @@ -767,8 +1030,9 @@ var require_util = __commonJS({ getSocketInfo, isFormDataLike, buildURL, - throwIfAborted, addAbortListener, + isValidHTTPToken, + isTokenCharCode, parseRangeHeader, nodeMajor, nodeMinor, @@ -779,10 +1043,9 @@ var require_util = __commonJS({ }); // lib/fetch/constants.js -var require_constants = __commonJS({ +var require_constants2 = __commonJS({ "lib/fetch/constants.js"(exports2, module2) { "use strict"; - var { MessageChannel, receiveMessageOnPort } = require("worker_threads"); var corsSafeListedMethods = ["GET", "HEAD", "POST"]; var corsSafeListedMethodsSet = new Set(corsSafeListedMethods); var nullBodyStatus = [101, 204, 205, 304]; @@ -927,31 +1190,7 @@ var require_constants = __commonJS({ "" ]; var subresourceSet = new Set(subresource); - var DOMException = globalThis.DOMException ?? (() => { - try { - atob("~"); - } catch (err) { - return Object.getPrototypeOf(err).constructor; - } - })(); - var channel; - var structuredClone = globalThis.structuredClone ?? // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js - // structuredClone was added in v17.0.0, but fetch supports v16.8 - /* @__PURE__ */ __name(function structuredClone2(value, options = void 0) { - if (arguments.length === 0) { - throw new TypeError("missing argument"); - } - if (!channel) { - channel = new MessageChannel(); - } - channel.port1.unref(); - channel.port2.unref(); - channel.port1.postMessage(value, options?.transfer); - return receiveMessageOnPort(channel.port2).message; - }, "structuredClone"); module2.exports = { - DOMException, - structuredClone, subresource, forbiddenMethods, requestBodyHeader, @@ -1015,216 +1254,519 @@ var require_global = __commonJS({ } }); -// lib/fetch/util.js -var require_util2 = __commonJS({ - "lib/fetch/util.js"(exports2, module2) { - "use strict"; - var { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require_constants(); - var { getGlobalOrigin } = require_global(); - var { performance: performance2 } = require("perf_hooks"); - var { isBlobLike, toUSVString, ReadableStreamFrom } = require_util(); +// lib/fetch/dataURL.js +var require_dataURL = __commonJS({ + "lib/fetch/dataURL.js"(exports2, module2) { var assert = require("assert"); - var { isUint8Array } = require("util/types"); - var crypto; - try { - crypto = require("crypto"); - } catch { - } - function responseURL(response) { - const urlList = response.urlList; - const length = urlList.length; - return length === 0 ? null : urlList[length - 1].toString(); - } - __name(responseURL, "responseURL"); - function responseLocationURL(response, requestFragment) { - if (!redirectStatusSet.has(response.status)) { - return null; + var { isomorphicDecode } = require_util2(); + var encoder = new TextEncoder(); + var HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/; + var HTTP_WHITESPACE_REGEX = /[\u000A|\u000D|\u0009|\u0020]/; + var ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g; + var HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/; + function dataURLProcessor(dataURL) { + assert(dataURL.protocol === "data:"); + let input = URLSerializer(dataURL, true); + input = input.slice(5); + const position = { position: 0 }; + let mimeType = collectASequenceOfCodePointsFast( + ",", + input, + position + ); + const mimeTypeLength = mimeType.length; + mimeType = removeASCIIWhitespace(mimeType, true, true); + if (position.position >= input.length) { + return "failure"; } - let location = response.headersList.get("location"); - if (location !== null && isValidHeaderValue(location)) { - location = new URL(location, responseURL(response)); + position.position++; + const encodedBody = input.slice(mimeTypeLength + 1); + let body = stringPercentDecode(encodedBody); + if (/;(\u0020){0,}base64$/i.test(mimeType)) { + const stringBody = isomorphicDecode(body); + body = forgivingBase64(stringBody); + if (body === "failure") { + return "failure"; + } + mimeType = mimeType.slice(0, -6); + mimeType = mimeType.replace(/(\u0020)+$/, ""); + mimeType = mimeType.slice(0, -1); } - if (location && !location.hash) { - location.hash = requestFragment; + if (mimeType.startsWith(";")) { + mimeType = "text/plain" + mimeType; } - return location; + let mimeTypeRecord = parseMIMEType(mimeType); + if (mimeTypeRecord === "failure") { + mimeTypeRecord = parseMIMEType("text/plain;charset=US-ASCII"); + } + return { mimeType: mimeTypeRecord, body }; } - __name(responseLocationURL, "responseLocationURL"); - function requestCurrentURL(request) { - return request.urlList[request.urlList.length - 1]; + __name(dataURLProcessor, "dataURLProcessor"); + function URLSerializer(url, excludeFragment = false) { + if (!excludeFragment) { + return url.href; + } + const href = url.href; + const hashLength = url.hash.length; + const serialized = hashLength === 0 ? href : href.substring(0, href.length - hashLength); + if (!hashLength && href.endsWith("#")) { + return serialized.slice(0, -1); + } + return serialized; } - __name(requestCurrentURL, "requestCurrentURL"); - function requestBadPort(request) { - const url = requestCurrentURL(request); - if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { - return "blocked"; + __name(URLSerializer, "URLSerializer"); + function collectASequenceOfCodePoints(condition, input, position) { + let result = ""; + while (position.position < input.length && condition(input[position.position])) { + result += input[position.position]; + position.position++; } - return "allowed"; + return result; } - __name(requestBadPort, "requestBadPort"); - function isErrorLike(object) { - return object instanceof Error || (object?.constructor?.name === "Error" || object?.constructor?.name === "DOMException"); + __name(collectASequenceOfCodePoints, "collectASequenceOfCodePoints"); + function collectASequenceOfCodePointsFast(char, input, position) { + const idx = input.indexOf(char, position.position); + const start = position.position; + if (idx === -1) { + position.position = input.length; + return input.slice(start); + } + position.position = idx; + return input.slice(start, position.position); } - __name(isErrorLike, "isErrorLike"); - function isValidReasonPhrase(statusText) { - for (let i = 0; i < statusText.length; ++i) { - const c = statusText.charCodeAt(i); - if (!(c === 9 || // HTAB - c >= 32 && c <= 126 || // SP / VCHAR - c >= 128 && c <= 255)) { - return false; + __name(collectASequenceOfCodePointsFast, "collectASequenceOfCodePointsFast"); + function stringPercentDecode(input) { + const bytes = encoder.encode(input); + return percentDecode(bytes); + } + __name(stringPercentDecode, "stringPercentDecode"); + function isHexCharByte(byte) { + return byte >= 48 && byte <= 57 || byte >= 65 && byte <= 70 || byte >= 97 && byte <= 102; + } + __name(isHexCharByte, "isHexCharByte"); + function percentDecode(input) { + const length = input.length; + const output = new Uint8Array(length); + let j = 0; + for (let i = 0; i < length; ++i) { + const byte = input[i]; + if (byte !== 37) { + output[j++] = byte; + } else if (byte === 37 && !(isHexCharByte(input[i + 1]) && isHexCharByte(input[i + 2]))) { + output[j++] = 37; + } else { + const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2]); + const bytePoint = Number.parseInt(nextTwoBytes, 16); + output[j++] = bytePoint; + i += 2; } } - return true; + return length === j ? output : output.subarray(0, j); } - __name(isValidReasonPhrase, "isValidReasonPhrase"); - function isTokenCharCode(c) { - switch (c) { - case 34: - case 40: - case 41: - case 44: - case 47: - case 58: - case 59: - case 60: - case 61: - case 62: - case 63: - case 64: - case 91: - case 92: - case 93: - case 123: - case 125: - return false; - default: - return c >= 33 && c <= 126; + __name(percentDecode, "percentDecode"); + function parseMIMEType(input) { + input = removeHTTPWhitespace(input, true, true); + const position = { position: 0 }; + const type = collectASequenceOfCodePointsFast( + "/", + input, + position + ); + if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { + return "failure"; } - } - __name(isTokenCharCode, "isTokenCharCode"); - function isValidHTTPToken(characters) { - if (characters.length === 0) { - return false; + if (position.position > input.length) { + return "failure"; } - for (let i = 0; i < characters.length; ++i) { - if (!isTokenCharCode(characters.charCodeAt(i))) { - return false; + position.position++; + let subtype = collectASequenceOfCodePointsFast( + ";", + input, + position + ); + subtype = removeHTTPWhitespace(subtype, false, true); + if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { + return "failure"; + } + const typeLowercase = type.toLowerCase(); + const subtypeLowercase = subtype.toLowerCase(); + const mimeType = { + type: typeLowercase, + subtype: subtypeLowercase, + /** @type {Map} */ + parameters: /* @__PURE__ */ new Map(), + // https://mimesniff.spec.whatwg.org/#mime-type-essence + essence: `${typeLowercase}/${subtypeLowercase}` + }; + while (position.position < input.length) { + position.position++; + collectASequenceOfCodePoints( + // https://fetch.spec.whatwg.org/#http-whitespace + (char) => HTTP_WHITESPACE_REGEX.test(char), + input, + position + ); + let parameterName = collectASequenceOfCodePoints( + (char) => char !== ";" && char !== "=", + input, + position + ); + parameterName = parameterName.toLowerCase(); + if (position.position < input.length) { + if (input[position.position] === ";") { + continue; + } + position.position++; + } + if (position.position > input.length) { + break; + } + let parameterValue = null; + if (input[position.position] === '"') { + parameterValue = collectAnHTTPQuotedString(input, position, true); + collectASequenceOfCodePointsFast( + ";", + input, + position + ); + } else { + parameterValue = collectASequenceOfCodePointsFast( + ";", + input, + position + ); + parameterValue = removeHTTPWhitespace(parameterValue, false, true); + if (parameterValue.length === 0) { + continue; + } + } + if (parameterName.length !== 0 && HTTP_TOKEN_CODEPOINTS.test(parameterName) && (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && !mimeType.parameters.has(parameterName)) { + mimeType.parameters.set(parameterName, parameterValue); } } - return true; - } - __name(isValidHTTPToken, "isValidHTTPToken"); - function isValidHeaderName(potentialValue) { - return isValidHTTPToken(potentialValue); + return mimeType; } - __name(isValidHeaderName, "isValidHeaderName"); - function isValidHeaderValue(potentialValue) { - if (potentialValue.startsWith(" ") || potentialValue.startsWith(" ") || potentialValue.endsWith(" ") || potentialValue.endsWith(" ")) { - return false; + __name(parseMIMEType, "parseMIMEType"); + function forgivingBase64(data) { + data = data.replace(ASCII_WHITESPACE_REPLACE_REGEX, ""); + let dataLength = data.length; + if (dataLength % 4 === 0) { + if (data.charCodeAt(dataLength - 1) === 61) { + --dataLength; + if (data.charCodeAt(dataLength - 1) === 61) { + --dataLength; + } + } } - if (potentialValue.includes("\0") || potentialValue.includes("\r") || potentialValue.includes("\n")) { - return false; + if (dataLength % 4 === 1) { + return "failure"; } - return true; + if (/[^+/0-9A-Za-z]/.test(data.length === dataLength ? data : data.substring(0, dataLength))) { + return "failure"; + } + const buffer = Buffer.from(data, "base64"); + return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); } - __name(isValidHeaderValue, "isValidHeaderValue"); - function setRequestReferrerPolicyOnRedirect(request, actualResponse) { - const { headersList } = actualResponse; - const policyHeader = (headersList.get("referrer-policy") ?? "").split(","); - let policy = ""; - if (policyHeader.length > 0) { - for (let i = policyHeader.length; i !== 0; i--) { - const token = policyHeader[i - 1].trim(); - if (referrerPolicyTokens.has(token)) { - policy = token; + __name(forgivingBase64, "forgivingBase64"); + function collectAnHTTPQuotedString(input, position, extractValue) { + const positionStart = position.position; + let value = ""; + assert(input[position.position] === '"'); + position.position++; + while (true) { + value += collectASequenceOfCodePoints( + (char) => char !== '"' && char !== "\\", + input, + position + ); + if (position.position >= input.length) { + break; + } + const quoteOrBackslash = input[position.position]; + position.position++; + if (quoteOrBackslash === "\\") { + if (position.position >= input.length) { + value += "\\"; break; } + value += input[position.position]; + position.position++; + } else { + assert(quoteOrBackslash === '"'); + break; } } - if (policy !== "") { - request.referrerPolicy = policy; + if (extractValue) { + return value; } + return input.slice(positionStart, position.position); } - __name(setRequestReferrerPolicyOnRedirect, "setRequestReferrerPolicyOnRedirect"); - function crossOriginResourcePolicyCheck() { - return "allowed"; - } - __name(crossOriginResourcePolicyCheck, "crossOriginResourcePolicyCheck"); - function corsCheck() { - return "success"; - } - __name(corsCheck, "corsCheck"); - function TAOCheck() { - return "success"; - } - __name(TAOCheck, "TAOCheck"); - function appendFetchMetadata(httpRequest) { - let header = null; - header = httpRequest.mode; - httpRequest.headersList.set("sec-fetch-mode", header); - } - __name(appendFetchMetadata, "appendFetchMetadata"); - function appendRequestOriginHeader(request) { - let serializedOrigin = request.origin; - if (request.responseTainting === "cors" || request.mode === "websocket") { - if (serializedOrigin) { - request.headersList.append("origin", serializedOrigin); - } - } else if (request.method !== "GET" && request.method !== "HEAD") { - switch (request.referrerPolicy) { - case "no-referrer": - serializedOrigin = null; - break; - case "no-referrer-when-downgrade": - case "strict-origin": - case "strict-origin-when-cross-origin": - if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { - serializedOrigin = null; - } - break; - case "same-origin": - if (!sameOrigin(request, requestCurrentURL(request))) { - serializedOrigin = null; - } - break; - default: - } - if (serializedOrigin) { - request.headersList.append("origin", serializedOrigin); + __name(collectAnHTTPQuotedString, "collectAnHTTPQuotedString"); + function serializeAMimeType(mimeType) { + assert(mimeType !== "failure"); + const { parameters, essence } = mimeType; + let serialization = essence; + for (let [name, value] of parameters.entries()) { + serialization += ";"; + serialization += name; + serialization += "="; + if (!HTTP_TOKEN_CODEPOINTS.test(value)) { + value = value.replace(/(\\|")/g, "\\$1"); + value = '"' + value; + value += '"'; } + serialization += value; } + return serialization; } - __name(appendRequestOriginHeader, "appendRequestOriginHeader"); - function coarsenedSharedCurrentTime(crossOriginIsolatedCapability) { - return performance2.now(); + __name(serializeAMimeType, "serializeAMimeType"); + function isHTTPWhiteSpace(char) { + return char === 13 || char === 10 || char === 9 || char === 32; } - __name(coarsenedSharedCurrentTime, "coarsenedSharedCurrentTime"); - function createOpaqueTimingInfo(timingInfo) { - return { - startTime: timingInfo.startTime ?? 0, - redirectStartTime: 0, - redirectEndTime: 0, - postRedirectStartTime: timingInfo.startTime ?? 0, - finalServiceWorkerStartTime: 0, - finalNetworkResponseStartTime: 0, - finalNetworkRequestStartTime: 0, - endTime: 0, - encodedBodySize: 0, - decodedBodySize: 0, - finalConnectionTimingInfo: null - }; + __name(isHTTPWhiteSpace, "isHTTPWhiteSpace"); + function removeHTTPWhitespace(str, leading = true, trailing = true) { + let i = 0; + let j = str.length; + if (leading) { + while (j > i && isHTTPWhiteSpace(str.charCodeAt(i))) + --i; + } + if (trailing) { + while (j > i && isHTTPWhiteSpace(str.charCodeAt(j - 1))) + --j; + } + return i === 0 && j === str.length ? str : str.substring(i, j); } - __name(createOpaqueTimingInfo, "createOpaqueTimingInfo"); - function makePolicyContainer() { - return { - referrerPolicy: "strict-origin-when-cross-origin" - }; + __name(removeHTTPWhitespace, "removeHTTPWhitespace"); + function isASCIIWhitespace(char) { + return char === 13 || char === 10 || char === 9 || char === 12 || char === 32; } - __name(makePolicyContainer, "makePolicyContainer"); - function clonePolicyContainer(policyContainer) { - return { - referrerPolicy: policyContainer.referrerPolicy + __name(isASCIIWhitespace, "isASCIIWhitespace"); + function removeASCIIWhitespace(str, leading = true, trailing = true) { + let i = 0; + let j = str.length; + if (leading) { + while (j > i && isASCIIWhitespace(str.charCodeAt(i))) + --i; + } + if (trailing) { + while (j > i && isASCIIWhitespace(str.charCodeAt(j - 1))) + --j; + } + return i === 0 && j === str.length ? str : str.substring(i, j); + } + __name(removeASCIIWhitespace, "removeASCIIWhitespace"); + module2.exports = { + dataURLProcessor, + URLSerializer, + collectASequenceOfCodePoints, + collectASequenceOfCodePointsFast, + stringPercentDecode, + parseMIMEType, + collectAnHTTPQuotedString, + serializeAMimeType + }; + } +}); + +// lib/fetch/util.js +var require_util2 = __commonJS({ + "lib/fetch/util.js"(exports2, module2) { + "use strict"; + var { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = require_constants2(); + var { getGlobalOrigin } = require_global(); + var { performance: performance2 } = require("perf_hooks"); + var { isBlobLike, toUSVString, ReadableStreamFrom, isValidHTTPToken } = require_util(); + var assert = require("assert"); + var { isUint8Array } = require("util/types"); + var crypto; + try { + crypto = require("crypto"); + } catch { + } + function responseURL(response) { + const urlList = response.urlList; + const length = urlList.length; + return length === 0 ? null : urlList[length - 1].toString(); + } + __name(responseURL, "responseURL"); + function responseLocationURL(response, requestFragment) { + if (!redirectStatusSet.has(response.status)) { + return null; + } + let location = response.headersList.get("location", true); + if (location !== null && isValidHeaderValue(location)) { + location = new URL(location, responseURL(response)); + } + if (location && !location.hash) { + location.hash = requestFragment; + } + return location; + } + __name(responseLocationURL, "responseLocationURL"); + function requestCurrentURL(request) { + return request.urlList[request.urlList.length - 1]; + } + __name(requestCurrentURL, "requestCurrentURL"); + function requestBadPort(request) { + const url = requestCurrentURL(request); + if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { + return "blocked"; + } + return "allowed"; + } + __name(requestBadPort, "requestBadPort"); + function isErrorLike(object) { + return object instanceof Error || (object?.constructor?.name === "Error" || object?.constructor?.name === "DOMException"); + } + __name(isErrorLike, "isErrorLike"); + function isValidReasonPhrase(statusText) { + for (let i = 0; i < statusText.length; ++i) { + const c = statusText.charCodeAt(i); + if (!(c === 9 || // HTAB + c >= 32 && c <= 126 || // SP / VCHAR + c >= 128 && c <= 255)) { + return false; + } + } + return true; + } + __name(isValidReasonPhrase, "isValidReasonPhrase"); + function isValidHeaderName(potentialValue) { + return isValidHTTPToken(potentialValue); + } + __name(isValidHeaderName, "isValidHeaderName"); + function isValidHeaderValue(potentialValue) { + if (potentialValue.startsWith(" ") || potentialValue.startsWith(" ") || potentialValue.endsWith(" ") || potentialValue.endsWith(" ")) { + return false; + } + if (potentialValue.includes("\0") || potentialValue.includes("\r") || potentialValue.includes("\n")) { + return false; + } + return true; + } + __name(isValidHeaderValue, "isValidHeaderValue"); + function setRequestReferrerPolicyOnRedirect(request, actualResponse) { + const { headersList } = actualResponse; + const policyHeader = (headersList.get("referrer-policy", true) ?? "").split(","); + let policy = ""; + if (policyHeader.length > 0) { + for (let i = policyHeader.length; i !== 0; i--) { + const token = policyHeader[i - 1].trim(); + if (referrerPolicyTokens.has(token)) { + policy = token; + break; + } + } + } + if (policy !== "") { + request.referrerPolicy = policy; + } + } + __name(setRequestReferrerPolicyOnRedirect, "setRequestReferrerPolicyOnRedirect"); + function crossOriginResourcePolicyCheck() { + return "allowed"; + } + __name(crossOriginResourcePolicyCheck, "crossOriginResourcePolicyCheck"); + function corsCheck() { + return "success"; + } + __name(corsCheck, "corsCheck"); + function TAOCheck() { + return "success"; + } + __name(TAOCheck, "TAOCheck"); + function appendFetchMetadata(httpRequest) { + let header = null; + header = httpRequest.mode; + httpRequest.headersList.set("sec-fetch-mode", header, true); + } + __name(appendFetchMetadata, "appendFetchMetadata"); + function appendRequestOriginHeader(request) { + let serializedOrigin = request.origin; + if (request.responseTainting === "cors" || request.mode === "websocket") { + if (serializedOrigin) { + request.headersList.append("origin", serializedOrigin, true); + } + } else if (request.method !== "GET" && request.method !== "HEAD") { + switch (request.referrerPolicy) { + case "no-referrer": + serializedOrigin = null; + break; + case "no-referrer-when-downgrade": + case "strict-origin": + case "strict-origin-when-cross-origin": + if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { + serializedOrigin = null; + } + break; + case "same-origin": + if (!sameOrigin(request, requestCurrentURL(request))) { + serializedOrigin = null; + } + break; + default: + } + if (serializedOrigin) { + request.headersList.append("origin", serializedOrigin, true); + } + } + } + __name(appendRequestOriginHeader, "appendRequestOriginHeader"); + function coarsenTime(timestamp, crossOriginIsolatedCapability) { + return timestamp; + } + __name(coarsenTime, "coarsenTime"); + function clampAndCoursenConnectionTimingInfo(connectionTimingInfo, defaultStartTime, crossOriginIsolatedCapability) { + if (!connectionTimingInfo?.startTime || connectionTimingInfo.startTime < defaultStartTime) { + return { + domainLookupStartTime: defaultStartTime, + domainLookupEndTime: defaultStartTime, + connectionStartTime: defaultStartTime, + connectionEndTime: defaultStartTime, + secureConnectionStartTime: defaultStartTime, + ALPNNegotiatedProtocol: connectionTimingInfo?.ALPNNegotiatedProtocol + }; + } + return { + domainLookupStartTime: coarsenTime(connectionTimingInfo.domainLookupStartTime, crossOriginIsolatedCapability), + domainLookupEndTime: coarsenTime(connectionTimingInfo.domainLookupEndTime, crossOriginIsolatedCapability), + connectionStartTime: coarsenTime(connectionTimingInfo.connectionStartTime, crossOriginIsolatedCapability), + connectionEndTime: coarsenTime(connectionTimingInfo.connectionEndTime, crossOriginIsolatedCapability), + secureConnectionStartTime: coarsenTime(connectionTimingInfo.secureConnectionStartTime, crossOriginIsolatedCapability), + ALPNNegotiatedProtocol: connectionTimingInfo.ALPNNegotiatedProtocol + }; + } + __name(clampAndCoursenConnectionTimingInfo, "clampAndCoursenConnectionTimingInfo"); + function coarsenedSharedCurrentTime(crossOriginIsolatedCapability) { + return coarsenTime(performance2.now(), crossOriginIsolatedCapability); + } + __name(coarsenedSharedCurrentTime, "coarsenedSharedCurrentTime"); + function createOpaqueTimingInfo(timingInfo) { + return { + startTime: timingInfo.startTime ?? 0, + redirectStartTime: 0, + redirectEndTime: 0, + postRedirectStartTime: timingInfo.startTime ?? 0, + finalServiceWorkerStartTime: 0, + finalNetworkResponseStartTime: 0, + finalNetworkRequestStartTime: 0, + endTime: 0, + encodedBodySize: 0, + decodedBodySize: 0, + finalConnectionTimingInfo: null + }; + } + __name(createOpaqueTimingInfo, "createOpaqueTimingInfo"); + function makePolicyContainer() { + return { + referrerPolicy: "strict-origin-when-cross-origin" + }; + } + __name(makePolicyContainer, "makePolicyContainer"); + function clonePolicyContainer(policyContainer) { + return { + referrerPolicy: policyContainer.referrerPolicy }; } __name(clonePolicyContainer, "clonePolicyContainer"); @@ -1504,27 +2046,33 @@ var require_util2 = __commonJS({ } } __name(fullyReadBody, "fullyReadBody"); - var ReadableStream = globalThis.ReadableStream; function isReadableStreamLike(stream) { - if (!ReadableStream) { - ReadableStream = require("stream/web").ReadableStream; - } return stream instanceof ReadableStream || stream[Symbol.toStringTag] === "ReadableStream" && typeof stream.tee === "function"; } __name(isReadableStreamLike, "isReadableStreamLike"); - var MAXIMUM_ARGUMENT_LENGTH = 65535; function isomorphicDecode(input) { - if (input.length < MAXIMUM_ARGUMENT_LENGTH) { - return String.fromCharCode(...input); + const length = input.length; + if ((2 << 15) - 1 > length) { + return String.fromCharCode.apply(null, input); + } + let result = ""; + let i = 0; + let addition = (2 << 15) - 1; + while (i < length) { + if (i + addition > length) { + addition = length - i; + } + result += String.fromCharCode.apply(null, input.subarray(i, i += addition)); } - return input.reduce((previous, current) => previous + String.fromCharCode(current), ""); + return result; } __name(isomorphicDecode, "isomorphicDecode"); function readableStreamClose(controller) { try { controller.close(); + controller.byobRequest?.respond(0); } catch (err) { - if (!err.message.includes("Controller is already closed")) { + if (!err.message.includes("Controller is already closed") && !err.message.includes("ReadableStream is already closed")) { throw err; } } @@ -1572,7 +2120,90 @@ var require_util2 = __commonJS({ return protocol === "http:" || protocol === "https:"; } __name(urlIsHttpHttpsScheme, "urlIsHttpHttpsScheme"); - var hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)); + var collectASequenceOfCodePoints; + function simpleRangeHeaderValue(value, allowWhitespace) { + collectASequenceOfCodePoints ??= require_dataURL().collectASequenceOfCodePoints; + const data = value; + if (!data.startsWith("bytes")) { + return "failure"; + } + const position = { position: 5 }; + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === " " || char === " ", + data, + position + ); + } + if (data.charCodeAt(position.position) !== 61) { + return "failure"; + } + position.position++; + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === " " || char === " ", + data, + position + ); + } + const rangeStart = collectASequenceOfCodePoints( + (char) => { + const code = char.charCodeAt(0); + return code >= 48 && code <= 57; + }, + data, + position + ); + const rangeStartValue = rangeStart.length ? Number(rangeStart) : null; + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === " " || char === " ", + data, + position + ); + } + if (data.charCodeAt(position.position) !== 45) { + return "failure"; + } + position.position++; + if (allowWhitespace) { + collectASequenceOfCodePoints( + (char) => char === " " || char === " ", + data, + position + ); + } + const rangeEnd = collectASequenceOfCodePoints( + (char) => { + const code = char.charCodeAt(0); + return code >= 48 && code <= 57; + }, + data, + position + ); + const rangeEndValue = rangeEnd.length ? Number(rangeEnd) : null; + if (position.position < data.length) { + return "failure"; + } + if (rangeEndValue === null && rangeStartValue === null) { + return "failure"; + } + if (rangeStartValue > rangeEndValue) { + return "failure"; + } + return { rangeStartValue, rangeEndValue }; + } + __name(simpleRangeHeaderValue, "simpleRangeHeaderValue"); + function buildContentRange(rangeStart, rangeEnd, fullLength) { + let contentRange = "bytes "; + contentRange += isomorphicEncode(`${rangeStart}`); + contentRange += "-"; + contentRange += isomorphicEncode(`${rangeEnd}`); + contentRange += "/"; + contentRange += isomorphicEncode(`${fullLength}`); + return contentRange; + } + __name(buildContentRange, "buildContentRange"); module2.exports = { isAborted, isCancelled, @@ -1580,6 +2211,7 @@ var require_util2 = __commonJS({ ReadableStreamFrom, toUSVString, tryUpgradeRequestToAPotentiallyTrustworthyURL, + clampAndCoursenConnectionTimingInfo, coarsenedSharedCurrentTime, determineRequestsReferrer, makePolicyContainer, @@ -1605,7 +2237,6 @@ var require_util2 = __commonJS({ makeIterator, isValidHeaderName, isValidHeaderValue, - hasOwn, isErrorLike, fullyReadBody, bytesMatch, @@ -1617,7 +2248,9 @@ var require_util2 = __commonJS({ urlHasHttpsScheme, urlIsHttpHttpsScheme, readAllBytes, - normalizeMethodRecord + normalizeMethodRecord, + simpleRangeHeaderValue, + buildContentRange }; } }); @@ -1627,7 +2260,7 @@ var require_webidl = __commonJS({ "lib/fetch/webidl.js"(exports2, module2) { "use strict"; var { types } = require("util"); - var { hasOwn, toUSVString } = require_util2(); + var { toUSVString } = require_util2(); var webidl = {}; webidl.converters = {}; webidl.util = {}; @@ -1838,7 +2471,7 @@ var require_webidl = __commonJS({ for (const options of converters) { const { key, defaultValue, required, converter } = options; if (required === true) { - if (!hasOwn(dictionary, key)) { + if (!Object.hasOwn(dictionary, key)) { throw webidl.errors.exception({ header: "Dictionary", message: `Missing required key "${key}".` @@ -1846,7 +2479,7 @@ var require_webidl = __commonJS({ } } let value = dictionary[key]; - const hasDefault = hasOwn(options, "defaultValue"); + const hasDefault = Object.hasOwn(options, "defaultValue"); if (hasDefault && value !== null) { value = value ?? defaultValue; } @@ -2066,7 +2699,7 @@ var require_headers = __commonJS({ throw new TypeError("immutable"); } else if (headers[kGuard] === "request-no-cors") { } - return headers[kHeadersList].append(name, value); + return headers[kHeadersList].append(name, value, false); } __name(appendHeader, "appendHeader"); var HeadersList = class _HeadersList { @@ -2085,20 +2718,28 @@ var require_headers = __commonJS({ this[kHeadersSortedMap] = null; } } - // https://fetch.spec.whatwg.org/#header-list-contains - contains(name) { - name = name.toLowerCase(); - return this[kHeadersMap].has(name); + /** + * @see https://fetch.spec.whatwg.org/#header-list-contains + * @param {string} name + * @param {boolean} isLowerCase + */ + contains(name, isLowerCase) { + return this[kHeadersMap].has(isLowerCase ? name : name.toLowerCase()); } clear() { this[kHeadersMap].clear(); this[kHeadersSortedMap] = null; this.cookies = null; } - // https://fetch.spec.whatwg.org/#concept-header-list-append - append(name, value) { + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-append + * @param {string} name + * @param {string} value + * @param {boolean} isLowerCase + */ + append(name, value, isLowerCase) { this[kHeadersSortedMap] = null; - const lowercaseName = name.toLowerCase(); + const lowercaseName = isLowerCase ? name : name.toLowerCase(); const exists = this[kHeadersMap].get(lowercaseName); if (exists) { const delimiter = lowercaseName === "cookie" ? "; " : ", "; @@ -2110,33 +2751,46 @@ var require_headers = __commonJS({ this[kHeadersMap].set(lowercaseName, { name, value }); } if (lowercaseName === "set-cookie") { - this.cookies ??= []; - this.cookies.push(value); + (this.cookies ??= []).push(value); } } - // https://fetch.spec.whatwg.org/#concept-header-list-set - set(name, value) { + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-set + * @param {string} name + * @param {string} value + * @param {boolean} isLowerCase + */ + set(name, value, isLowerCase) { this[kHeadersSortedMap] = null; - const lowercaseName = name.toLowerCase(); + const lowercaseName = isLowerCase ? name : name.toLowerCase(); if (lowercaseName === "set-cookie") { this.cookies = [value]; } this[kHeadersMap].set(lowercaseName, { name, value }); } - // https://fetch.spec.whatwg.org/#concept-header-list-delete - delete(name) { + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-delete + * @param {string} name + * @param {boolean} isLowerCase + */ + delete(name, isLowerCase) { this[kHeadersSortedMap] = null; - name = name.toLowerCase(); + if (!isLowerCase) + name = name.toLowerCase(); if (name === "set-cookie") { this.cookies = null; } this[kHeadersMap].delete(name); } - // https://fetch.spec.whatwg.org/#concept-header-list-get - get(name) { - const value = this[kHeadersMap].get(name.toLowerCase()); - return value === void 0 ? null : value.value; - } + /** + * @see https://fetch.spec.whatwg.org/#concept-header-list-get + * @param {string} name + * @param {boolean} isLowerCase + * @returns {string | null} + */ + get(name, isLowerCase) { + return this[kHeadersMap].get(isLowerCase ? name : name.toLowerCase())?.value ?? null; + } *[Symbol.iterator]() { for (const [name, { value }] of this[kHeadersMap]) { yield [name, value]; @@ -2191,10 +2845,10 @@ var require_headers = __commonJS({ throw new TypeError("immutable"); } else if (this[kGuard] === "request-no-cors") { } - if (!this[kHeadersList].contains(name)) { + if (!this[kHeadersList].contains(name, false)) { return; } - this[kHeadersList].delete(name); + this[kHeadersList].delete(name, false); } // https://fetch.spec.whatwg.org/#dom-headers-get get(name) { @@ -2208,7 +2862,7 @@ var require_headers = __commonJS({ type: "header name" }); } - return this[kHeadersList].get(name); + return this[kHeadersList].get(name, false); } // https://fetch.spec.whatwg.org/#dom-headers-has has(name) { @@ -2222,7 +2876,7 @@ var require_headers = __commonJS({ type: "header name" }); } - return this[kHeadersList].contains(name); + return this[kHeadersList].contains(name, false); } // https://fetch.spec.whatwg.org/#dom-headers-set set(name, value) { @@ -2248,7 +2902,7 @@ var require_headers = __commonJS({ throw new TypeError("immutable"); } else if (this[kGuard] === "request-no-cors") { } - this[kHeadersList].set(name, value); + this[kHeadersList].set(name, value, false); } // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie getSetCookie() { @@ -2532,12 +3186,12 @@ var require_PartStream = __commonJS({ "node_modules/@fastify/busboy/deps/dicer/lib/PartStream.js"(exports2, module2) { "use strict"; var inherits = require("node:util").inherits; - var ReadableStream = require("node:stream").Readable; + var ReadableStream2 = require("node:stream").Readable; function PartStream(opts) { - ReadableStream.call(this, opts); + ReadableStream2.call(this, opts); } __name(PartStream, "PartStream"); - inherits(PartStream, ReadableStream); + inherits(PartStream, ReadableStream2); PartStream.prototype._read = function(n) { }; module2.exports = PartStream; @@ -4289,410 +4943,107 @@ var require_urlencoded = __commonJS({ if (this.boy._done) { return; } - if (this._state === "key" && this._key.length > 0) { - this.boy.emit( - "field", - decodeText(this._key, "binary", this.charset), - "", - this._keyTrunc, - false - ); - } else if (this._state === "val") { - this.boy.emit( - "field", - decodeText(this._key, "binary", this.charset), - decodeText(this._val, "binary", this.charset), - this._keyTrunc, - this._valTrunc - ); - } - this.boy._done = true; - this.boy.emit("finish"); - }; - module2.exports = UrlEncoded; - } -}); - -// node_modules/@fastify/busboy/lib/main.js -var require_main = __commonJS({ - "node_modules/@fastify/busboy/lib/main.js"(exports2, module2) { - "use strict"; - var WritableStream = require("node:stream").Writable; - var { inherits } = require("node:util"); - var Dicer = require_Dicer(); - var MultipartParser = require_multipart(); - var UrlencodedParser = require_urlencoded(); - var parseParams = require_parseParams(); - function Busboy(opts) { - if (!(this instanceof Busboy)) { - return new Busboy(opts); - } - if (typeof opts !== "object") { - throw new TypeError("Busboy expected an options-Object."); - } - if (typeof opts.headers !== "object") { - throw new TypeError("Busboy expected an options-Object with headers-attribute."); - } - if (typeof opts.headers["content-type"] !== "string") { - throw new TypeError("Missing Content-Type-header."); - } - const { - headers, - ...streamOptions - } = opts; - this.opts = { - autoDestroy: false, - ...streamOptions - }; - WritableStream.call(this, this.opts); - this._done = false; - this._parser = this.getParserByHeaders(headers); - this._finished = false; - } - __name(Busboy, "Busboy"); - inherits(Busboy, WritableStream); - Busboy.prototype.emit = function(ev) { - if (ev === "finish") { - if (!this._done) { - this._parser?.end(); - return; - } else if (this._finished) { - return; - } - this._finished = true; - } - WritableStream.prototype.emit.apply(this, arguments); - }; - Busboy.prototype.getParserByHeaders = function(headers) { - const parsed = parseParams(headers["content-type"]); - const cfg = { - defCharset: this.opts.defCharset, - fileHwm: this.opts.fileHwm, - headers, - highWaterMark: this.opts.highWaterMark, - isPartAFile: this.opts.isPartAFile, - limits: this.opts.limits, - parsedConType: parsed, - preservePath: this.opts.preservePath - }; - if (MultipartParser.detect.test(parsed[0])) { - return new MultipartParser(this, cfg); - } - if (UrlencodedParser.detect.test(parsed[0])) { - return new UrlencodedParser(this, cfg); - } - throw new Error("Unsupported Content-Type."); - }; - Busboy.prototype._write = function(chunk, encoding, cb) { - this._parser.write(chunk, cb); - }; - module2.exports = Busboy; - module2.exports.default = Busboy; - module2.exports.Busboy = Busboy; - module2.exports.Dicer = Dicer; - } -}); - -// lib/fetch/dataURL.js -var require_dataURL = __commonJS({ - "lib/fetch/dataURL.js"(exports2, module2) { - var assert = require("assert"); - var { atob: atob2 } = require("buffer"); - var { isomorphicDecode } = require_util2(); - var encoder = new TextEncoder(); - var HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/; - var HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/; - var HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/; - function dataURLProcessor(dataURL) { - assert(dataURL.protocol === "data:"); - let input = URLSerializer(dataURL, true); - input = input.slice(5); - const position = { position: 0 }; - let mimeType = collectASequenceOfCodePointsFast( - ",", - input, - position - ); - const mimeTypeLength = mimeType.length; - mimeType = removeASCIIWhitespace(mimeType, true, true); - if (position.position >= input.length) { - return "failure"; - } - position.position++; - const encodedBody = input.slice(mimeTypeLength + 1); - let body = stringPercentDecode(encodedBody); - if (/;(\u0020){0,}base64$/i.test(mimeType)) { - const stringBody = isomorphicDecode(body); - body = forgivingBase64(stringBody); - if (body === "failure") { - return "failure"; - } - mimeType = mimeType.slice(0, -6); - mimeType = mimeType.replace(/(\u0020)+$/, ""); - mimeType = mimeType.slice(0, -1); - } - if (mimeType.startsWith(";")) { - mimeType = "text/plain" + mimeType; - } - let mimeTypeRecord = parseMIMEType(mimeType); - if (mimeTypeRecord === "failure") { - mimeTypeRecord = parseMIMEType("text/plain;charset=US-ASCII"); - } - return { mimeType: mimeTypeRecord, body }; - } - __name(dataURLProcessor, "dataURLProcessor"); - function URLSerializer(url, excludeFragment = false) { - if (!excludeFragment) { - return url.href; - } - const href = url.href; - const hashLength = url.hash.length; - return hashLength === 0 ? href : href.substring(0, href.length - hashLength); - } - __name(URLSerializer, "URLSerializer"); - function collectASequenceOfCodePoints(condition, input, position) { - let result = ""; - while (position.position < input.length && condition(input[position.position])) { - result += input[position.position]; - position.position++; - } - return result; - } - __name(collectASequenceOfCodePoints, "collectASequenceOfCodePoints"); - function collectASequenceOfCodePointsFast(char, input, position) { - const idx = input.indexOf(char, position.position); - const start = position.position; - if (idx === -1) { - position.position = input.length; - return input.slice(start); - } - position.position = idx; - return input.slice(start, position.position); - } - __name(collectASequenceOfCodePointsFast, "collectASequenceOfCodePointsFast"); - function stringPercentDecode(input) { - const bytes = encoder.encode(input); - return percentDecode(bytes); - } - __name(stringPercentDecode, "stringPercentDecode"); - function percentDecode(input) { - const output = []; - for (let i = 0; i < input.length; i++) { - const byte = input[i]; - if (byte !== 37) { - output.push(byte); - } else if (byte === 37 && !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2]))) { - output.push(37); - } else { - const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2]); - const bytePoint = Number.parseInt(nextTwoBytes, 16); - output.push(bytePoint); - i += 2; - } - } - return Uint8Array.from(output); - } - __name(percentDecode, "percentDecode"); - function parseMIMEType(input) { - input = removeHTTPWhitespace(input, true, true); - const position = { position: 0 }; - const type = collectASequenceOfCodePointsFast( - "/", - input, - position - ); - if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { - return "failure"; - } - if (position.position > input.length) { - return "failure"; - } - position.position++; - let subtype = collectASequenceOfCodePointsFast( - ";", - input, - position - ); - subtype = removeHTTPWhitespace(subtype, false, true); - if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { - return "failure"; - } - const typeLowercase = type.toLowerCase(); - const subtypeLowercase = subtype.toLowerCase(); - const mimeType = { - type: typeLowercase, - subtype: subtypeLowercase, - /** @type {Map} */ - parameters: /* @__PURE__ */ new Map(), - // https://mimesniff.spec.whatwg.org/#mime-type-essence - essence: `${typeLowercase}/${subtypeLowercase}` - }; - while (position.position < input.length) { - position.position++; - collectASequenceOfCodePoints( - // https://fetch.spec.whatwg.org/#http-whitespace - (char) => HTTP_WHITESPACE_REGEX.test(char), - input, - position - ); - let parameterName = collectASequenceOfCodePoints( - (char) => char !== ";" && char !== "=", - input, - position - ); - parameterName = parameterName.toLowerCase(); - if (position.position < input.length) { - if (input[position.position] === ";") { - continue; - } - position.position++; - } - if (position.position > input.length) { - break; - } - let parameterValue = null; - if (input[position.position] === '"') { - parameterValue = collectAnHTTPQuotedString(input, position, true); - collectASequenceOfCodePointsFast( - ";", - input, - position - ); - } else { - parameterValue = collectASequenceOfCodePointsFast( - ";", - input, - position - ); - parameterValue = removeHTTPWhitespace(parameterValue, false, true); - if (parameterValue.length === 0) { - continue; - } - } - if (parameterName.length !== 0 && HTTP_TOKEN_CODEPOINTS.test(parameterName) && (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && !mimeType.parameters.has(parameterName)) { - mimeType.parameters.set(parameterName, parameterValue); - } - } - return mimeType; - } - __name(parseMIMEType, "parseMIMEType"); - function forgivingBase64(data) { - data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, ""); - if (data.length % 4 === 0) { - data = data.replace(/=?=$/, ""); - } - if (data.length % 4 === 1) { - return "failure"; + if (this._state === "key" && this._key.length > 0) { + this.boy.emit( + "field", + decodeText(this._key, "binary", this.charset), + "", + this._keyTrunc, + false + ); + } else if (this._state === "val") { + this.boy.emit( + "field", + decodeText(this._key, "binary", this.charset), + decodeText(this._val, "binary", this.charset), + this._keyTrunc, + this._valTrunc + ); } - if (/[^+/0-9A-Za-z]/.test(data)) { - return "failure"; + this.boy._done = true; + this.boy.emit("finish"); + }; + module2.exports = UrlEncoded; + } +}); + +// node_modules/@fastify/busboy/lib/main.js +var require_main = __commonJS({ + "node_modules/@fastify/busboy/lib/main.js"(exports2, module2) { + "use strict"; + var WritableStream = require("node:stream").Writable; + var { inherits } = require("node:util"); + var Dicer = require_Dicer(); + var MultipartParser = require_multipart(); + var UrlencodedParser = require_urlencoded(); + var parseParams = require_parseParams(); + function Busboy(opts) { + if (!(this instanceof Busboy)) { + return new Busboy(opts); } - const binary = atob2(data); - const bytes = new Uint8Array(binary.length); - for (let byte = 0; byte < binary.length; byte++) { - bytes[byte] = binary.charCodeAt(byte); + if (typeof opts !== "object") { + throw new TypeError("Busboy expected an options-Object."); } - return bytes; - } - __name(forgivingBase64, "forgivingBase64"); - function collectAnHTTPQuotedString(input, position, extractValue) { - const positionStart = position.position; - let value = ""; - assert(input[position.position] === '"'); - position.position++; - while (true) { - value += collectASequenceOfCodePoints( - (char) => char !== '"' && char !== "\\", - input, - position - ); - if (position.position >= input.length) { - break; - } - const quoteOrBackslash = input[position.position]; - position.position++; - if (quoteOrBackslash === "\\") { - if (position.position >= input.length) { - value += "\\"; - break; - } - value += input[position.position]; - position.position++; - } else { - assert(quoteOrBackslash === '"'); - break; - } + if (typeof opts.headers !== "object") { + throw new TypeError("Busboy expected an options-Object with headers-attribute."); } - if (extractValue) { - return value; + if (typeof opts.headers["content-type"] !== "string") { + throw new TypeError("Missing Content-Type-header."); } - return input.slice(positionStart, position.position); + const { + headers, + ...streamOptions + } = opts; + this.opts = { + autoDestroy: false, + ...streamOptions + }; + WritableStream.call(this, this.opts); + this._done = false; + this._parser = this.getParserByHeaders(headers); + this._finished = false; } - __name(collectAnHTTPQuotedString, "collectAnHTTPQuotedString"); - function serializeAMimeType(mimeType) { - assert(mimeType !== "failure"); - const { parameters, essence } = mimeType; - let serialization = essence; - for (let [name, value] of parameters.entries()) { - serialization += ";"; - serialization += name; - serialization += "="; - if (!HTTP_TOKEN_CODEPOINTS.test(value)) { - value = value.replace(/(\\|")/g, "\\$1"); - value = '"' + value; - value += '"'; + __name(Busboy, "Busboy"); + inherits(Busboy, WritableStream); + Busboy.prototype.emit = function(ev) { + if (ev === "finish") { + if (!this._done) { + this._parser?.end(); + return; + } else if (this._finished) { + return; } - serialization += value; - } - return serialization; - } - __name(serializeAMimeType, "serializeAMimeType"); - function isHTTPWhiteSpace(char) { - return char === "\r" || char === "\n" || char === " " || char === " "; - } - __name(isHTTPWhiteSpace, "isHTTPWhiteSpace"); - function removeHTTPWhitespace(str, leading = true, trailing = true) { - let lead = 0; - let trail = str.length - 1; - if (leading) { - for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++) - ; - } - if (trailing) { - for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--) - ; + this._finished = true; } - return str.slice(lead, trail + 1); - } - __name(removeHTTPWhitespace, "removeHTTPWhitespace"); - function isASCIIWhitespace(char) { - return char === "\r" || char === "\n" || char === " " || char === "\f" || char === " "; - } - __name(isASCIIWhitespace, "isASCIIWhitespace"); - function removeASCIIWhitespace(str, leading = true, trailing = true) { - let lead = 0; - let trail = str.length - 1; - if (leading) { - for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++) - ; + WritableStream.prototype.emit.apply(this, arguments); + }; + Busboy.prototype.getParserByHeaders = function(headers) { + const parsed = parseParams(headers["content-type"]); + const cfg = { + defCharset: this.opts.defCharset, + fileHwm: this.opts.fileHwm, + headers, + highWaterMark: this.opts.highWaterMark, + isPartAFile: this.opts.isPartAFile, + limits: this.opts.limits, + parsedConType: parsed, + preservePath: this.opts.preservePath + }; + if (MultipartParser.detect.test(parsed[0])) { + return new MultipartParser(this, cfg); } - if (trailing) { - for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--) - ; + if (UrlencodedParser.detect.test(parsed[0])) { + return new UrlencodedParser(this, cfg); } - return str.slice(lead, trail + 1); - } - __name(removeASCIIWhitespace, "removeASCIIWhitespace"); - module2.exports = { - dataURLProcessor, - URLSerializer, - collectASequenceOfCodePoints, - collectASequenceOfCodePointsFast, - stringPercentDecode, - parseMIMEType, - collectAnHTTPQuotedString, - serializeAMimeType + throw new Error("Unsupported Content-Type."); + }; + Busboy.prototype._write = function(chunk, encoding, cb) { + this._parser.write(chunk, cb); }; + module2.exports = Busboy; + module2.exports.default = Busboy; + module2.exports.Busboy = Busboy; + module2.exports.Dicer = Dicer; } }); @@ -5068,7 +5419,6 @@ var require_body = __commonJS({ var { FormData } = require_formdata(); var { kState } = require_symbols2(); var { webidl } = require_webidl(); - var { DOMException, structuredClone } = require_constants(); var { Blob: Blob2, File: NativeFile } = require("buffer"); var { kBodyUsed } = require_symbols(); var assert = require("assert"); @@ -5076,14 +5426,10 @@ var require_body = __commonJS({ var { isUint8Array, isArrayBuffer } = require("util/types"); var { File: UndiciFile } = require_file(); var { parseMIMEType, serializeAMimeType } = require_dataURL(); - var ReadableStream = globalThis.ReadableStream; var File = NativeFile ?? UndiciFile; var textEncoder = new TextEncoder(); var textDecoder = new TextDecoder(); function extractBody(object, keepalive = false) { - if (!ReadableStream) { - ReadableStream = require("stream/web").ReadableStream; - } let stream = null; if (object instanceof ReadableStream) { stream = object; @@ -5092,14 +5438,15 @@ var require_body = __commonJS({ } else { stream = new ReadableStream({ async pull(controller) { - controller.enqueue( - typeof source === "string" ? textEncoder.encode(source) : source - ); + const buffer = typeof source === "string" ? textEncoder.encode(source) : source; + if (buffer.byteLength) { + controller.enqueue(buffer); + } queueMicrotask(() => readableStreamClose(controller)); }, start() { }, - type: void 0 + type: "bytes" }); } assert(isReadableStreamLike(stream)); @@ -5196,10 +5543,14 @@ Content-Type: ${value.type || "application/octet-stream"}\r if (done) { queueMicrotask(() => { controller.close(); + controller.byobRequest?.respond(0); }); } else { if (!isErrored(stream)) { - controller.enqueue(new Uint8Array(value)); + const buffer = new Uint8Array(value); + if (buffer.byteLength) { + controller.enqueue(buffer); + } } } return controller.desiredSize > 0; @@ -5207,7 +5558,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r async cancel(reason) { await iterator.return(); }, - type: void 0 + type: "bytes" }); } const body = { stream, source, length }; @@ -5215,9 +5566,6 @@ Content-Type: ${value.type || "application/octet-stream"}\r } __name(extractBody, "extractBody"); function safelyExtractBody(object, keepalive = false) { - if (!ReadableStream) { - ReadableStream = require("stream/web").ReadableStream; - } if (object instanceof ReadableStream) { assert(!util.isDisturbed(object), "The body has already been consumed."); assert(!object.locked, "The stream is locked."); @@ -5292,7 +5640,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r if (/multipart\/form-data/.test(contentType)) { const headers = {}; for (const [key, value] of this.headers) - headers[key.toLowerCase()] = value; + headers[key] = value; const responseFormData = new FormData(); let busboy; try { @@ -5456,9 +5804,8 @@ var require_response = __commonJS({ } = require_util2(); var { redirectStatusSet, - nullBodyStatus, - DOMException - } = require_constants(); + nullBodyStatus + } = require_constants2(); var { kState, kHeaders, kGuard, kRealm } = require_symbols2(); var { webidl } = require_webidl(); var { FormData } = require_formdata(); @@ -5467,7 +5814,6 @@ var require_response = __commonJS({ var { kHeadersList, kConstruct } = require_symbols(); var assert = require("assert"); var { types } = require("util"); - var ReadableStream = globalThis.ReadableStream || require("stream/web").ReadableStream; var textEncoder = new TextEncoder("utf-8"); var Response = class _Response { static { @@ -5476,9 +5822,10 @@ var require_response = __commonJS({ // Creates network error Response. static error() { const relevantRealm = { settingsObject: {} }; - const responseObject = new _Response(); + const responseObject = new _Response(kConstruct); responseObject[kState] = makeNetworkError(); responseObject[kRealm] = relevantRealm; + responseObject[kHeaders] = new Headers(kConstruct); responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList; responseObject[kHeaders][kGuard] = "immutable"; responseObject[kHeaders][kRealm] = relevantRealm; @@ -5495,8 +5842,11 @@ var require_response = __commonJS({ ); const body = extractBody(bytes); const relevantRealm = { settingsObject: {} }; - const responseObject = new _Response(); + const responseObject = new _Response(kConstruct); + responseObject[kState] = makeResponse({}); responseObject[kRealm] = relevantRealm; + responseObject[kHeaders] = new Headers(kConstruct); + responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList; responseObject[kHeaders][kGuard] = "response"; responseObject[kHeaders][kRealm] = relevantRealm; initializeResponse(responseObject, init, { body: body[0], type: "application/json" }); @@ -5519,17 +5869,23 @@ var require_response = __commonJS({ if (!redirectStatusSet.has(status)) { throw new RangeError("Invalid status code " + status); } - const responseObject = new _Response(); + const responseObject = new _Response(kConstruct); + responseObject[kState] = makeResponse({}); responseObject[kRealm] = relevantRealm; + responseObject[kHeaders] = new Headers(kConstruct); + responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList; responseObject[kHeaders][kGuard] = "immutable"; responseObject[kHeaders][kRealm] = relevantRealm; responseObject[kState].status = status; const value = isomorphicEncode(URLSerializer(parsedURL)); - responseObject[kState].headersList.append("location", value); + responseObject[kState].headersList.append("location", value, true); return responseObject; } // https://fetch.spec.whatwg.org/#dom-response constructor(body = null, init = {}) { + if (body === kConstruct) { + return; + } if (body !== null) { body = webidl.converters.BodyInit(body); } @@ -5605,9 +5961,10 @@ var require_response = __commonJS({ }); } const clonedResponse = cloneResponse(this[kState]); - const clonedResponseObject = new _Response(); + const clonedResponseObject = new _Response(kConstruct); clonedResponseObject[kState] = clonedResponse; clonedResponseObject[kRealm] = this[kRealm]; + clonedResponseObject[kHeaders] = new Headers(kConstruct); clonedResponseObject[kHeaders][kHeadersList] = clonedResponse.headersList; clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard]; clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm]; @@ -5662,8 +6019,8 @@ var require_response = __commonJS({ cacheState: "", statusText: "", ...init, - headersList: init.headersList ? new HeadersList(init.headersList) : new HeadersList(), - urlList: init.urlList ? [...init.urlList] : [] + headersList: init?.headersList ? new HeadersList(init?.headersList) : new HeadersList(), + urlList: init?.urlList ? [...init.urlList] : [] }; } __name(makeResponse, "makeResponse"); @@ -5757,8 +6114,8 @@ var require_response = __commonJS({ }); } response[kState].body = body.body; - if (body.type != null && !response[kState].headersList.contains("Content-Type")) { - response[kState].headersList.append("content-type", body.type); + if (body.type != null && !response[kState].headersList.contains("content-type", true)) { + response[kState].headersList.append("content-type", body.type, true); } } } @@ -5866,10 +6223,7 @@ var require_dispatcher_weakref = __commonJS({ FinalizationRegistry: CompatFinalizer }; } - return { - WeakRef: global.WeakRef || CompatWeakRef, - FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer - }; + return { WeakRef, FinalizationRegistry }; }; } }); @@ -5880,7 +6234,7 @@ var require_request = __commonJS({ "use strict"; var { extractBody, mixinBody, cloneBody } = require_body(); var { Headers, fill: fillHeaders, HeadersList } = require_headers(); - var { FinalizationRegistry } = require_dispatcher_weakref()(); + var { FinalizationRegistry: FinalizationRegistry2 } = require_dispatcher_weakref()(); var util = require_util(); var { isValidHTTPToken, @@ -5898,7 +6252,7 @@ var require_request = __commonJS({ requestCredentials, requestCache, requestDuplex - } = require_constants(); + } = require_constants2(); var { kEnumerableProperty } = util; var { kHeaders, kSignal, kState, kGuard, kRealm } = require_symbols2(); var { webidl } = require_webidl(); @@ -5907,9 +6261,8 @@ var require_request = __commonJS({ var { kHeadersList, kConstruct } = require_symbols(); var assert = require("assert"); var { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = require("events"); - var TransformStream = globalThis.TransformStream; var kAbortController = Symbol("abortController"); - var requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { + var requestFinalizer = new FinalizationRegistry2(({ signal, abort }) => { signal.removeEventListener("abort", abort); }); var Request = class _Request { @@ -6185,9 +6538,6 @@ var require_request = __commonJS({ "Cannot construct a Request with a Request object that has already been used." ); } - if (!TransformStream) { - TransformStream = require("stream/web").TransformStream; - } const identityTransform = new TransformStream(); inputBody.stream.pipeThrough(identityTransform); finalBody = { @@ -7061,7 +7411,7 @@ var require_request2 = __commonJS({ var assert = require("assert"); var { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = require_symbols(); var util = require_util(); - var tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/; + var { headerNameLowerCasedRecord } = require_constants(); var headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; var invalidPathRegex = /[^\u0021-\u00ff]/; var kHandler = Symbol("handler"); @@ -7109,7 +7459,7 @@ var require_request2 = __commonJS({ } if (typeof method !== "string") { throw new InvalidArgumentError("method must be a string"); - } else if (tokenRegExp.exec(method) === null) { + } else if (!util.isValidHTTPToken(method)) { throw new InvalidArgumentError("invalid request method"); } if (upgrade && typeof upgrade !== "string") { @@ -7194,9 +7544,6 @@ var require_request2 = __commonJS({ throw new InvalidArgumentError("headers must be an object or an array"); } if (util.isFormDataLike(this.body)) { - if (util.nodeMajor < 16 || util.nodeMajor === 16 && util.nodeMinor < 8) { - throw new InvalidArgumentError("Form-Data bodies are only supported in node v16.8 and newer."); - } if (!extractBody) { extractBody = require_body().extractBody; } @@ -7251,6 +7598,9 @@ var require_request2 = __commonJS({ return this[kHandler].onConnect(abort); } } + onResponseStarted() { + return this[kHandler].onResponseStarted?.(); + } onHeaders(statusCode, headers, resume, statusText) { assert(!this.aborted); assert(!this.completed); @@ -7376,39 +7726,40 @@ var require_request2 = __commonJS({ } else if (val === void 0) { return; } - if (request.host === null && key.length === 4 && key.toLowerCase() === "host") { + let headerName = headerNameLowerCasedRecord[key]; + if (headerName === void 0) { + headerName = key.toLowerCase(); + if (headerNameLowerCasedRecord[headerName] === void 0 && !util.isValidHTTPToken(headerName)) { + throw new InvalidArgumentError("invalid header key"); + } + } + if (request.host === null && headerName === "host") { if (headerCharRegex.exec(val) !== null) { throw new InvalidArgumentError(`invalid ${key} header`); } request.host = val; - } else if (request.contentLength === null && key.length === 14 && key.toLowerCase() === "content-length") { + } else if (request.contentLength === null && headerName === "content-length") { request.contentLength = parseInt(val, 10); if (!Number.isFinite(request.contentLength)) { throw new InvalidArgumentError("invalid content-length header"); } - } else if (request.contentType === null && key.length === 12 && key.toLowerCase() === "content-type") { + } else if (request.contentType === null && headerName === "content-type") { request.contentType = val; if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend); else request.headers += processHeaderValue(key, val); - } else if (key.length === 17 && key.toLowerCase() === "transfer-encoding") { - throw new InvalidArgumentError("invalid transfer-encoding header"); - } else if (key.length === 10 && key.toLowerCase() === "connection") { + } else if (headerName === "transfer-encoding" || headerName === "keep-alive" || headerName === "upgrade") { + throw new InvalidArgumentError(`invalid ${headerName} header`); + } else if (headerName === "connection") { const value = typeof val === "string" ? val.toLowerCase() : null; if (value !== "close" && value !== "keep-alive") { throw new InvalidArgumentError("invalid connection header"); } else if (value === "close") { request.reset = true; } - } else if (key.length === 10 && key.toLowerCase() === "keep-alive") { - throw new InvalidArgumentError("invalid keep-alive header"); - } else if (key.length === 7 && key.toLowerCase() === "upgrade") { - throw new InvalidArgumentError("invalid upgrade header"); - } else if (key.length === 6 && key.toLowerCase() === "expect") { + } else if (headerName === "expect") { throw new NotSupportedError("expect header not supported"); - } else if (tokenRegExp.exec(key) === null) { - throw new InvalidArgumentError("invalid header key"); } else { if (Array.isArray(val)) { for (let i = 0; i < val.length; i++) { @@ -7444,7 +7795,7 @@ var require_connect = __commonJS({ var { InvalidArgumentError, ConnectTimeoutError } = require_errors(); var tls; var SessionCache; - if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) { + if (global.FinalizationRegistry && !(process.env.NODE_V8_COVERAGE || process.env.UNDICI_NO_FG)) { SessionCache = class WeakSessionCache { static { __name(this, "WeakSessionCache"); @@ -7592,7 +7943,11 @@ var require_connect = __commonJS({ } __name(setupTimeout, "setupTimeout"); function onConnectTimeout(socket) { - util.destroy(socket, new ConnectTimeoutError()); + let message = "Connect Timeout Error"; + if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { + message = +` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(", ")})`; + } + util.destroy(socket, new ConnectTimeoutError(message)); } __name(onConnectTimeout, "onConnectTimeout"); module2.exports = buildConnector; @@ -7621,7 +7976,7 @@ var require_utils = __commonJS({ }); // lib/llhttp/constants.js -var require_constants2 = __commonJS({ +var require_constants3 = __commonJS({ "lib/llhttp/constants.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); @@ -8056,14 +8411,24 @@ var require_RedirectHandler = __commonJS({ return null; } for (let i = 0; i < headers.length; i += 2) { - if (headers[i].toString().toLowerCase() === "location") { + if (headers[i].length === 8 && util.headerNameToString(headers[i]) === "location") { return headers[i + 1]; } } } __name(parseLocation, "parseLocation"); function shouldRemoveHeader(header, removeContent, unknownOrigin) { - return header.length === 4 && header.toString().toLowerCase() === "host" || removeContent && header.toString().toLowerCase().indexOf("content-") === 0 || unknownOrigin && header.length === 13 && header.toString().toLowerCase() === "authorization" || unknownOrigin && header.length === 6 && header.toString().toLowerCase() === "cookie"; + if (header.length === 4) { + return util.headerNameToString(header) === "host"; + } + if (removeContent && util.headerNameToString(header).startsWith("content-")) { + return true; + } + if (unknownOrigin && (header.length === 13 || header.length === 6)) { + const name = util.headerNameToString(header); + return name === "authorization" || name === "cookie"; + } + return false; } __name(shouldRemoveHeader, "shouldRemoveHeader"); function cleanRequestHeaders(headers, removeContent, unknownOrigin) { @@ -8340,7 +8705,7 @@ var require_client = __commonJS({ throw new InvalidArgumentError("allowH2 must be a valid boolean value"); } if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== "number" || maxConcurrentStreams < 1)) { - throw new InvalidArgumentError("maxConcurrentStreams must be a possitive integer, greater than 0"); + throw new InvalidArgumentError("maxConcurrentStreams must be a positive integer, greater than 0"); } if (typeof connect2 !== "function") { connect2 = buildConnector({ @@ -8381,7 +8746,7 @@ var require_client = __commonJS({ this[kHTTP2SessionState] = !allowH2 ? null : { // streams: null, // Fixed queue of streams - For future support of `push` openStreams: 0, - // Keep track of them to decide wether or not unref the session + // Keep track of them to decide whether or not unref the session maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server }; @@ -8518,7 +8883,7 @@ var require_client = __commonJS({ resume(client); } __name(onHTTP2GoAway, "onHTTP2GoAway"); - var constants = require_constants2(); + var constants = require_constants3(); var createRedirectInterceptor = require_redirectInterceptor(); var EMPTY_BUF = Buffer.alloc(0); async function lazyllhttp() { @@ -8722,6 +9087,7 @@ var require_client = __commonJS({ if (!request) { return -1; } + request.onResponseStarted(); } onHeaderField(buf) { const len = this.headers.length; @@ -8741,11 +9107,14 @@ var require_client = __commonJS({ this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]); } const key = this.headers[len - 2]; - if (key.length === 10 && key.toString().toLowerCase() === "keep-alive") { - this.keepAlive += buf.toString(); - } else if (key.length === 10 && key.toString().toLowerCase() === "connection") { - this.connection += buf.toString(); - } else if (key.length === 14 && key.toString().toLowerCase() === "content-length") { + if (key.length === 10) { + const headerName = util.bufferToLowerCasedHeaderName(key); + if (headerName === "keep-alive") { + this.keepAlive += buf.toString(); + } else if (headerName === "connection") { + this.connection += buf.toString(); + } + } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === "content-length") { this.contentLength += buf.toString(); } this.trackHeader(buf.length); @@ -9477,6 +9846,7 @@ upgrade: ${upgrade}\r ++h2State.openStreams; stream.once("response", (headers2) => { const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers2; + request.onResponseStarted(); if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), "") === false) { stream.pause(); } @@ -9622,13 +9992,15 @@ upgrade: ${upgrade}\r body.resume(); } }, "onDrain"); - const onAbort = /* @__PURE__ */ __name(function() { - if (finished) { - return; + const onClose = /* @__PURE__ */ __name(function() { + queueMicrotask(() => { + body.removeListener("error", onFinished); + }); + if (!finished) { + const err = new RequestAbortedError(); + queueMicrotask(() => onFinished(err)); } - const err = new RequestAbortedError(); - queueMicrotask(() => onFinished(err)); - }, "onAbort"); + }, "onClose"); const onFinished = /* @__PURE__ */ __name(function(err) { if (finished) { return; @@ -9636,7 +10008,7 @@ upgrade: ${upgrade}\r finished = true; assert(socket.destroyed || socket[kWriting] && client[kRunning] <= 1); socket.off("drain", onDrain).off("error", onFinished); - body.removeListener("data", onData).removeListener("end", onFinished).removeListener("error", onFinished).removeListener("close", onAbort); + body.removeListener("data", onData).removeListener("end", onFinished).removeListener("close", onClose); if (!err) { try { writer.end(); @@ -9651,7 +10023,7 @@ upgrade: ${upgrade}\r util.destroy(body); } }, "onFinished"); - body.on("data", onData).on("end", onFinished).on("error", onFinished).on("close", onAbort); + body.on("data", onData).on("end", onFinished).on("error", onFinished).on("close", onClose); if (body.resume) { body.resume(); } @@ -9968,14 +10340,12 @@ var require_agent = __commonJS({ var Client = require_client(); var util = require_util(); var createRedirectInterceptor = require_redirectInterceptor(); - var { WeakRef: WeakRef2, FinalizationRegistry } = require_dispatcher_weakref()(); var kOnConnect = Symbol("onConnect"); var kOnDisconnect = Symbol("onDisconnect"); var kOnConnectionError = Symbol("onConnectionError"); var kMaxRedirections = Symbol("maxRedirections"); var kOnDrain = Symbol("onDrain"); var kFactory = Symbol("factory"); - var kFinalizer = Symbol("finalizer"); var kOptions = Symbol("options"); function defaultFactory(origin, opts) { return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); @@ -10005,15 +10375,6 @@ var require_agent = __commonJS({ this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; this[kClients] = /* @__PURE__ */ new Map(); - this[kFinalizer] = new FinalizationRegistry( - /* istanbul ignore next: gc is undeterministic */ - (key) => { - const ref = this[kClients].get(key); - if (ref !== void 0 && ref.deref() === void 0) { - this[kClients].delete(key); - } - } - ); const agent = this; this[kOnDrain] = (origin, targets) => { agent.emit("drain", origin, [agent, ...targets]); @@ -10030,11 +10391,8 @@ var require_agent = __commonJS({ } get [kRunning]() { let ret = 0; - for (const ref of this[kClients].values()) { - const client = ref.deref(); - if (client) { - ret += client[kRunning]; - } + for (const client of this[kClients].values()) { + ret += client[kRunning]; } return ret; } @@ -10045,33 +10403,27 @@ var require_agent = __commonJS({ } else { throw new InvalidArgumentError("opts.origin must be a non-empty string or URL."); } - const ref = this[kClients].get(key); - let dispatcher = ref ? ref.deref() : null; + let dispatcher = this[kClients].get(key); if (!dispatcher) { dispatcher = this[kFactory](opts.origin, this[kOptions]).on("drain", this[kOnDrain]).on("connect", this[kOnConnect]).on("disconnect", this[kOnDisconnect]).on("connectionError", this[kOnConnectionError]); - this[kClients].set(key, new WeakRef2(dispatcher)); - this[kFinalizer].register(dispatcher, key); + this[kClients].set(key, dispatcher); } return dispatcher.dispatch(opts, handler); } async [kClose]() { const closePromises = []; - for (const ref of this[kClients].values()) { - const client = ref.deref(); - if (client) { - closePromises.push(client.close()); - } + for (const client of this[kClients].values()) { + closePromises.push(client.close()); } + this[kClients].clear(); await Promise.all(closePromises); } async [kDestroy](err) { const destroyPromises = []; - for (const ref of this[kClients].values()) { - const client = ref.deref(); - if (client) { - destroyPromises.push(client.destroy(err)); - } + for (const client of this[kClients].values()) { + destroyPromises.push(client.destroy(err)); } + this[kClients].clear(); await Promise.all(destroyPromises); } }; @@ -10123,7 +10475,7 @@ var require_fetch = __commonJS({ filterResponse, makeResponse } = require_response(); - var { Headers } = require_headers(); + var { Headers, HeadersList } = require_headers(); var { Request, makeRequest } = require_request(); var zlib = require("zlib"); var { @@ -10154,31 +10506,31 @@ var require_fetch = __commonJS({ isomorphicEncode, urlIsLocal, urlIsHttpHttpsScheme, - urlHasHttpsScheme + urlHasHttpsScheme, + clampAndCoursenConnectionTimingInfo, + simpleRangeHeaderValue, + buildContentRange } = require_util2(); var { kState, kHeaders, kGuard, kRealm } = require_symbols2(); var assert = require("assert"); - var { safelyExtractBody } = require_body(); + var { safelyExtractBody, extractBody } = require_body(); var { redirectStatusSet, nullBodyStatus, safeMethodsSet, requestBodyHeader, - subresourceSet, - DOMException - } = require_constants(); - var { kHeadersList } = require_symbols(); + subresourceSet + } = require_constants2(); + var { kHeadersList, kConstruct } = require_symbols(); var EE = require("events"); var { Readable, pipeline } = require("stream"); - var { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = require_util(); - var { dataURLProcessor, serializeAMimeType } = require_dataURL(); - var { TransformStream } = require("stream/web"); + var { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor, bufferToLowerCasedHeaderName } = require_util(); + var { dataURLProcessor, serializeAMimeType, parseMIMEType } = require_dataURL(); var { getGlobalDispatcher } = require_global2(); var { webidl } = require_webidl(); var { STATUS_CODES } = require("http"); var GET_OR_HEAD = ["GET", "HEAD"]; var resolveObjectURL; - var ReadableStream = globalThis.ReadableStream; var Fetch = class extends EE { static { __name(this, "Fetch"); @@ -10260,9 +10612,10 @@ var require_fetch = __commonJS({ ); return Promise.resolve(); } - responseObject = new Response(); + responseObject = new Response(kConstruct); responseObject[kState] = response; responseObject[kRealm] = relevantRealm; + responseObject[kHeaders] = new Headers(kConstruct); responseObject[kHeaders][kHeadersList] = response.headersList; responseObject[kHeaders][kGuard] = "immutable"; responseObject[kHeaders][kRealm] = relevantRealm; @@ -10361,9 +10714,9 @@ var require_fetch = __commonJS({ taskDestination = request.client.globalObject; crossOriginIsolatedCapability = request.client.crossOriginIsolatedCapability; } - const currenTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability); + const currentTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability); const timingInfo = createOpaqueTimingInfo({ - startTime: currenTime + startTime: currentTime }); const fetchParams = { controller: new Fetch(dispatcher), @@ -10393,12 +10746,12 @@ var require_fetch = __commonJS({ request.policyContainer = makePolicyContainer(); } } - if (!request.headersList.contains("accept")) { + if (!request.headersList.contains("accept", true)) { const value = "*/*"; - request.headersList.append("accept", value); + request.headersList.append("accept", value, true); } - if (!request.headersList.contains("accept-language")) { - request.headersList.append("accept-language", "*"); + if (!request.headersList.contains("accept-language", true)) { + request.headersList.append("accept-language", "*", true); } if (request.priority === null) { } @@ -10481,7 +10834,7 @@ var require_fetch = __commonJS({ if (!request.timingAllowFailed) { response.timingAllowPassed = true; } - if (response.type === "opaque" && internalResponse.status === 206 && internalResponse.rangeRequested && !request.headers.contains("range")) { + if (response.type === "opaque" && internalResponse.status === 206 && internalResponse.rangeRequested && !request.headers.contains("range", true)) { response = internalResponse = makeNetworkError(); } if (response.status !== 0 && (request.method === "HEAD" || request.method === "CONNECT" || nullBodyStatus.includes(internalResponse.status))) { @@ -10526,22 +10879,50 @@ var require_fetch = __commonJS({ if (blobURLEntry.search.length !== 0) { return Promise.resolve(makeNetworkError("NetworkError when attempting to fetch resource.")); } - const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()); - if (request.method !== "GET" || !isBlobLike(blobURLEntryObject)) { + const blob = resolveObjectURL(blobURLEntry.toString()); + if (request.method !== "GET" || !isBlobLike(blob)) { return Promise.resolve(makeNetworkError("invalid method")); } - const bodyWithType = safelyExtractBody(blobURLEntryObject); - const body = bodyWithType[0]; - const length = isomorphicEncode(`${body.length}`); - const type = bodyWithType[1] ?? ""; - const response = makeResponse({ - statusText: "OK", - headersList: [ - ["content-length", { name: "Content-Length", value: length }], - ["content-type", { name: "Content-Type", value: type }] - ] - }); - response.body = body; + const response = makeResponse(); + const fullLength = blob.size; + const serializedFullLength = isomorphicEncode(`${fullLength}`); + const type = blob.type; + if (!request.headersList.contains("range", true)) { + const bodyWithType = extractBody(blob); + response.statusText = "OK"; + response.body = bodyWithType[0]; + response.headersList.set("content-length", serializedFullLength, true); + response.headersList.set("content-type", type, true); + } else { + response.rangeRequested = true; + const rangeHeader = request.headersList.get("range", true); + const rangeValue = simpleRangeHeaderValue(rangeHeader, true); + if (rangeValue === "failure") { + return Promise.resolve(makeNetworkError("failed to fetch the data URL")); + } + let { rangeStartValue: rangeStart, rangeEndValue: rangeEnd } = rangeValue; + if (rangeStart === null) { + rangeStart = fullLength - rangeEnd; + rangeEnd = rangeStart + rangeEnd - 1; + } else { + if (rangeStart >= fullLength) { + return Promise.resolve(makeNetworkError("Range start is greater than the blob's size.")); + } + if (rangeEnd === null || rangeEnd >= fullLength) { + rangeEnd = fullLength - 1; + } + } + const slicedBlob = blob.slice(rangeStart, rangeEnd, type); + const slicedBodyWithType = extractBody(slicedBlob); + response.body = slicedBodyWithType[0]; + const serializedSlicedLength = isomorphicEncode(`${slicedBlob.size}`); + const contentRange = buildContentRange(rangeStart, rangeEnd, fullLength); + response.status = 206; + response.statusText = "Partial Content"; + response.headersList.set("content-length", serializedSlicedLength, true); + response.headersList.set("content-type", type, true); + response.headersList.set("content-range", contentRange, true); + } return Promise.resolve(response); } case "data:": { @@ -10580,52 +10961,77 @@ var require_fetch = __commonJS({ } __name(finalizeResponse, "finalizeResponse"); function fetchFinale(fetchParams, response) { - if (response.type === "error") { - response.urlList = [fetchParams.request.urlList[0]]; - response.timingInfo = createOpaqueTimingInfo({ - startTime: fetchParams.timingInfo.startTime - }); - } + let timingInfo = fetchParams.timingInfo; const processResponseEndOfBody = /* @__PURE__ */ __name(() => { - fetchParams.request.done = true; - if (fetchParams.processResponseEndOfBody != null) { - queueMicrotask(() => fetchParams.processResponseEndOfBody(response)); + const unsafeEndTime = Date.now(); + if (fetchParams.request.destination === "document") { + fetchParams.controller.fullTimingInfo = timingInfo; } + fetchParams.controller.reportTimingSteps = () => { + if (fetchParams.request.url.protocol !== "https:") { + return; + } + timingInfo.endTime = unsafeEndTime; + let cacheState = response.cacheState; + const bodyInfo = response.bodyInfo; + if (!response.timingAllowPassed) { + timingInfo = createOpaqueTimingInfo(timingInfo); + cacheState = ""; + } + let responseStatus = 0; + if (fetchParams.request.mode !== "navigator" || !response.hasCrossOriginRedirects) { + responseStatus = response.status; + const mimeType = parseMIMEType(response.headersList.get("content-type", true)); + if (mimeType !== "failure") { + } + } + if (fetchParams.request.initiatorType != null) { + markResourceTiming(timingInfo, fetchParams.request.url, fetchParams.request.initiatorType, globalThis, cacheState, bodyInfo, responseStatus); + } + }; + const processResponseEndOfBodyTask = /* @__PURE__ */ __name(() => { + fetchParams.request.done = true; + if (fetchParams.processResponseEndOfBody != null) { + queueMicrotask(() => fetchParams.processResponseEndOfBody(response)); + } + if (fetchParams.request.initiatorType != null) { + fetchParams.controller.reportTimingSteps(); + } + }, "processResponseEndOfBodyTask"); + queueMicrotask(() => processResponseEndOfBodyTask()); }, "processResponseEndOfBody"); if (fetchParams.processResponse != null) { queueMicrotask(() => fetchParams.processResponse(response)); } - if (response.body == null) { + const internalResponse = response.type === "error" ? response : response.internalResponse ?? response; + if (internalResponse.body == null) { processResponseEndOfBody(); } else { - const identityTransformAlgorithm = /* @__PURE__ */ __name((chunk, controller) => { - controller.enqueue(chunk); - }, "identityTransformAlgorithm"); const transformStream = new TransformStream({ start() { }, - transform: identityTransformAlgorithm, + transform(chunk, controller) { + controller.enqueue(chunk); + }, flush: processResponseEndOfBody - }, { - size() { - return 1; - } - }, { - size() { - return 1; - } }); - response.body = { stream: response.body.stream.pipeThrough(transformStream) }; - } - if (fetchParams.processResponseConsumeBody != null) { - const processBody = /* @__PURE__ */ __name((nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes), "processBody"); - const processBodyError = /* @__PURE__ */ __name((failure) => fetchParams.processResponseConsumeBody(response, failure), "processBodyError"); - if (response.body == null) { - queueMicrotask(() => processBody(null)); - } else { - return fullyReadBody(response.body, processBody, processBodyError); - } - return Promise.resolve(); + internalResponse.body.stream.pipeThrough(transformStream); + const byteStream = new ReadableStream({ + readableStream: transformStream.readable, + async start(controller) { + const reader = this.readableStream.getReader(); + while (true) { + const { done, value } = await reader.read(); + if (done) { + queueMicrotask(() => readableStreamClose(controller)); + break; + } + controller.enqueue(value); + } + }, + type: "bytes" + }); + internalResponse.body.stream = byteStream; } } __name(fetchFinale, "fetchFinale"); @@ -10715,9 +11121,9 @@ var require_fetch = __commonJS({ } } if (!sameOrigin(requestCurrentURL(request), locationURL)) { - request.headersList.delete("authorization"); - request.headersList.delete("cookie"); - request.headersList.delete("host"); + request.headersList.delete("authorization", true); + request.headersList.delete("cookie", true); + request.headersList.delete("host", true); } if (request.body != null) { assert(request.body.source != null); @@ -10758,43 +11164,43 @@ var require_fetch = __commonJS({ contentLengthHeaderValue = isomorphicEncode(`${contentLength}`); } if (contentLengthHeaderValue != null) { - httpRequest.headersList.append("content-length", contentLengthHeaderValue); + httpRequest.headersList.append("content-length", contentLengthHeaderValue, true); } if (contentLength != null && httpRequest.keepalive) { } if (httpRequest.referrer instanceof URL) { - httpRequest.headersList.append("referer", isomorphicEncode(httpRequest.referrer.href)); + httpRequest.headersList.append("referer", isomorphicEncode(httpRequest.referrer.href), true); } appendRequestOriginHeader(httpRequest); appendFetchMetadata(httpRequest); - if (!httpRequest.headersList.contains("user-agent")) { - httpRequest.headersList.append("user-agent", false ? "undici" : "node"); + if (!httpRequest.headersList.contains("user-agent", true)) { + httpRequest.headersList.append("user-agent", false ? "undici" : "node", true); } - if (httpRequest.cache === "default" && (httpRequest.headersList.contains("if-modified-since") || httpRequest.headersList.contains("if-none-match") || httpRequest.headersList.contains("if-unmodified-since") || httpRequest.headersList.contains("if-match") || httpRequest.headersList.contains("if-range"))) { + if (httpRequest.cache === "default" && (httpRequest.headersList.contains("if-modified-since", true) || httpRequest.headersList.contains("if-none-match", true) || httpRequest.headersList.contains("if-unmodified-since", true) || httpRequest.headersList.contains("if-match", true) || httpRequest.headersList.contains("if-range", true))) { httpRequest.cache = "no-store"; } - if (httpRequest.cache === "no-cache" && !httpRequest.preventNoCacheCacheControlHeaderModification && !httpRequest.headersList.contains("cache-control")) { - httpRequest.headersList.append("cache-control", "max-age=0"); + if (httpRequest.cache === "no-cache" && !httpRequest.preventNoCacheCacheControlHeaderModification && !httpRequest.headersList.contains("cache-control", true)) { + httpRequest.headersList.append("cache-control", "max-age=0", true); } if (httpRequest.cache === "no-store" || httpRequest.cache === "reload") { - if (!httpRequest.headersList.contains("pragma")) { - httpRequest.headersList.append("pragma", "no-cache"); + if (!httpRequest.headersList.contains("pragma", true)) { + httpRequest.headersList.append("pragma", "no-cache", true); } - if (!httpRequest.headersList.contains("cache-control")) { - httpRequest.headersList.append("cache-control", "no-cache"); + if (!httpRequest.headersList.contains("cache-control", true)) { + httpRequest.headersList.append("cache-control", "no-cache", true); } } - if (httpRequest.headersList.contains("range")) { - httpRequest.headersList.append("accept-encoding", "identity"); + if (httpRequest.headersList.contains("range", true)) { + httpRequest.headersList.append("accept-encoding", "identity", true); } - if (!httpRequest.headersList.contains("accept-encoding")) { + if (!httpRequest.headersList.contains("accept-encoding", true)) { if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { - httpRequest.headersList.append("accept-encoding", "br, gzip, deflate"); + httpRequest.headersList.append("accept-encoding", "br, gzip, deflate", true); } else { - httpRequest.headersList.append("accept-encoding", "gzip, deflate"); + httpRequest.headersList.append("accept-encoding", "gzip, deflate", true); } } - httpRequest.headersList.delete("host"); + httpRequest.headersList.delete("host", true); if (includeCredentials) { } if (httpCache == null) { @@ -10820,7 +11226,7 @@ var require_fetch = __commonJS({ } } response.urlList = [...httpRequest.urlList]; - if (httpRequest.headersList.contains("range")) { + if (httpRequest.headersList.contains("range", true)) { response.rangeRequested = true; } response.requestIncludesCredentials = includeCredentials; @@ -10939,9 +11345,6 @@ var require_fetch = __commonJS({ const cancelAlgorithm = /* @__PURE__ */ __name((reason) => { fetchParams.controller.abort(reason); }, "cancelAlgorithm"); - if (!ReadableStream) { - ReadableStream = require("stream/web").ReadableStream; - } const stream = new ReadableStream( { async start(controller) { @@ -10952,13 +11355,8 @@ var require_fetch = __commonJS({ }, async cancel(reason) { await cancelAlgorithm(reason); - } - }, - { - highWaterMark: 0, - size() { - return 1; - } + }, + type: "bytes" } ); response.body = { stream }; @@ -10991,7 +11389,10 @@ var require_fetch = __commonJS({ fetchParams.controller.terminate(bytes); return; } - fetchParams.controller.controller.enqueue(new Uint8Array(bytes)); + const buffer = new Uint8Array(bytes); + if (buffer.byteLength) { + fetchParams.controller.controller.enqueue(buffer); + } if (isErrored(stream)) { fetchParams.controller.terminate(); return; @@ -11020,7 +11421,7 @@ var require_fetch = __commonJS({ } __name(onAborted, "onAborted"); return response; - async function dispatch({ body }) { + function dispatch({ body }) { const url = requestCurrentURL(request); const agent = fetchParams.controller.dispatcher; return new Promise((resolve, reject) => agent.dispatch( @@ -11028,7 +11429,7 @@ var require_fetch = __commonJS({ path: url.pathname + url.search, origin: url.origin, method: request.method, - body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, + body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body, headers: request.headersList.entries, maxRedirections: 0, upgrade: request.mode === "websocket" ? "websocket" : void 0 @@ -11038,48 +11439,51 @@ var require_fetch = __commonJS({ abort: null, onConnect(abort) { const { connection } = fetchParams.controller; + timingInfo.finalConnectionTimingInfo = clampAndCoursenConnectionTimingInfo(void 0, timingInfo.postRedirectStartTime, fetchParams.crossOriginIsolatedCapability); if (connection.destroyed) { abort(new DOMException("The operation was aborted.", "AbortError")); } else { fetchParams.controller.on("terminated", abort); this.abort = connection.abort = abort; } + timingInfo.finalNetworkRequestStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); }, - onHeaders(status, headersList, resume, statusText) { + onResponseStarted() { + timingInfo.finalNetworkResponseStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); + }, + onHeaders(status, rawHeaders, resume, statusText) { if (status < 200) { return; } let codings = []; let location = ""; - const headers = new Headers(); - if (Array.isArray(headersList)) { - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString("latin1"); - const val = headersList[n + 1].toString("latin1"); - if (key.toLowerCase() === "content-encoding") { - codings = val.toLowerCase().split(",").map((x) => x.trim()); - } else if (key.toLowerCase() === "location") { - location = val; - } - headers[kHeadersList].append(key, val); + const headersList = new HeadersList(); + if (Array.isArray(rawHeaders)) { + for (let i = 0; i < rawHeaders.length; i += 2) { + headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } + const contentEncoding = headersList.get("content-encoding", true); + if (contentEncoding) { + codings = contentEncoding.toLowerCase().split(",").map((x) => x.trim()); + } + location = headersList.get("location", true); } else { - const keys = Object.keys(headersList); - for (const key of keys) { - const val = headersList[key]; - if (key.toLowerCase() === "content-encoding") { - codings = val.toLowerCase().split(",").map((x) => x.trim()).reverse(); - } else if (key.toLowerCase() === "location") { - location = val; - } - headers[kHeadersList].append(key, val); + const keys = Object.keys(rawHeaders); + for (let i = 0; i < keys.length; ++i) { + headersList.append(keys[i], rawHeaders[keys[i]]); } + const contentEncoding = rawHeaders["content-encoding"]; + if (contentEncoding) { + codings = contentEncoding.toLowerCase().split(",").map((x) => x.trim()).reverse(); + } + location = rawHeaders.location; } this.body = new Readable({ read: resume }); const decoders = []; - const willFollow = request.redirect === "follow" && location && redirectStatusSet.has(status); + const willFollow = location && request.redirect === "follow" && redirectStatusSet.has(status); if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { - for (const coding of codings) { + for (let i = 0; i < codings.length; ++i) { + const coding = codings[i]; if (coding === "x-gzip" || coding === "gzip") { decoders.push(zlib.createGunzip({ // Be less strict when decoding compressed responses, since sometimes @@ -11102,7 +11506,7 @@ var require_fetch = __commonJS({ resolve({ status, statusText, - headersList: headers[kHeadersList], + headersList, body: decoders.length ? pipeline(this.body, ...decoders, () => { }) : this.body.on("error", () => { }) @@ -11132,20 +11536,18 @@ var require_fetch = __commonJS({ fetchParams.controller.terminate(error); reject(error); }, - onUpgrade(status, headersList, socket) { + onUpgrade(status, rawHeaders, socket) { if (status !== 101) { return; } - const headers = new Headers(); - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString("latin1"); - const val = headersList[n + 1].toString("latin1"); - headers[kHeadersList].append(key, val); + const headersList = new HeadersList(); + for (let i = 0; i < rawHeaders.length; i += 2) { + headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } resolve({ status, statusText: STATUS_CODES[status], - headersList: headers[kHeadersList], + headersList, socket }); return true; @@ -11166,7 +11568,7 @@ var require_fetch = __commonJS({ }); // lib/websocket/constants.js -var require_constants3 = __commonJS({ +var require_constants4 = __commonJS({ "lib/websocket/constants.js"(exports2, module2) { "use strict"; var uid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -11483,7 +11885,7 @@ var require_util3 = __commonJS({ "lib/websocket/util.js"(exports2, module2) { "use strict"; var { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = require_symbols3(); - var { states, opcodes } = require_constants3(); + var { states, opcodes } = require_constants4(); var { MessageEvent, ErrorEvent } = require_events(); function isEstablished(ws) { return ws[kReadyState] === states.OPEN; @@ -11581,7 +11983,7 @@ var require_connection = __commonJS({ "lib/websocket/connection.js"(exports2, module2) { "use strict"; var diagnosticsChannel = require("diagnostics_channel"); - var { uid, states } = require_constants3(); + var { uid, states } = require_constants4(); var { kReadyState, kSentClose, @@ -11732,7 +12134,7 @@ var require_connection = __commonJS({ var require_frame = __commonJS({ "lib/websocket/frame.js"(exports2, module2) { "use strict"; - var { maxUnsigned16Bit } = require_constants3(); + var { maxUnsigned16Bit } = require_constants4(); var crypto; try { crypto = require("crypto"); @@ -11794,7 +12196,7 @@ var require_receiver = __commonJS({ "use strict"; var { Writable } = require("stream"); var diagnosticsChannel = require("diagnostics_channel"); - var { parserStates, opcodes, states, emptyBuffer } = require_constants3(); + var { parserStates, opcodes, states, emptyBuffer } = require_constants4(); var { kReadyState, kSentClose, kResponse, kReceivedClose } = require_symbols3(); var { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = require_util3(); var { WebsocketFrameSend } = require_frame(); @@ -12032,10 +12434,9 @@ var require_websocket = __commonJS({ "lib/websocket/websocket.js"(exports2, module2) { "use strict"; var { webidl } = require_webidl(); - var { DOMException } = require_constants(); var { URLSerializer } = require_dataURL(); var { getGlobalOrigin } = require_global(); - var { staticPropertyDescriptors, states, opcodes, emptyBuffer } = require_constants3(); + var { staticPropertyDescriptors, states, opcodes, emptyBuffer } = require_constants4(); var { kWebSocketURL, kReadyState, diff --git a/src/undici_version.h b/src/undici_version.h index 02433e7e0c3a84..3c74788caee88a 100644 --- a/src/undici_version.h +++ b/src/undici_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-undici.sh #ifndef SRC_UNDICI_VERSION_H_ #define SRC_UNDICI_VERSION_H_ -#define UNDICI_VERSION "5.28.2" +#define UNDICI_VERSION "6.2.1" #endif // SRC_UNDICI_VERSION_H_