mirror of
https://github.com/golangci/golangci-lint-action
synced 2026-11-02 21:23:55 +00:00
build(deps): bump undici from 7.30.0 to 7.30.1 (#1430)
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
This commit is contained in:
co-authored by
Fernandez Ludovic
parent
80a417e615
commit
1eaa2a6e86
+298
-38
@@ -33621,18 +33621,24 @@ const SessionCache = class WeakSessionCache {
|
||||
if (this._sessionCache.has(sessionKey)) {
|
||||
this._sessionCache.delete(sessionKey)
|
||||
} else if (this._sessionCache.size >= this._maxCachedSessions) {
|
||||
// Make room for the new session: prefer an entry whose session has
|
||||
// already been collected, otherwise evict the oldest one.
|
||||
let evicted = false
|
||||
for (const [key, ref] of this._sessionCache) {
|
||||
if (ref.deref() === undefined) {
|
||||
this._sessionCache.delete(key)
|
||||
return
|
||||
evicted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!evicted) {
|
||||
const oldest = this._sessionCache.keys().next()
|
||||
if (!oldest.done) {
|
||||
this._sessionCache.delete(oldest.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._sessionCache.set(sessionKey, new WeakRef(session))
|
||||
this._sessionRegistry.register(session, sessionKey)
|
||||
@@ -35760,6 +35766,7 @@ module.exports = {
|
||||
kDestroy: Symbol('destroy'),
|
||||
kDispatch: Symbol('dispatch'),
|
||||
kUrl: Symbol('url'),
|
||||
kRedirectCacheControl: Symbol('redirect cache control'),
|
||||
kWriting: Symbol('writing'),
|
||||
kResuming: Symbol('resuming'),
|
||||
kQueue: Symbol('queue'),
|
||||
@@ -37028,7 +37035,7 @@ function defaultFactory (origin, opts) {
|
||||
}
|
||||
|
||||
class Agent extends DispatcherBase {
|
||||
constructor ({ factory = defaultFactory, maxOrigins = Infinity, connect, ...options } = {}) {
|
||||
constructor ({ factory = defaultFactory, maxOrigins = Infinity, connect, tls, ...options } = {}) {
|
||||
if (typeof factory !== 'function') {
|
||||
throw new InvalidArgumentError('factory must be a function.')
|
||||
}
|
||||
@@ -37047,7 +37054,11 @@ class Agent extends DispatcherBase {
|
||||
connect = { ...connect }
|
||||
}
|
||||
|
||||
this[kOptions] = { ...util.deepClone(options), maxOrigins, connect }
|
||||
if (tls && typeof tls !== 'function') {
|
||||
tls = { ...tls }
|
||||
}
|
||||
|
||||
this[kOptions] = { ...util.deepClone(options), maxOrigins, connect, tls }
|
||||
this[kFactory] = factory
|
||||
this[kClients] = new Map()
|
||||
this[kOrigins] = new Set()
|
||||
@@ -38329,8 +38340,6 @@ function connectH1 (client, socket) {
|
||||
}
|
||||
|
||||
function onHttpSocketError (err) {
|
||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
||||
|
||||
const parser = this[kParser]
|
||||
|
||||
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
|
||||
@@ -39448,8 +39457,6 @@ function onHttp2SendPing (session) {
|
||||
}
|
||||
|
||||
function onHttp2SessionError (err) {
|
||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
||||
|
||||
this[kSocket][kError] = err
|
||||
this[kClient][kOnError](err)
|
||||
}
|
||||
@@ -39591,8 +39598,6 @@ function onHttp2SocketClose () {
|
||||
}
|
||||
|
||||
function onHttp2SocketError (err) {
|
||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
||||
|
||||
this[kError] = err
|
||||
|
||||
this[kClient][kOnError](err)
|
||||
@@ -40338,7 +40343,8 @@ class Client extends DispatcherBase {
|
||||
initialWindowSize,
|
||||
connectionWindowSize,
|
||||
pingInterval,
|
||||
webSocket
|
||||
webSocket,
|
||||
eventSource
|
||||
} = {}) {
|
||||
if (keepAlive !== undefined) {
|
||||
throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
|
||||
@@ -40446,7 +40452,7 @@ class Client extends DispatcherBase {
|
||||
throw new InvalidArgumentError('pingInterval must be a positive integer, greater or equal to 0')
|
||||
}
|
||||
|
||||
super({ webSocket })
|
||||
super({ webSocket, eventSource })
|
||||
|
||||
if (typeof connect !== 'function') {
|
||||
connect = buildConnector({
|
||||
@@ -40899,6 +40905,7 @@ module.exports = Client
|
||||
"use strict";
|
||||
|
||||
|
||||
const buffer = __nccwpck_require__(4573)
|
||||
const Dispatcher = __nccwpck_require__(30883)
|
||||
const UnwrapHandler = __nccwpck_require__(92365)
|
||||
const {
|
||||
@@ -40911,6 +40918,7 @@ const { kDestroy, kClose, kClosed, kDestroyed, kDispatch } = __nccwpck_require__
|
||||
const kOnDestroyed = Symbol('onDestroyed')
|
||||
const kOnClosed = Symbol('onClosed')
|
||||
const kWebSocketOptions = Symbol('webSocketOptions')
|
||||
const kEventSourceOptions = Symbol('eventSourceOptions')
|
||||
|
||||
class DispatcherBase extends Dispatcher {
|
||||
/** @type {boolean} */
|
||||
@@ -40931,6 +40939,7 @@ class DispatcherBase extends Dispatcher {
|
||||
constructor (opts) {
|
||||
super()
|
||||
this[kWebSocketOptions] = opts?.webSocket ?? {}
|
||||
this[kEventSourceOptions] = opts?.eventSource ?? {}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40943,6 +40952,15 @@ class DispatcherBase extends Dispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {import('../../types/client').Client.EventSourceOptions}
|
||||
*/
|
||||
get eventSourceOptions () {
|
||||
return {
|
||||
maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
get destroyed () {
|
||||
return this[kDestroyed]
|
||||
@@ -42743,6 +42761,7 @@ module.exports = {
|
||||
|
||||
|
||||
const util = __nccwpck_require__(3440)
|
||||
const { kRedirectCacheControl } = __nccwpck_require__(36443)
|
||||
const {
|
||||
parseCacheControlHeader,
|
||||
hasInvalidCacheControlDirective,
|
||||
@@ -42755,6 +42774,19 @@ const { parseHttpDate } = __nccwpck_require__(25453)
|
||||
|
||||
function noop () {}
|
||||
|
||||
/**
|
||||
* @param {string | URL} a
|
||||
* @param {string | URL} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function sameOrigin (a, b) {
|
||||
try {
|
||||
return new URL(String(a)).origin === new URL(String(b)).origin
|
||||
} catch {
|
||||
return String(a) === String(b)
|
||||
}
|
||||
}
|
||||
|
||||
// Status codes that we can use some heuristics on to cache
|
||||
const HEURISTICALLY_CACHEABLE_STATUS_CODES = [
|
||||
200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501
|
||||
@@ -42893,6 +42925,14 @@ class CacheHandler {
|
||||
*/
|
||||
#writeStream
|
||||
|
||||
/**
|
||||
* The URLs visited while following redirects, shared by reference from the
|
||||
* redirect handler through the request context. Carries the suppressed hops'
|
||||
* cache-control under {@link kRedirectCacheControl}.
|
||||
* @type {URL[] | undefined}
|
||||
*/
|
||||
#history
|
||||
|
||||
/**
|
||||
* @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} opts
|
||||
* @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey
|
||||
@@ -42909,6 +42949,9 @@ class CacheHandler {
|
||||
onRequestStart (controller, context) {
|
||||
this.#writeStream?.destroy()
|
||||
this.#writeStream = undefined
|
||||
// The redirect handler mutates this shared history as redirects are
|
||||
// followed, allowing the cache to identify the response's actual origin.
|
||||
this.#history = context?.history
|
||||
this.#handler.onRequestStart?.(controller, context)
|
||||
}
|
||||
|
||||
@@ -42948,6 +42991,29 @@ class CacheHandler {
|
||||
return downstreamOnHeaders()
|
||||
}
|
||||
|
||||
// Never store a response produced by a different origin under the original
|
||||
// request's cache key.
|
||||
if (this.#history && this.#history.length > 0) {
|
||||
const finalUrl = this.#history[this.#history.length - 1]
|
||||
if (!sameOrigin(finalUrl.origin, this.#cacheKey.origin)) {
|
||||
return downstreamOnHeaders()
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve restrictive cache policy from suppressed redirect responses.
|
||||
const redirectCacheControl = this.#history?.[kRedirectCacheControl]
|
||||
if (redirectCacheControl) {
|
||||
for (const hopCacheControl of redirectCacheControl) {
|
||||
const hopDirectives = hopCacheControl ? parseCacheControlHeader(hopCacheControl) : {}
|
||||
if (
|
||||
hopDirectives['no-store'] === true ||
|
||||
(this.#cacheType === 'shared' && hopDirectives.private === true)
|
||||
) {
|
||||
return downstreamOnHeaders()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const cacheControlHeader = resHeaders['cache-control']
|
||||
const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {}
|
||||
|
||||
@@ -43749,6 +43815,7 @@ const DEFAULT_MAX_BUFFER_SIZE = 5 * 1024 * 1024
|
||||
* @property {number} bufferedBytes
|
||||
* @property {object | null} pendingTrailers
|
||||
* @property {boolean} done
|
||||
* @property {boolean} [pendingStart] onRequestStart deferred until the primary request's context is known
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43763,6 +43830,20 @@ class DeduplicationHandler {
|
||||
*/
|
||||
#primaryHandler
|
||||
|
||||
/**
|
||||
* Whether the primary request has started (onRequestStart received). Until
|
||||
* then the request context is unknown and cannot be given to waiting handlers.
|
||||
* @type {boolean}
|
||||
*/
|
||||
#requestStarted = false
|
||||
|
||||
/**
|
||||
* The primary request context, replayed to waiting handlers so they observe
|
||||
* the same redirect history as the primary.
|
||||
* @type {any}
|
||||
*/
|
||||
#context = null
|
||||
|
||||
/**
|
||||
* @type {WaitingHandler[]}
|
||||
*/
|
||||
@@ -43845,7 +43926,10 @@ class DeduplicationHandler {
|
||||
const waitingController = waitingHandler.controller
|
||||
|
||||
try {
|
||||
handler.onRequestStart?.(waitingController, null)
|
||||
if (this.#requestStarted) {
|
||||
// The primary request has started, so its context (including the
|
||||
// redirect history) is known and can be delivered immediately.
|
||||
handler.onRequestStart?.(waitingController, this.#context)
|
||||
|
||||
if (waitingController.aborted) {
|
||||
waitingHandler.done = true
|
||||
@@ -43860,6 +43944,13 @@ class DeduplicationHandler {
|
||||
this.#statusMessage
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// The primary request has not started yet. Defer onRequestStart until
|
||||
// its context is known, so the waiting handler observes the same
|
||||
// redirect history as the primary (a cache handler relies on it to
|
||||
// reject cross-origin redirect responses).
|
||||
waitingHandler.pendingStart = true
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors from waiting handlers
|
||||
waitingHandler.done = true
|
||||
@@ -43879,6 +43970,24 @@ class DeduplicationHandler {
|
||||
*/
|
||||
onRequestStart (controller, context) {
|
||||
this.#controller = controller
|
||||
if (!this.#requestStarted) {
|
||||
this.#requestStarted = true
|
||||
this.#context = context
|
||||
// Deliver the now-known context to handlers that joined before the
|
||||
// primary request started.
|
||||
for (const waitingHandler of this.#waitingHandlers) {
|
||||
if (waitingHandler.pendingStart && !waitingHandler.done && !waitingHandler.controller.aborted) {
|
||||
waitingHandler.pendingStart = false
|
||||
try {
|
||||
waitingHandler.handler.onRequestStart?.(waitingHandler.controller, context)
|
||||
} catch {
|
||||
// Ignore errors from waiting handlers
|
||||
waitingHandler.done = true
|
||||
}
|
||||
}
|
||||
}
|
||||
this.#pruneDoneWaitingHandlers()
|
||||
}
|
||||
this.#primaryHandler.onRequestStart?.(controller, context)
|
||||
}
|
||||
|
||||
@@ -44052,7 +44161,8 @@ class DeduplicationHandler {
|
||||
bufferedChunks: [],
|
||||
bufferedBytes: 0,
|
||||
pendingTrailers: null,
|
||||
done: false
|
||||
done: false,
|
||||
pendingStart: false
|
||||
}
|
||||
|
||||
const state = {
|
||||
@@ -44202,7 +44312,7 @@ module.exports = DeduplicationHandler
|
||||
|
||||
|
||||
const util = __nccwpck_require__(3440)
|
||||
const { kBodyUsed } = __nccwpck_require__(36443)
|
||||
const { kBodyUsed, kRedirectCacheControl } = __nccwpck_require__(36443)
|
||||
const assert = __nccwpck_require__(34589)
|
||||
const { InvalidArgumentError } = __nccwpck_require__(68707)
|
||||
const EE = __nccwpck_require__(78474)
|
||||
@@ -44248,6 +44358,11 @@ class RedirectHandler {
|
||||
this.maxRedirections = maxRedirections
|
||||
this.handler = handler
|
||||
this.history = []
|
||||
// Retain cache-control from suppressed redirect hops for an outer cache.
|
||||
Object.defineProperty(this.history, kRedirectCacheControl, {
|
||||
value: [],
|
||||
enumerable: false
|
||||
})
|
||||
|
||||
if (util.isStream(this.opts.body)) {
|
||||
// TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
|
||||
@@ -44331,6 +44446,8 @@ class RedirectHandler {
|
||||
return
|
||||
}
|
||||
|
||||
this.history[kRedirectCacheControl].push(headers['cache-control'])
|
||||
|
||||
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)))
|
||||
const path = search ? `${pathname}${search}` : pathname
|
||||
|
||||
@@ -46035,10 +46152,15 @@ class DecompressHandler extends DecoratorHandler {
|
||||
this.#decompressedSize = decompressedSize
|
||||
}
|
||||
|
||||
try {
|
||||
const result = super.onResponseData(this.#controller, chunk)
|
||||
if (result === false && !this.#controller.paused) {
|
||||
this.#controller.pause()
|
||||
}
|
||||
} catch (err) {
|
||||
this.#fail(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
} while (this.#drainRequested && !this.#terminated && !this.#controller.paused)
|
||||
} finally {
|
||||
@@ -46054,9 +46176,14 @@ class DecompressHandler extends DecoratorHandler {
|
||||
return
|
||||
}
|
||||
|
||||
this.#terminated = true
|
||||
this.#cleanupDecompressors()
|
||||
try {
|
||||
super.onResponseEnd(this.#controller, this.#trailers)
|
||||
} catch (err) {
|
||||
this.#fail(err)
|
||||
return
|
||||
}
|
||||
this.#terminated = true
|
||||
}
|
||||
|
||||
#onDecompressionEnd () {
|
||||
@@ -53701,8 +53828,10 @@ function getCookies (headers) {
|
||||
|
||||
const cookie = headers.get('cookie')
|
||||
|
||||
// A null prototype keeps a cookie named `__proto__` from hitting the
|
||||
// Object.prototype setter, which would silently drop it.
|
||||
/** @type {Record<string, string>} */
|
||||
const out = {}
|
||||
const out = { __proto__: null }
|
||||
|
||||
if (!cookie) {
|
||||
return out
|
||||
@@ -53968,6 +54097,7 @@ function parseSetCookie (header) {
|
||||
* @param {Object.<string, unknown>} [cookieAttributeList={}]
|
||||
*/
|
||||
function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) {
|
||||
while (true) {
|
||||
// 1. If the unparsed-attributes string is empty, skip the rest of
|
||||
// these steps.
|
||||
if (unparsedAttributes.length === 0) {
|
||||
@@ -54036,7 +54166,7 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
||||
// 6. If the attribute-value is longer than 1024 octets, ignore the
|
||||
// cookie-av string and return to Step 1 of this algorithm.
|
||||
if (attributeValue.length > maxAttributeValueSize) {
|
||||
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList)
|
||||
continue
|
||||
}
|
||||
|
||||
// 7. Process the attribute-name and attribute-value according to the
|
||||
@@ -54066,13 +54196,13 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
||||
const charCode = attributeValue.charCodeAt(0)
|
||||
|
||||
if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') {
|
||||
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList)
|
||||
continue
|
||||
}
|
||||
|
||||
// 2. If the remainder of attribute-value contains a non-DIGIT
|
||||
// character, ignore the cookie-av.
|
||||
if (!/^\d+$/.test(attributeValue)) {
|
||||
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList)
|
||||
continue
|
||||
}
|
||||
|
||||
// 3. Let delta-seconds be the attribute-value converted to an integer.
|
||||
@@ -54181,7 +54311,7 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
||||
}
|
||||
|
||||
// 8. Return to Step 1 of this algorithm.
|
||||
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -54513,9 +54643,28 @@ function stringify (cookie) {
|
||||
out.push(`Path=${cookie.path}`)
|
||||
}
|
||||
|
||||
if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') {
|
||||
// A numeric 0 is the Unix epoch, not an absent value -- the same reason the
|
||||
// Max-Age check above tests the type rather than truthiness.
|
||||
//
|
||||
// expires is Date | number, so the "Invalid Date" check only guards the Date
|
||||
// form. A number that is not a valid time value (NaN, +/-Infinity, or outside
|
||||
// the Date range) would otherwise reach toIMFDate, which splices undefined and
|
||||
// NaN into the header value instead of failing.
|
||||
if (cookie.expires != null) {
|
||||
const expiresMs = cookie.expires instanceof Date
|
||||
? cookie.expires.getTime()
|
||||
: cookie.expires
|
||||
|
||||
// The largest time value a Date can represent, in milliseconds, i.e.
|
||||
// 100,000,000 days either side of the epoch (ECMA-262 Date Time Values).
|
||||
// Anything within it is safe for toIMFDate to format; anything beyond it
|
||||
// produces an invalid Date and must be ignored instead.
|
||||
const maxTimeValue = 8640000000000000
|
||||
|
||||
if (typeof expiresMs === 'number' && Number.isFinite(expiresMs) && Math.abs(expiresMs) <= maxTimeValue) {
|
||||
out.push(`Expires=${toIMFDate(cookie.expires)}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (cookie.sameSite) {
|
||||
out.push(`SameSite=${cookie.sameSite}`)
|
||||
@@ -54557,6 +54706,7 @@ module.exports = {
|
||||
|
||||
"use strict";
|
||||
|
||||
const buffer = __nccwpck_require__(4573)
|
||||
const { Transform } = __nccwpck_require__(57075)
|
||||
const { isASCIINumber, isValidLastEventId } = __nccwpck_require__(94811)
|
||||
|
||||
@@ -54581,11 +54731,19 @@ const COLON = 0x3A
|
||||
*/
|
||||
const SPACE = 0x20
|
||||
|
||||
const defaultMaxEventSize = buffer.kStringMaxLength
|
||||
|
||||
const DATA = Buffer.from('data')
|
||||
const EVENT = Buffer.from('event')
|
||||
const ID = Buffer.from('id')
|
||||
const RETRY = Buffer.from('retry')
|
||||
|
||||
// Each data field creates a string node, and each unconsumed input chunk keeps
|
||||
// a Buffer wrapper. The absolute ceiling protects the large default byte limit.
|
||||
const minParserItems = 1024
|
||||
const maxParserItems = 131072
|
||||
const bytesPerParserItem = 128
|
||||
|
||||
function isASCIINumberBytes (buffer, start) {
|
||||
if (start >= buffer.length) {
|
||||
return false
|
||||
@@ -54624,6 +54782,12 @@ function isFieldName (line, length, field) {
|
||||
return true
|
||||
}
|
||||
|
||||
function createMaxEventSizeExceededError () {
|
||||
const error = new Error('EventSource message size exceeded')
|
||||
error.aborted = false
|
||||
return error
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} EventSourceStreamEvent
|
||||
* @type {object}
|
||||
@@ -54672,6 +54836,13 @@ class EventSourceStream extends Transform {
|
||||
pos = 0
|
||||
lineChunkIndex = 0
|
||||
linePos = 0
|
||||
lineLength = 0
|
||||
eventSize = 0
|
||||
eventFieldSizes = { data: 0, event: 0, id: 0, retry: 0 }
|
||||
dataLineCount = 0
|
||||
maxEventSize
|
||||
maxDataLines
|
||||
maxBufferedChunks
|
||||
|
||||
event = {
|
||||
data: undefined,
|
||||
@@ -54683,6 +54854,7 @@ class EventSourceStream extends Transform {
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {boolean} [options.readableObjectMode]
|
||||
* @param {number} [options.maxEventSize]
|
||||
* @param {eventSourceSettings} [options.eventSourceSettings]
|
||||
* @param {(chunk: any, encoding?: BufferEncoding | undefined) => boolean} [options.push]
|
||||
*/
|
||||
@@ -54694,6 +54866,12 @@ class EventSourceStream extends Transform {
|
||||
super(options)
|
||||
|
||||
this.state = options.eventSourceSettings || {}
|
||||
this.maxEventSize = options.maxEventSize ?? defaultMaxEventSize
|
||||
const parserItemLimit = this.maxEventSize > 0
|
||||
? Math.min(maxParserItems, Math.max(minParserItems, Math.floor(this.maxEventSize / bytesPerParserItem)))
|
||||
: 0
|
||||
this.maxDataLines = parserItemLimit
|
||||
this.maxBufferedChunks = parserItemLimit
|
||||
if (options.push) {
|
||||
this.push = options.push
|
||||
}
|
||||
@@ -54711,6 +54889,14 @@ class EventSourceStream extends Transform {
|
||||
return
|
||||
}
|
||||
|
||||
// A leading line ending can immediately release the currently buffered
|
||||
// line, even when it uses the final allowed chunk slot.
|
||||
if (this.maxEventSize > 0 &&
|
||||
this.chunks.length >= this.maxBufferedChunks &&
|
||||
chunk[0] !== LF && chunk[0] !== CR) {
|
||||
callback(createMaxEventSizeExceededError())
|
||||
return
|
||||
}
|
||||
this.chunks.push(chunk)
|
||||
|
||||
// Strip leading byte-order-mark if we opened the stream and started
|
||||
@@ -54789,7 +54975,12 @@ class EventSourceStream extends Transform {
|
||||
|
||||
// In any case, we can process the line as we reached an
|
||||
// end-of-line character
|
||||
try {
|
||||
this.parseLine(this.readLine(), this.event)
|
||||
} catch (error) {
|
||||
callback(error)
|
||||
return
|
||||
}
|
||||
this.consumeCurrentByte()
|
||||
// A line was processed and this could be the end of the event. We need
|
||||
// to check if the next line is empty to determine if the event is
|
||||
@@ -54798,12 +54989,25 @@ class EventSourceStream extends Transform {
|
||||
continue
|
||||
}
|
||||
|
||||
// readLine() is only called after CR or LF. Reject an unfinished line
|
||||
// before it can retain an unbounded number of decoded chunks. The seven
|
||||
// extra bytes allow the longest field prefix ("event: " or "retry: ").
|
||||
if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) {
|
||||
callback(createMaxEventSizeExceededError())
|
||||
return
|
||||
}
|
||||
this.advanceCursor()
|
||||
}
|
||||
|
||||
callback()
|
||||
}
|
||||
|
||||
_destroy (error, callback) {
|
||||
this.chunks.length = 0
|
||||
this.clearEvent()
|
||||
super._destroy(error, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Buffer} line
|
||||
* @param {EventSourceStreamEvent} event
|
||||
@@ -54840,6 +55044,13 @@ class EventSourceStream extends Transform {
|
||||
}
|
||||
|
||||
if (isFieldName(line, fieldLength, DATA)) {
|
||||
if (this.maxEventSize > 0 && this.dataLineCount >= this.maxDataLines) {
|
||||
throw createMaxEventSizeExceededError()
|
||||
}
|
||||
const valueBytes = line.length - valueStart
|
||||
const dataSize = this.eventFieldSizes.data + (event.data === undefined ? 0 : 1) + valueBytes
|
||||
this.setEventFieldSize('data', dataSize)
|
||||
|
||||
const value = line.toString('utf8', valueStart)
|
||||
|
||||
if (event.data === undefined) {
|
||||
@@ -54847,11 +55058,13 @@ class EventSourceStream extends Transform {
|
||||
} else {
|
||||
event.data += `\n${value}`
|
||||
}
|
||||
this.dataLineCount++
|
||||
return
|
||||
}
|
||||
|
||||
if (isFieldName(line, fieldLength, RETRY)) {
|
||||
if (isASCIINumberBytes(line, valueStart)) {
|
||||
this.setEventFieldSize('retry', line.length - valueStart)
|
||||
event.retry = line.toString('utf8', valueStart)
|
||||
}
|
||||
return
|
||||
@@ -54859,18 +55072,27 @@ class EventSourceStream extends Transform {
|
||||
|
||||
if (isFieldName(line, fieldLength, ID)) {
|
||||
if (isValidLastEventIdBytes(line, valueStart)) {
|
||||
this.setEventFieldSize('id', line.length - valueStart)
|
||||
event.id = line.toString('utf8', valueStart)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (isFieldName(line, fieldLength, EVENT)) {
|
||||
const value = line.toString('utf8', valueStart)
|
||||
if (valueStart < line.length) {
|
||||
this.setEventFieldSize('event', line.length - valueStart)
|
||||
event.event = line.toString('utf8', valueStart)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.length > 0) {
|
||||
event.event = value
|
||||
}
|
||||
setEventFieldSize (field, size) {
|
||||
const eventSize = this.eventSize - this.eventFieldSizes[field] + size
|
||||
if (this.maxEventSize > 0 && eventSize > this.maxEventSize) {
|
||||
throw createMaxEventSizeExceededError()
|
||||
}
|
||||
this.eventSize = eventSize
|
||||
this.eventFieldSizes[field] = size
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54903,6 +55125,12 @@ class EventSourceStream extends Transform {
|
||||
this.event.event = undefined
|
||||
this.event.id = undefined
|
||||
this.event.retry = undefined
|
||||
this.eventSize = 0
|
||||
this.dataLineCount = 0
|
||||
this.eventFieldSizes.data = 0
|
||||
this.eventFieldSizes.event = 0
|
||||
this.eventFieldSizes.id = 0
|
||||
this.eventFieldSizes.retry = 0
|
||||
}
|
||||
|
||||
hasPendingEvent () {
|
||||
@@ -54938,14 +55166,16 @@ class EventSourceStream extends Transform {
|
||||
syncLineStartToCursor () {
|
||||
this.lineChunkIndex = this.chunkIndex
|
||||
this.linePos = this.pos
|
||||
this.lineLength = 0
|
||||
this.dropConsumedChunks()
|
||||
}
|
||||
|
||||
dropConsumedChunks () {
|
||||
while (this.lineChunkIndex > 0) {
|
||||
this.chunks.shift()
|
||||
this.lineChunkIndex--
|
||||
this.chunkIndex--
|
||||
if (this.lineChunkIndex > 0) {
|
||||
const consumed = this.lineChunkIndex
|
||||
this.chunks.splice(0, consumed)
|
||||
this.lineChunkIndex = 0
|
||||
this.chunkIndex -= consumed
|
||||
}
|
||||
|
||||
if (this.chunkIndex === this.chunks.length) {
|
||||
@@ -55070,6 +55300,7 @@ const { createFastMessageEvent } = __nccwpck_require__(15188)
|
||||
const { isNetworkError } = __nccwpck_require__(99051)
|
||||
const { kEnumerableProperty } = __nccwpck_require__(3440)
|
||||
const { environmentSettingsObject } = __nccwpck_require__(73168)
|
||||
const { getGlobalDispatcher } = __nccwpck_require__(32581)
|
||||
|
||||
let experimentalWarned = false
|
||||
|
||||
@@ -55352,6 +55583,7 @@ class EventSource extends EventTarget {
|
||||
|
||||
const eventSourceStream = new EventSourceStream({
|
||||
eventSourceSettings: this.#state,
|
||||
maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize,
|
||||
push: (event) => {
|
||||
this.dispatchEvent(createFastMessageEvent(
|
||||
event.type,
|
||||
@@ -55536,7 +55768,8 @@ webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([
|
||||
},
|
||||
{
|
||||
key: 'dispatcher', // undici only
|
||||
converter: webidl.converters.any
|
||||
converter: webidl.converters.any,
|
||||
defaultValue: () => getGlobalDispatcher()
|
||||
},
|
||||
{
|
||||
key: 'node', // undici only
|
||||
@@ -60717,8 +60950,6 @@ async function httpNetworkFetch (
|
||||
}
|
||||
const location = headersList.get('location', true)
|
||||
|
||||
this.body = new Readable({ read: resume })
|
||||
|
||||
const willFollow = location && request.redirect === 'follow' &&
|
||||
redirectStatusSet.has(status)
|
||||
|
||||
@@ -60736,7 +60967,7 @@ async function httpNetworkFetch (
|
||||
// CVE fix similar to urllib3 (GHSA-gm62-xv2j-4w53) and curl (CVE-2022-32206).
|
||||
const maxContentEncodings = 5
|
||||
if (codings.length > maxContentEncodings) {
|
||||
reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`))
|
||||
this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`))
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -60774,6 +61005,8 @@ async function httpNetworkFetch (
|
||||
}
|
||||
}
|
||||
|
||||
this.body = new Readable({ read: resume })
|
||||
|
||||
const onError = this.onError.bind(this)
|
||||
|
||||
resolve({
|
||||
@@ -64277,6 +64510,19 @@ function collectASequenceOfCodePointsFast (char, input, position) {
|
||||
}
|
||||
|
||||
const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g // eslint-disable-line no-control-regex
|
||||
const nonASCIIRegex = /[^\x00-\x7F]/ // eslint-disable-line no-control-regex
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*
|
||||
* @see https://infra.spec.whatwg.org/#ascii-lowercase
|
||||
*/
|
||||
function asciiLowercase (str) {
|
||||
return nonASCIIRegex.test(str)
|
||||
? str.replace(/[A-Z]+/g, (upper) => upper.toLowerCase())
|
||||
: str.toLowerCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
@@ -64441,6 +64687,7 @@ function serializeJavascriptValueToJSONString (value) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
asciiLowercase,
|
||||
collectASequenceOfCodePoints,
|
||||
collectASequenceOfCodePointsFast,
|
||||
forgivingBase64,
|
||||
@@ -64464,6 +64711,7 @@ module.exports = {
|
||||
|
||||
const assert = __nccwpck_require__(34589)
|
||||
const { runtimeFeatures } = __nccwpck_require__(313)
|
||||
const { asciiLowercase } = __nccwpck_require__(8116)
|
||||
|
||||
/**
|
||||
* @typedef {object} Metadata
|
||||
@@ -64528,14 +64776,12 @@ const getSRIHashAlgorithmIndex = /** @type {GetSRIHashAlgorithmIndex} */ (Map.pr
|
||||
|
||||
/**
|
||||
* @typedef IsValidSRIHashAlgorithm
|
||||
* @see https://w3c.github.io/webappsec-subresource-integrity/#valid-sri-hash-algorithm-token
|
||||
* @type {(algorithm: string) => algorithm is SRIHashAlgorithm}
|
||||
* @param {*} algorithm
|
||||
* @returns {algorithm is SRIHashAlgorithm}
|
||||
*/
|
||||
|
||||
const isValidSRIHashAlgorithm = /** @type {IsValidSRIHashAlgorithm} */ (
|
||||
Map.prototype.has.bind(validSRIHashAlgorithmTokenSet)
|
||||
)
|
||||
const isValidSRIHashAlgorithm = (algorithm) => validSRIHashAlgorithmTokenSet.has(asciiLowercase(algorithm))
|
||||
|
||||
/**
|
||||
* @param {Uint8Array} bytes
|
||||
@@ -64691,7 +64937,8 @@ function parseMetadata (metadata) {
|
||||
// 8. Let metadata be the ordered map
|
||||
// «["alg" → algorithm, "val" → base64-value]».
|
||||
const metadata = {
|
||||
alg: algorithm,
|
||||
// Possible spec bug?
|
||||
alg: asciiLowercase(algorithm),
|
||||
val: base64Value
|
||||
}
|
||||
|
||||
@@ -67109,6 +67356,19 @@ class ByteParser extends Writable {
|
||||
if (isControlFrame(this.#info.opcode)) {
|
||||
this.#loop = this.parseControlFrame(body)
|
||||
this.#state = parserStates.INFO
|
||||
|
||||
// If the automatic PONG/CLOSE reply filled the socket's write buffer,
|
||||
// stop parsing and resume on drain so a PING flood cannot grow the
|
||||
// outbound queue without bound.
|
||||
if (this.#loop && this.#handler.socket.writableNeedDrain) {
|
||||
this.#loop = false
|
||||
this.#handler.socket.once('drain', () => {
|
||||
if (this.destroyed) return
|
||||
this.#loop = true
|
||||
this.run(callback)
|
||||
})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (!this.#info.compressed) {
|
||||
if (!this.writeFragments(body)) {
|
||||
|
||||
+298
-38
@@ -33621,18 +33621,24 @@ const SessionCache = class WeakSessionCache {
|
||||
if (this._sessionCache.has(sessionKey)) {
|
||||
this._sessionCache.delete(sessionKey)
|
||||
} else if (this._sessionCache.size >= this._maxCachedSessions) {
|
||||
// Make room for the new session: prefer an entry whose session has
|
||||
// already been collected, otherwise evict the oldest one.
|
||||
let evicted = false
|
||||
for (const [key, ref] of this._sessionCache) {
|
||||
if (ref.deref() === undefined) {
|
||||
this._sessionCache.delete(key)
|
||||
return
|
||||
evicted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!evicted) {
|
||||
const oldest = this._sessionCache.keys().next()
|
||||
if (!oldest.done) {
|
||||
this._sessionCache.delete(oldest.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._sessionCache.set(sessionKey, new WeakRef(session))
|
||||
this._sessionRegistry.register(session, sessionKey)
|
||||
@@ -35760,6 +35766,7 @@ module.exports = {
|
||||
kDestroy: Symbol('destroy'),
|
||||
kDispatch: Symbol('dispatch'),
|
||||
kUrl: Symbol('url'),
|
||||
kRedirectCacheControl: Symbol('redirect cache control'),
|
||||
kWriting: Symbol('writing'),
|
||||
kResuming: Symbol('resuming'),
|
||||
kQueue: Symbol('queue'),
|
||||
@@ -37028,7 +37035,7 @@ function defaultFactory (origin, opts) {
|
||||
}
|
||||
|
||||
class Agent extends DispatcherBase {
|
||||
constructor ({ factory = defaultFactory, maxOrigins = Infinity, connect, ...options } = {}) {
|
||||
constructor ({ factory = defaultFactory, maxOrigins = Infinity, connect, tls, ...options } = {}) {
|
||||
if (typeof factory !== 'function') {
|
||||
throw new InvalidArgumentError('factory must be a function.')
|
||||
}
|
||||
@@ -37047,7 +37054,11 @@ class Agent extends DispatcherBase {
|
||||
connect = { ...connect }
|
||||
}
|
||||
|
||||
this[kOptions] = { ...util.deepClone(options), maxOrigins, connect }
|
||||
if (tls && typeof tls !== 'function') {
|
||||
tls = { ...tls }
|
||||
}
|
||||
|
||||
this[kOptions] = { ...util.deepClone(options), maxOrigins, connect, tls }
|
||||
this[kFactory] = factory
|
||||
this[kClients] = new Map()
|
||||
this[kOrigins] = new Set()
|
||||
@@ -38329,8 +38340,6 @@ function connectH1 (client, socket) {
|
||||
}
|
||||
|
||||
function onHttpSocketError (err) {
|
||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
||||
|
||||
const parser = this[kParser]
|
||||
|
||||
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
|
||||
@@ -39448,8 +39457,6 @@ function onHttp2SendPing (session) {
|
||||
}
|
||||
|
||||
function onHttp2SessionError (err) {
|
||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
||||
|
||||
this[kSocket][kError] = err
|
||||
this[kClient][kOnError](err)
|
||||
}
|
||||
@@ -39591,8 +39598,6 @@ function onHttp2SocketClose () {
|
||||
}
|
||||
|
||||
function onHttp2SocketError (err) {
|
||||
assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
|
||||
|
||||
this[kError] = err
|
||||
|
||||
this[kClient][kOnError](err)
|
||||
@@ -40338,7 +40343,8 @@ class Client extends DispatcherBase {
|
||||
initialWindowSize,
|
||||
connectionWindowSize,
|
||||
pingInterval,
|
||||
webSocket
|
||||
webSocket,
|
||||
eventSource
|
||||
} = {}) {
|
||||
if (keepAlive !== undefined) {
|
||||
throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
|
||||
@@ -40446,7 +40452,7 @@ class Client extends DispatcherBase {
|
||||
throw new InvalidArgumentError('pingInterval must be a positive integer, greater or equal to 0')
|
||||
}
|
||||
|
||||
super({ webSocket })
|
||||
super({ webSocket, eventSource })
|
||||
|
||||
if (typeof connect !== 'function') {
|
||||
connect = buildConnector({
|
||||
@@ -40899,6 +40905,7 @@ module.exports = Client
|
||||
"use strict";
|
||||
|
||||
|
||||
const buffer = __nccwpck_require__(4573)
|
||||
const Dispatcher = __nccwpck_require__(30883)
|
||||
const UnwrapHandler = __nccwpck_require__(92365)
|
||||
const {
|
||||
@@ -40911,6 +40918,7 @@ const { kDestroy, kClose, kClosed, kDestroyed, kDispatch } = __nccwpck_require__
|
||||
const kOnDestroyed = Symbol('onDestroyed')
|
||||
const kOnClosed = Symbol('onClosed')
|
||||
const kWebSocketOptions = Symbol('webSocketOptions')
|
||||
const kEventSourceOptions = Symbol('eventSourceOptions')
|
||||
|
||||
class DispatcherBase extends Dispatcher {
|
||||
/** @type {boolean} */
|
||||
@@ -40931,6 +40939,7 @@ class DispatcherBase extends Dispatcher {
|
||||
constructor (opts) {
|
||||
super()
|
||||
this[kWebSocketOptions] = opts?.webSocket ?? {}
|
||||
this[kEventSourceOptions] = opts?.eventSource ?? {}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40943,6 +40952,15 @@ class DispatcherBase extends Dispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {import('../../types/client').Client.EventSourceOptions}
|
||||
*/
|
||||
get eventSourceOptions () {
|
||||
return {
|
||||
maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
get destroyed () {
|
||||
return this[kDestroyed]
|
||||
@@ -42743,6 +42761,7 @@ module.exports = {
|
||||
|
||||
|
||||
const util = __nccwpck_require__(3440)
|
||||
const { kRedirectCacheControl } = __nccwpck_require__(36443)
|
||||
const {
|
||||
parseCacheControlHeader,
|
||||
hasInvalidCacheControlDirective,
|
||||
@@ -42755,6 +42774,19 @@ const { parseHttpDate } = __nccwpck_require__(25453)
|
||||
|
||||
function noop () {}
|
||||
|
||||
/**
|
||||
* @param {string | URL} a
|
||||
* @param {string | URL} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function sameOrigin (a, b) {
|
||||
try {
|
||||
return new URL(String(a)).origin === new URL(String(b)).origin
|
||||
} catch {
|
||||
return String(a) === String(b)
|
||||
}
|
||||
}
|
||||
|
||||
// Status codes that we can use some heuristics on to cache
|
||||
const HEURISTICALLY_CACHEABLE_STATUS_CODES = [
|
||||
200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501
|
||||
@@ -42893,6 +42925,14 @@ class CacheHandler {
|
||||
*/
|
||||
#writeStream
|
||||
|
||||
/**
|
||||
* The URLs visited while following redirects, shared by reference from the
|
||||
* redirect handler through the request context. Carries the suppressed hops'
|
||||
* cache-control under {@link kRedirectCacheControl}.
|
||||
* @type {URL[] | undefined}
|
||||
*/
|
||||
#history
|
||||
|
||||
/**
|
||||
* @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} opts
|
||||
* @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey
|
||||
@@ -42909,6 +42949,9 @@ class CacheHandler {
|
||||
onRequestStart (controller, context) {
|
||||
this.#writeStream?.destroy()
|
||||
this.#writeStream = undefined
|
||||
// The redirect handler mutates this shared history as redirects are
|
||||
// followed, allowing the cache to identify the response's actual origin.
|
||||
this.#history = context?.history
|
||||
this.#handler.onRequestStart?.(controller, context)
|
||||
}
|
||||
|
||||
@@ -42948,6 +42991,29 @@ class CacheHandler {
|
||||
return downstreamOnHeaders()
|
||||
}
|
||||
|
||||
// Never store a response produced by a different origin under the original
|
||||
// request's cache key.
|
||||
if (this.#history && this.#history.length > 0) {
|
||||
const finalUrl = this.#history[this.#history.length - 1]
|
||||
if (!sameOrigin(finalUrl.origin, this.#cacheKey.origin)) {
|
||||
return downstreamOnHeaders()
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve restrictive cache policy from suppressed redirect responses.
|
||||
const redirectCacheControl = this.#history?.[kRedirectCacheControl]
|
||||
if (redirectCacheControl) {
|
||||
for (const hopCacheControl of redirectCacheControl) {
|
||||
const hopDirectives = hopCacheControl ? parseCacheControlHeader(hopCacheControl) : {}
|
||||
if (
|
||||
hopDirectives['no-store'] === true ||
|
||||
(this.#cacheType === 'shared' && hopDirectives.private === true)
|
||||
) {
|
||||
return downstreamOnHeaders()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const cacheControlHeader = resHeaders['cache-control']
|
||||
const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {}
|
||||
|
||||
@@ -43749,6 +43815,7 @@ const DEFAULT_MAX_BUFFER_SIZE = 5 * 1024 * 1024
|
||||
* @property {number} bufferedBytes
|
||||
* @property {object | null} pendingTrailers
|
||||
* @property {boolean} done
|
||||
* @property {boolean} [pendingStart] onRequestStart deferred until the primary request's context is known
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43763,6 +43830,20 @@ class DeduplicationHandler {
|
||||
*/
|
||||
#primaryHandler
|
||||
|
||||
/**
|
||||
* Whether the primary request has started (onRequestStart received). Until
|
||||
* then the request context is unknown and cannot be given to waiting handlers.
|
||||
* @type {boolean}
|
||||
*/
|
||||
#requestStarted = false
|
||||
|
||||
/**
|
||||
* The primary request context, replayed to waiting handlers so they observe
|
||||
* the same redirect history as the primary.
|
||||
* @type {any}
|
||||
*/
|
||||
#context = null
|
||||
|
||||
/**
|
||||
* @type {WaitingHandler[]}
|
||||
*/
|
||||
@@ -43845,7 +43926,10 @@ class DeduplicationHandler {
|
||||
const waitingController = waitingHandler.controller
|
||||
|
||||
try {
|
||||
handler.onRequestStart?.(waitingController, null)
|
||||
if (this.#requestStarted) {
|
||||
// The primary request has started, so its context (including the
|
||||
// redirect history) is known and can be delivered immediately.
|
||||
handler.onRequestStart?.(waitingController, this.#context)
|
||||
|
||||
if (waitingController.aborted) {
|
||||
waitingHandler.done = true
|
||||
@@ -43860,6 +43944,13 @@ class DeduplicationHandler {
|
||||
this.#statusMessage
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// The primary request has not started yet. Defer onRequestStart until
|
||||
// its context is known, so the waiting handler observes the same
|
||||
// redirect history as the primary (a cache handler relies on it to
|
||||
// reject cross-origin redirect responses).
|
||||
waitingHandler.pendingStart = true
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors from waiting handlers
|
||||
waitingHandler.done = true
|
||||
@@ -43879,6 +43970,24 @@ class DeduplicationHandler {
|
||||
*/
|
||||
onRequestStart (controller, context) {
|
||||
this.#controller = controller
|
||||
if (!this.#requestStarted) {
|
||||
this.#requestStarted = true
|
||||
this.#context = context
|
||||
// Deliver the now-known context to handlers that joined before the
|
||||
// primary request started.
|
||||
for (const waitingHandler of this.#waitingHandlers) {
|
||||
if (waitingHandler.pendingStart && !waitingHandler.done && !waitingHandler.controller.aborted) {
|
||||
waitingHandler.pendingStart = false
|
||||
try {
|
||||
waitingHandler.handler.onRequestStart?.(waitingHandler.controller, context)
|
||||
} catch {
|
||||
// Ignore errors from waiting handlers
|
||||
waitingHandler.done = true
|
||||
}
|
||||
}
|
||||
}
|
||||
this.#pruneDoneWaitingHandlers()
|
||||
}
|
||||
this.#primaryHandler.onRequestStart?.(controller, context)
|
||||
}
|
||||
|
||||
@@ -44052,7 +44161,8 @@ class DeduplicationHandler {
|
||||
bufferedChunks: [],
|
||||
bufferedBytes: 0,
|
||||
pendingTrailers: null,
|
||||
done: false
|
||||
done: false,
|
||||
pendingStart: false
|
||||
}
|
||||
|
||||
const state = {
|
||||
@@ -44202,7 +44312,7 @@ module.exports = DeduplicationHandler
|
||||
|
||||
|
||||
const util = __nccwpck_require__(3440)
|
||||
const { kBodyUsed } = __nccwpck_require__(36443)
|
||||
const { kBodyUsed, kRedirectCacheControl } = __nccwpck_require__(36443)
|
||||
const assert = __nccwpck_require__(34589)
|
||||
const { InvalidArgumentError } = __nccwpck_require__(68707)
|
||||
const EE = __nccwpck_require__(78474)
|
||||
@@ -44248,6 +44358,11 @@ class RedirectHandler {
|
||||
this.maxRedirections = maxRedirections
|
||||
this.handler = handler
|
||||
this.history = []
|
||||
// Retain cache-control from suppressed redirect hops for an outer cache.
|
||||
Object.defineProperty(this.history, kRedirectCacheControl, {
|
||||
value: [],
|
||||
enumerable: false
|
||||
})
|
||||
|
||||
if (util.isStream(this.opts.body)) {
|
||||
// TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
|
||||
@@ -44331,6 +44446,8 @@ class RedirectHandler {
|
||||
return
|
||||
}
|
||||
|
||||
this.history[kRedirectCacheControl].push(headers['cache-control'])
|
||||
|
||||
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)))
|
||||
const path = search ? `${pathname}${search}` : pathname
|
||||
|
||||
@@ -46035,10 +46152,15 @@ class DecompressHandler extends DecoratorHandler {
|
||||
this.#decompressedSize = decompressedSize
|
||||
}
|
||||
|
||||
try {
|
||||
const result = super.onResponseData(this.#controller, chunk)
|
||||
if (result === false && !this.#controller.paused) {
|
||||
this.#controller.pause()
|
||||
}
|
||||
} catch (err) {
|
||||
this.#fail(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
} while (this.#drainRequested && !this.#terminated && !this.#controller.paused)
|
||||
} finally {
|
||||
@@ -46054,9 +46176,14 @@ class DecompressHandler extends DecoratorHandler {
|
||||
return
|
||||
}
|
||||
|
||||
this.#terminated = true
|
||||
this.#cleanupDecompressors()
|
||||
try {
|
||||
super.onResponseEnd(this.#controller, this.#trailers)
|
||||
} catch (err) {
|
||||
this.#fail(err)
|
||||
return
|
||||
}
|
||||
this.#terminated = true
|
||||
}
|
||||
|
||||
#onDecompressionEnd () {
|
||||
@@ -53701,8 +53828,10 @@ function getCookies (headers) {
|
||||
|
||||
const cookie = headers.get('cookie')
|
||||
|
||||
// A null prototype keeps a cookie named `__proto__` from hitting the
|
||||
// Object.prototype setter, which would silently drop it.
|
||||
/** @type {Record<string, string>} */
|
||||
const out = {}
|
||||
const out = { __proto__: null }
|
||||
|
||||
if (!cookie) {
|
||||
return out
|
||||
@@ -53968,6 +54097,7 @@ function parseSetCookie (header) {
|
||||
* @param {Object.<string, unknown>} [cookieAttributeList={}]
|
||||
*/
|
||||
function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) {
|
||||
while (true) {
|
||||
// 1. If the unparsed-attributes string is empty, skip the rest of
|
||||
// these steps.
|
||||
if (unparsedAttributes.length === 0) {
|
||||
@@ -54036,7 +54166,7 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
||||
// 6. If the attribute-value is longer than 1024 octets, ignore the
|
||||
// cookie-av string and return to Step 1 of this algorithm.
|
||||
if (attributeValue.length > maxAttributeValueSize) {
|
||||
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList)
|
||||
continue
|
||||
}
|
||||
|
||||
// 7. Process the attribute-name and attribute-value according to the
|
||||
@@ -54066,13 +54196,13 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
||||
const charCode = attributeValue.charCodeAt(0)
|
||||
|
||||
if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') {
|
||||
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList)
|
||||
continue
|
||||
}
|
||||
|
||||
// 2. If the remainder of attribute-value contains a non-DIGIT
|
||||
// character, ignore the cookie-av.
|
||||
if (!/^\d+$/.test(attributeValue)) {
|
||||
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList)
|
||||
continue
|
||||
}
|
||||
|
||||
// 3. Let delta-seconds be the attribute-value converted to an integer.
|
||||
@@ -54181,7 +54311,7 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
|
||||
}
|
||||
|
||||
// 8. Return to Step 1 of this algorithm.
|
||||
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -54513,9 +54643,28 @@ function stringify (cookie) {
|
||||
out.push(`Path=${cookie.path}`)
|
||||
}
|
||||
|
||||
if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') {
|
||||
// A numeric 0 is the Unix epoch, not an absent value -- the same reason the
|
||||
// Max-Age check above tests the type rather than truthiness.
|
||||
//
|
||||
// expires is Date | number, so the "Invalid Date" check only guards the Date
|
||||
// form. A number that is not a valid time value (NaN, +/-Infinity, or outside
|
||||
// the Date range) would otherwise reach toIMFDate, which splices undefined and
|
||||
// NaN into the header value instead of failing.
|
||||
if (cookie.expires != null) {
|
||||
const expiresMs = cookie.expires instanceof Date
|
||||
? cookie.expires.getTime()
|
||||
: cookie.expires
|
||||
|
||||
// The largest time value a Date can represent, in milliseconds, i.e.
|
||||
// 100,000,000 days either side of the epoch (ECMA-262 Date Time Values).
|
||||
// Anything within it is safe for toIMFDate to format; anything beyond it
|
||||
// produces an invalid Date and must be ignored instead.
|
||||
const maxTimeValue = 8640000000000000
|
||||
|
||||
if (typeof expiresMs === 'number' && Number.isFinite(expiresMs) && Math.abs(expiresMs) <= maxTimeValue) {
|
||||
out.push(`Expires=${toIMFDate(cookie.expires)}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (cookie.sameSite) {
|
||||
out.push(`SameSite=${cookie.sameSite}`)
|
||||
@@ -54557,6 +54706,7 @@ module.exports = {
|
||||
|
||||
"use strict";
|
||||
|
||||
const buffer = __nccwpck_require__(4573)
|
||||
const { Transform } = __nccwpck_require__(57075)
|
||||
const { isASCIINumber, isValidLastEventId } = __nccwpck_require__(94811)
|
||||
|
||||
@@ -54581,11 +54731,19 @@ const COLON = 0x3A
|
||||
*/
|
||||
const SPACE = 0x20
|
||||
|
||||
const defaultMaxEventSize = buffer.kStringMaxLength
|
||||
|
||||
const DATA = Buffer.from('data')
|
||||
const EVENT = Buffer.from('event')
|
||||
const ID = Buffer.from('id')
|
||||
const RETRY = Buffer.from('retry')
|
||||
|
||||
// Each data field creates a string node, and each unconsumed input chunk keeps
|
||||
// a Buffer wrapper. The absolute ceiling protects the large default byte limit.
|
||||
const minParserItems = 1024
|
||||
const maxParserItems = 131072
|
||||
const bytesPerParserItem = 128
|
||||
|
||||
function isASCIINumberBytes (buffer, start) {
|
||||
if (start >= buffer.length) {
|
||||
return false
|
||||
@@ -54624,6 +54782,12 @@ function isFieldName (line, length, field) {
|
||||
return true
|
||||
}
|
||||
|
||||
function createMaxEventSizeExceededError () {
|
||||
const error = new Error('EventSource message size exceeded')
|
||||
error.aborted = false
|
||||
return error
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} EventSourceStreamEvent
|
||||
* @type {object}
|
||||
@@ -54672,6 +54836,13 @@ class EventSourceStream extends Transform {
|
||||
pos = 0
|
||||
lineChunkIndex = 0
|
||||
linePos = 0
|
||||
lineLength = 0
|
||||
eventSize = 0
|
||||
eventFieldSizes = { data: 0, event: 0, id: 0, retry: 0 }
|
||||
dataLineCount = 0
|
||||
maxEventSize
|
||||
maxDataLines
|
||||
maxBufferedChunks
|
||||
|
||||
event = {
|
||||
data: undefined,
|
||||
@@ -54683,6 +54854,7 @@ class EventSourceStream extends Transform {
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {boolean} [options.readableObjectMode]
|
||||
* @param {number} [options.maxEventSize]
|
||||
* @param {eventSourceSettings} [options.eventSourceSettings]
|
||||
* @param {(chunk: any, encoding?: BufferEncoding | undefined) => boolean} [options.push]
|
||||
*/
|
||||
@@ -54694,6 +54866,12 @@ class EventSourceStream extends Transform {
|
||||
super(options)
|
||||
|
||||
this.state = options.eventSourceSettings || {}
|
||||
this.maxEventSize = options.maxEventSize ?? defaultMaxEventSize
|
||||
const parserItemLimit = this.maxEventSize > 0
|
||||
? Math.min(maxParserItems, Math.max(minParserItems, Math.floor(this.maxEventSize / bytesPerParserItem)))
|
||||
: 0
|
||||
this.maxDataLines = parserItemLimit
|
||||
this.maxBufferedChunks = parserItemLimit
|
||||
if (options.push) {
|
||||
this.push = options.push
|
||||
}
|
||||
@@ -54711,6 +54889,14 @@ class EventSourceStream extends Transform {
|
||||
return
|
||||
}
|
||||
|
||||
// A leading line ending can immediately release the currently buffered
|
||||
// line, even when it uses the final allowed chunk slot.
|
||||
if (this.maxEventSize > 0 &&
|
||||
this.chunks.length >= this.maxBufferedChunks &&
|
||||
chunk[0] !== LF && chunk[0] !== CR) {
|
||||
callback(createMaxEventSizeExceededError())
|
||||
return
|
||||
}
|
||||
this.chunks.push(chunk)
|
||||
|
||||
// Strip leading byte-order-mark if we opened the stream and started
|
||||
@@ -54789,7 +54975,12 @@ class EventSourceStream extends Transform {
|
||||
|
||||
// In any case, we can process the line as we reached an
|
||||
// end-of-line character
|
||||
try {
|
||||
this.parseLine(this.readLine(), this.event)
|
||||
} catch (error) {
|
||||
callback(error)
|
||||
return
|
||||
}
|
||||
this.consumeCurrentByte()
|
||||
// A line was processed and this could be the end of the event. We need
|
||||
// to check if the next line is empty to determine if the event is
|
||||
@@ -54798,12 +54989,25 @@ class EventSourceStream extends Transform {
|
||||
continue
|
||||
}
|
||||
|
||||
// readLine() is only called after CR or LF. Reject an unfinished line
|
||||
// before it can retain an unbounded number of decoded chunks. The seven
|
||||
// extra bytes allow the longest field prefix ("event: " or "retry: ").
|
||||
if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) {
|
||||
callback(createMaxEventSizeExceededError())
|
||||
return
|
||||
}
|
||||
this.advanceCursor()
|
||||
}
|
||||
|
||||
callback()
|
||||
}
|
||||
|
||||
_destroy (error, callback) {
|
||||
this.chunks.length = 0
|
||||
this.clearEvent()
|
||||
super._destroy(error, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Buffer} line
|
||||
* @param {EventSourceStreamEvent} event
|
||||
@@ -54840,6 +55044,13 @@ class EventSourceStream extends Transform {
|
||||
}
|
||||
|
||||
if (isFieldName(line, fieldLength, DATA)) {
|
||||
if (this.maxEventSize > 0 && this.dataLineCount >= this.maxDataLines) {
|
||||
throw createMaxEventSizeExceededError()
|
||||
}
|
||||
const valueBytes = line.length - valueStart
|
||||
const dataSize = this.eventFieldSizes.data + (event.data === undefined ? 0 : 1) + valueBytes
|
||||
this.setEventFieldSize('data', dataSize)
|
||||
|
||||
const value = line.toString('utf8', valueStart)
|
||||
|
||||
if (event.data === undefined) {
|
||||
@@ -54847,11 +55058,13 @@ class EventSourceStream extends Transform {
|
||||
} else {
|
||||
event.data += `\n${value}`
|
||||
}
|
||||
this.dataLineCount++
|
||||
return
|
||||
}
|
||||
|
||||
if (isFieldName(line, fieldLength, RETRY)) {
|
||||
if (isASCIINumberBytes(line, valueStart)) {
|
||||
this.setEventFieldSize('retry', line.length - valueStart)
|
||||
event.retry = line.toString('utf8', valueStart)
|
||||
}
|
||||
return
|
||||
@@ -54859,18 +55072,27 @@ class EventSourceStream extends Transform {
|
||||
|
||||
if (isFieldName(line, fieldLength, ID)) {
|
||||
if (isValidLastEventIdBytes(line, valueStart)) {
|
||||
this.setEventFieldSize('id', line.length - valueStart)
|
||||
event.id = line.toString('utf8', valueStart)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (isFieldName(line, fieldLength, EVENT)) {
|
||||
const value = line.toString('utf8', valueStart)
|
||||
if (valueStart < line.length) {
|
||||
this.setEventFieldSize('event', line.length - valueStart)
|
||||
event.event = line.toString('utf8', valueStart)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.length > 0) {
|
||||
event.event = value
|
||||
}
|
||||
setEventFieldSize (field, size) {
|
||||
const eventSize = this.eventSize - this.eventFieldSizes[field] + size
|
||||
if (this.maxEventSize > 0 && eventSize > this.maxEventSize) {
|
||||
throw createMaxEventSizeExceededError()
|
||||
}
|
||||
this.eventSize = eventSize
|
||||
this.eventFieldSizes[field] = size
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54903,6 +55125,12 @@ class EventSourceStream extends Transform {
|
||||
this.event.event = undefined
|
||||
this.event.id = undefined
|
||||
this.event.retry = undefined
|
||||
this.eventSize = 0
|
||||
this.dataLineCount = 0
|
||||
this.eventFieldSizes.data = 0
|
||||
this.eventFieldSizes.event = 0
|
||||
this.eventFieldSizes.id = 0
|
||||
this.eventFieldSizes.retry = 0
|
||||
}
|
||||
|
||||
hasPendingEvent () {
|
||||
@@ -54938,14 +55166,16 @@ class EventSourceStream extends Transform {
|
||||
syncLineStartToCursor () {
|
||||
this.lineChunkIndex = this.chunkIndex
|
||||
this.linePos = this.pos
|
||||
this.lineLength = 0
|
||||
this.dropConsumedChunks()
|
||||
}
|
||||
|
||||
dropConsumedChunks () {
|
||||
while (this.lineChunkIndex > 0) {
|
||||
this.chunks.shift()
|
||||
this.lineChunkIndex--
|
||||
this.chunkIndex--
|
||||
if (this.lineChunkIndex > 0) {
|
||||
const consumed = this.lineChunkIndex
|
||||
this.chunks.splice(0, consumed)
|
||||
this.lineChunkIndex = 0
|
||||
this.chunkIndex -= consumed
|
||||
}
|
||||
|
||||
if (this.chunkIndex === this.chunks.length) {
|
||||
@@ -55070,6 +55300,7 @@ const { createFastMessageEvent } = __nccwpck_require__(15188)
|
||||
const { isNetworkError } = __nccwpck_require__(99051)
|
||||
const { kEnumerableProperty } = __nccwpck_require__(3440)
|
||||
const { environmentSettingsObject } = __nccwpck_require__(73168)
|
||||
const { getGlobalDispatcher } = __nccwpck_require__(32581)
|
||||
|
||||
let experimentalWarned = false
|
||||
|
||||
@@ -55352,6 +55583,7 @@ class EventSource extends EventTarget {
|
||||
|
||||
const eventSourceStream = new EventSourceStream({
|
||||
eventSourceSettings: this.#state,
|
||||
maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize,
|
||||
push: (event) => {
|
||||
this.dispatchEvent(createFastMessageEvent(
|
||||
event.type,
|
||||
@@ -55536,7 +55768,8 @@ webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([
|
||||
},
|
||||
{
|
||||
key: 'dispatcher', // undici only
|
||||
converter: webidl.converters.any
|
||||
converter: webidl.converters.any,
|
||||
defaultValue: () => getGlobalDispatcher()
|
||||
},
|
||||
{
|
||||
key: 'node', // undici only
|
||||
@@ -60717,8 +60950,6 @@ async function httpNetworkFetch (
|
||||
}
|
||||
const location = headersList.get('location', true)
|
||||
|
||||
this.body = new Readable({ read: resume })
|
||||
|
||||
const willFollow = location && request.redirect === 'follow' &&
|
||||
redirectStatusSet.has(status)
|
||||
|
||||
@@ -60736,7 +60967,7 @@ async function httpNetworkFetch (
|
||||
// CVE fix similar to urllib3 (GHSA-gm62-xv2j-4w53) and curl (CVE-2022-32206).
|
||||
const maxContentEncodings = 5
|
||||
if (codings.length > maxContentEncodings) {
|
||||
reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`))
|
||||
this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`))
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -60774,6 +61005,8 @@ async function httpNetworkFetch (
|
||||
}
|
||||
}
|
||||
|
||||
this.body = new Readable({ read: resume })
|
||||
|
||||
const onError = this.onError.bind(this)
|
||||
|
||||
resolve({
|
||||
@@ -64277,6 +64510,19 @@ function collectASequenceOfCodePointsFast (char, input, position) {
|
||||
}
|
||||
|
||||
const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g // eslint-disable-line no-control-regex
|
||||
const nonASCIIRegex = /[^\x00-\x7F]/ // eslint-disable-line no-control-regex
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*
|
||||
* @see https://infra.spec.whatwg.org/#ascii-lowercase
|
||||
*/
|
||||
function asciiLowercase (str) {
|
||||
return nonASCIIRegex.test(str)
|
||||
? str.replace(/[A-Z]+/g, (upper) => upper.toLowerCase())
|
||||
: str.toLowerCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
@@ -64441,6 +64687,7 @@ function serializeJavascriptValueToJSONString (value) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
asciiLowercase,
|
||||
collectASequenceOfCodePoints,
|
||||
collectASequenceOfCodePointsFast,
|
||||
forgivingBase64,
|
||||
@@ -64464,6 +64711,7 @@ module.exports = {
|
||||
|
||||
const assert = __nccwpck_require__(34589)
|
||||
const { runtimeFeatures } = __nccwpck_require__(313)
|
||||
const { asciiLowercase } = __nccwpck_require__(8116)
|
||||
|
||||
/**
|
||||
* @typedef {object} Metadata
|
||||
@@ -64528,14 +64776,12 @@ const getSRIHashAlgorithmIndex = /** @type {GetSRIHashAlgorithmIndex} */ (Map.pr
|
||||
|
||||
/**
|
||||
* @typedef IsValidSRIHashAlgorithm
|
||||
* @see https://w3c.github.io/webappsec-subresource-integrity/#valid-sri-hash-algorithm-token
|
||||
* @type {(algorithm: string) => algorithm is SRIHashAlgorithm}
|
||||
* @param {*} algorithm
|
||||
* @returns {algorithm is SRIHashAlgorithm}
|
||||
*/
|
||||
|
||||
const isValidSRIHashAlgorithm = /** @type {IsValidSRIHashAlgorithm} */ (
|
||||
Map.prototype.has.bind(validSRIHashAlgorithmTokenSet)
|
||||
)
|
||||
const isValidSRIHashAlgorithm = (algorithm) => validSRIHashAlgorithmTokenSet.has(asciiLowercase(algorithm))
|
||||
|
||||
/**
|
||||
* @param {Uint8Array} bytes
|
||||
@@ -64691,7 +64937,8 @@ function parseMetadata (metadata) {
|
||||
// 8. Let metadata be the ordered map
|
||||
// «["alg" → algorithm, "val" → base64-value]».
|
||||
const metadata = {
|
||||
alg: algorithm,
|
||||
// Possible spec bug?
|
||||
alg: asciiLowercase(algorithm),
|
||||
val: base64Value
|
||||
}
|
||||
|
||||
@@ -67109,6 +67356,19 @@ class ByteParser extends Writable {
|
||||
if (isControlFrame(this.#info.opcode)) {
|
||||
this.#loop = this.parseControlFrame(body)
|
||||
this.#state = parserStates.INFO
|
||||
|
||||
// If the automatic PONG/CLOSE reply filled the socket's write buffer,
|
||||
// stop parsing and resume on drain so a PING flood cannot grow the
|
||||
// outbound queue without bound.
|
||||
if (this.#loop && this.#handler.socket.writableNeedDrain) {
|
||||
this.#loop = false
|
||||
this.#handler.socket.once('drain', () => {
|
||||
if (this.destroyed) return
|
||||
this.#loop = true
|
||||
this.run(callback)
|
||||
})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (!this.#info.compressed) {
|
||||
if (!this.writeFragments(body)) {
|
||||
|
||||
Generated
+3
-3
@@ -4233,9 +4233,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "7.30.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.30.0.tgz",
|
||||
"integrity": "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==",
|
||||
"version": "7.30.1",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.30.1.tgz",
|
||||
"integrity": "sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
|
||||
Reference in New Issue
Block a user