From ee783ce31419f5358bc8328fb11c4db4617606b1 Mon Sep 17 00:00:00 2001 From: Kat Cosgrove Date: Mon, 19 Oct 2026 17:25:09 -0600 Subject: [PATCH 1/3] add optional delay for blunderbuss, docs Signed-off-by: Kat Cosgrove --- __tests__/cronJobTest/sweep.test.ts | 81 ++ __tests__/plugins/blunderbuss.test.ts | 17 + dist/index.js | 981 +++++++++++++++++------ docs/configuration.md | 16 + docs/cron-jobs.md | 2 +- package-lock.json | 1026 +++++++++++++------------ src/cronJobs/sweep.ts | 100 ++- src/plugins/blunderbuss.ts | 10 + src/utils/config.ts | 20 + 9 files changed, 1515 insertions(+), 738 deletions(-) diff --git a/__tests__/cronJobTest/sweep.test.ts b/__tests__/cronJobTest/sweep.test.ts index 37a24b2c..c6e394e0 100644 --- a/__tests__/cronJobTest/sweep.test.ts +++ b/__tests__/cronJobTest/sweep.test.ts @@ -33,6 +33,7 @@ interface PullSpec { labels?: string[] draft?: boolean requested_reviewers?: string[] + requested_teams?: string[] head?: string mergeable_state?: string user?: string @@ -51,6 +52,7 @@ function pull(spec: PullSpec) { created_at: spec.created ?? spec.updated ?? ago(10 * 60_000), updated_at: spec.updated ?? ago(10 * 60_000), requested_reviewers: (spec.requested_reviewers ?? []).map(login => ({ login })), + requested_teams: (spec.requested_teams ?? []).map(slug => ({ slug })), assignees: [], user: { login: spec.user ?? 'some-author' }, head: { sha: spec.head ?? `sha${spec.number}` }, @@ -112,6 +114,9 @@ describe('resolveSweepLookback', () => { ['a non-string lookback', 'sweep:\n lookback: 3600\n', 'x: sweep.lookback must be a duration string such as 1h or 30m'], ['a malformed lookback', 'sweep:\n lookback: soon\n', 'x: invalid sweep.lookback \'soon\': expected a duration such as 5s, 2m or 500ms'], ['a zero lookback', 'sweep:\n lookback: \'0\'\n', 'x: sweep.lookback must be longer than 0'], + ['a non-string blunderbuss.delay', 'blunderbuss:\n delay: 3600\n', 'x: blunderbuss.delay must be a duration string such as 1h or 30m'], + ['a malformed blunderbuss.delay', 'blunderbuss:\n delay: later\n', 'x: invalid blunderbuss.delay \'later\': expected a duration such as 5s, 2m or 500ms'], + ['a blunderbuss.delay over 24h', 'blunderbuss:\n delay: 25h\n', 'x: blunderbuss.delay must not be longer than 24h'], ])('rejects %s', (_, text, error) => { expect(() => parseProwConfig('x', text)).toThrow(error) }) @@ -440,6 +445,82 @@ describe('sweep on a repository with OWNERS files', () => { }) }) +describe('sweep with blunderbuss.delay', () => { + const owners = { OWNERS: 'approvers:\n- alice\nreviewers:\n- carol\n' } + + function serve(specs: PullSpec[], timelines: Record = {}, reviewed: number[] = []) { + const tree = Object.keys(owners).map(path => ({ path, type: 'blob', sha: blobSha(path) })) + const requested: number[] = [] + const timelineReads: number[] = [] + server.use( + prowYaml('blunderbuss:\n delay: 1h\n'), + utils.defaultBranchTree(Object.keys(owners)), + http.get(`${repo}/git/trees/basesha`, utils.mockResponse(200, { sha: 'basesha', truncated: false, tree })), + http.get(`${repo}/pulls/:number/files`, utils.mockResponse(200, [{ filename: 'x.go', status: 'modified' }])), + ...Object.entries(owners).map(([path, contents]) => http.get(`${repo}/git/blobs/${blobSha(path)}`, utils.mockResponse(200, { encoding: 'base64', content: Buffer.from(contents).toString('base64') }))), + http.get(`${repo}/issues/:number`, utils.mockResponse(200, { labels: [] })), + http.get(`${repo}/issues/:number/comments`, utils.mockResponse(200, [])), + http.post(`${repo}/issues/:number/comments`, utils.mockResponse(201, {})), + http.get(`${repo}/issues/:number/timeline`, ({ params }) => { + timelineReads.push(Number(params.number)) + return json((timelines[Number(params.number)] ?? []).map(at => ({ event: 'ready_for_review', created_at: at }))) + }), + http.get(`${repo}/pulls/:number/reviews`, ({ params }) => json(reviewed.includes(Number(params.number)) ? [{ id: 1, state: 'COMMENTED', user: { login: 'carol' } }] : [])), + http.post(`${repo}/pulls/:number/requested_reviewers`, ({ params }) => { + requested.push(Number(params.number)) + return json({}, 201) + }), + utils.repoHasLabels(['approved', 'lgtm']), + ) + servePulls(specs) + return { requested, timelineReads } + } + + it('requests on a pull request opened an hour ago that nobody touched since, outside the normal window', async () => { + const { requested } = serve([{ number: 1, created: ago(70 * 60_000), updated: ago(70 * 60_000) }]) + + await expect(sweep(context)).resolves.toEqual({ candidates: [], merged: [], enqueued: [], failures: [] }) + expect(requested).toEqual([1]) + }) + + it('does not request before the delay has passed, nor after the due window', async () => { + const { requested, timelineReads } = serve([ + { number: 1, created: ago(30 * 60_000), updated: ago(30 * 60_000) }, + { number: 2, created: ago(3 * hour), updated: ago(90 * 60_000) }, + ]) + + await expect(sweep(context)).resolves.toMatchObject({ failures: [] }) + expect(requested).toEqual([]) + // #1 is not due yet: no timeline read; #2 was opened long ago and never marked ready + expect(timelineReads).toEqual([2]) + }) + + it('leaves alone a pull request with a requested reviewer, a requested team, a review or that is a draft', async () => { + const { requested } = serve([ + { number: 1, created: ago(70 * 60_000), updated: ago(70 * 60_000), requested_reviewers: ['bob'] }, + { number: 2, created: ago(70 * 60_000), updated: ago(70 * 60_000), requested_teams: ['sdk'] }, + { number: 3, created: ago(70 * 60_000), updated: ago(70 * 60_000) }, + { number: 4, created: ago(70 * 60_000), updated: ago(70 * 60_000), draft: true }, + ], {}, [3]) + + await expect(sweep(context)).resolves.toMatchObject({ failures: [] }) + expect(requested).toEqual([]) + }) + + it('times a former draft from its last ready_for_review', async () => { + const { requested } = serve([ + { number: 1, created: ago(5 * hour), updated: ago(70 * 60_000) }, + { number: 2, created: ago(70 * 60_000), updated: ago(10 * 60_000) }, + ], { + 1: [ago(4 * hour), ago(70 * 60_000)], + 2: [ago(10 * 60_000)], + }) + + await expect(sweep(context)).resolves.toMatchObject({ candidates: [2], failures: [] }) + expect(requested).toEqual([1]) + }) +}) + describe('sweep and the ok-to-test label', () => { function serveRuns(runs: unknown[], approved: number[]) { server.use( diff --git a/__tests__/plugins/blunderbuss.test.ts b/__tests__/plugins/blunderbuss.test.ts index 7a659513..2483bffd 100644 --- a/__tests__/plugins/blunderbuss.test.ts +++ b/__tests__/plugins/blunderbuss.test.ts @@ -122,9 +122,14 @@ describe('blunderbussSettings', () => { exclude_approvers: false, ignore_drafts: true, ignore_authors: [], + delay: 0, }) }) + it('reads delay as milliseconds', () => { + expect(blunderbussSettings({ labels: {}, require_matching_label: [], tide: {}, hold: {}, blunderbuss: { delay: '1h30m' }, sources: [] }).delay).toBe(90 * 60_000) + }) + it('lowercases ignore_authors', () => { expect(blunderbussSettings({ labels: {}, require_matching_label: [], tide: {}, hold: {}, blunderbuss: { ignore_authors: ['Dependabot[bot]'] }, sources: [] }).ignore_authors).toEqual(['dependabot[bot]']) }) @@ -225,6 +230,18 @@ describe('blunderbuss handler', () => { expect(debug).toHaveBeenCalledWith('blunderbuss: #1 is a draft, waiting for ready_for_review') }) + it.each(['opened', 'ready_for_review'])('delay: %s requests nobody and leaves it to the sweep job', async (action) => { + serveConfig('blunderbuss:\n delay: 1h\n') + servePr(owners, ['sdk/x.go']) + const observe = observeRequestReviewers() + const info = vi.spyOn(core, 'info').mockImplementation(() => {}) + + await blunderbuss(prEvent(action), first) + + await expect(observe.notCalled()).resolves.toBe('not called') + expect(info).toHaveBeenCalledWith(`blunderbuss: #1 ${action}; blunderbuss.delay is set, so the sweep job requests reviewers once it is due and nobody has been asked`) + }) + it('ready_for_review: requests reviewers for the former draft', async () => { serveConfig() servePr(owners, ['sdk/x.go']) diff --git a/dist/index.js b/dist/index.js index 6b20c354..602c3173 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,7 +1,7 @@ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ -/***/ 4844: +/***/ 9659: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -55,7 +55,7 @@ exports.getProxyUrl = getProxyUrl; exports.isHttps = isHttps; const http = __importStar(__nccwpck_require__(8611)); const https = __importStar(__nccwpck_require__(5692)); -const pm = __importStar(__nccwpck_require__(4988)); +const pm = __importStar(__nccwpck_require__(3335)); const tunnel = __importStar(__nccwpck_require__(770)); const undici_1 = __nccwpck_require__(6752); var HttpCodes; @@ -745,7 +745,7 @@ const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCa /***/ }), -/***/ 4988: +/***/ 3335: /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -4102,11 +4102,77 @@ class Request { } } - onUpgrade (statusCode, headers, socket) { + /** + * @param {number|null} statusCode + * @param {Buffer[]|null} headers + * @param {import('node:stream').Duplex} socket + * @param {string} [statusText] + */ + onUpgrade (statusCode, headers, socket, statusText = '') { + this.onFinally() + assert(!this.aborted) assert(!this.completed) - return this[kHandler].onUpgrade(statusCode, headers, socket) + if (statusCode !== null) { + this.#publishUpgradeHeaders(statusCode, headers, statusText) + } + + const result = this[kHandler].onUpgrade(statusCode, headers, socket) + + if (!this.aborted) { + this.completed = true + if (statusCode !== null) { + this.#publishUpgradeTrailers() + } + } + + return result + } + + /** + * @param {number} statusCode + * @param {import('node:http2').IncomingHttpHeaders} headers + * @param {(headers: import('node:http2').IncomingHttpHeaders) => Buffer[]} parseHeaders + * @param {string} [statusText] + */ + onUpgradeResponse (statusCode, headers, parseHeaders, statusText = '') { + assert(!this.aborted) + assert(this.completed) + + if (channels.headers.hasSubscribers) { + this.#publishUpgradeHeaders(statusCode, parseHeaders(headers), statusText) + } + this.#publishUpgradeTrailers() + } + + /** + * @param {Error} error + */ + onUpgradeError (error) { + assert(!this.aborted) + assert(this.completed) + + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error }) + } + } + + /** + * @param {number} statusCode + * @param {Buffer[]} headers + * @param {string} statusText + */ + #publishUpgradeHeaders (statusCode, headers, statusText) { + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) + } + } + + #publishUpgradeTrailers () { + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers: [] }) + } } onComplete (trailers) { @@ -5247,7 +5313,7 @@ function defaultFactory (origin, opts) { } class Agent extends DispatcherBase { - constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor ({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== 'function') { throw new InvalidArgumentError('factory must be a function.') } @@ -5266,11 +5332,15 @@ class Agent extends DispatcherBase { connect = { ...connect } } + if (tls && typeof tls !== 'function') { + tls = { ...tls } + } + this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })] - this[kOptions] = { ...util.deepClone(options), connect } + this[kOptions] = { ...util.deepClone(options), connect, tls } this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : undefined @@ -6010,7 +6080,7 @@ class Parser { } onUpgrade (head) { - const { upgrade, client, socket, headers, statusCode } = this + const { upgrade, client, socket, headers, statusCode, statusText } = this assert(upgrade) assert(client[kSocket] === socket) @@ -6045,9 +6115,10 @@ class Parser { client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) try { - request.onUpgrade(statusCode, headers, socket) - } catch (err) { - util.destroy(socket, err) + request.onUpgrade(statusCode, headers, socket, statusText) + } catch (error) { + util.errorRequest(client, request, error) + util.destroy(socket, error) } client[kResume]() @@ -6304,8 +6375,6 @@ async function connectH1 (client, socket) { socket[kParser] = new Parser(client, socket, llhttpInstance) addListener(socket, 'error', function (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 @@ -6628,12 +6697,22 @@ function writeH1 (client, request) { const socket = client[kSocket] clearIdleSocketValidation(socket) - const abort = (err) => { - if (request.aborted || request.completed) { + /** + * @param {Error} [error] + */ + const abort = (error) => { + if (request.aborted) { + return + } + + if (request.completed) { + if (request.upgrade || request.method === 'CONNECT') { + util.destroy(socket, new InformationalError('aborted')) + } return } - util.errorRequest(client, request, err || new RequestAbortedError()) + util.errorRequest(client, request, error || new RequestAbortedError()) util.destroy(body) util.destroy(socket, new InformationalError('aborted')) @@ -7091,6 +7170,7 @@ module.exports = connectH1 const assert = __nccwpck_require__(4589) +const { errorMonitor } = __nccwpck_require__(8474) const { pipeline } = __nccwpck_require__(7075) const util = __nccwpck_require__(3440) const { @@ -7167,6 +7247,15 @@ function parseH2Headers (headers) { return result } +/** + * @param {import('node:http2').IncomingHttpHeaders} headers + * @returns {Buffer[]} + */ +function parseH2ResponseHeaders (headers) { + const { [HTTP2_HEADER_STATUS]: _statusCode, ...realHeaders } = headers + return parseH2Headers(realHeaders) +} + async function connectH2 (client, socket) { client[kSocket] = socket @@ -7216,8 +7305,6 @@ async function connectH2 (client, socket) { socket[kHTTP2Session] = session util.addListener(socket, 'error', function (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') - this[kError] = err this[kClient][kOnError](err) @@ -7291,8 +7378,6 @@ function resumeH2 (client) { } function onHttp2SessionError (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') - this[kSocket][kError] = err this[kClient][kOnError](err) } @@ -7387,22 +7472,32 @@ function writeH2 (client, request) { headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ''}` headers[HTTP2_HEADER_METHOD] = method - const abort = (err) => { - if (request.aborted || request.completed) { + /** + * @param {Error} [error] + */ + const abort = (error) => { + if (request.aborted) { + return + } + + if (request.completed) { + if (method === 'CONNECT' && stream != null) { + util.destroy(stream, error || new RequestAbortedError()) + } return } - err = err || new RequestAbortedError() + error = error || new RequestAbortedError() - util.errorRequest(client, request, err) + util.errorRequest(client, request, error) if (stream != null) { - util.destroy(stream, err) + util.destroy(stream, error) } // We do not destroy the socket as we can continue using the session // the stream get's destroyed and the session remains to create new streams - util.destroy(body, err) + util.destroy(body, error) client[kQueue][client[kRunningIdx]++] = null client[kResume]() } @@ -7421,25 +7516,57 @@ function writeH2 (client, request) { if (method === 'CONNECT') { session.ref() - // We are already connected, streams are pending, first request - // will create a new stream. We trigger a request to create the stream and wait until - // `ready` event is triggered // We disabled endStream to allow the user to write to the stream stream = session.request(headers, { endStream: false, signal }) + let upgradeResponseFinished = false - if (stream.id && !stream.pending) { - request.onUpgrade(null, null, stream) - ++session[kOpenStreams] - client[kQueue][client[kRunningIdx]++] = null - } else { - stream.once('ready', () => { + /** + * @param {import('node:http2').IncomingHttpHeaders} headers + */ + const onResponse = (headers) => { + upgradeResponseFinished = true + stream.off(errorMonitor, onUpgradeError) + request.onUpgradeResponse(Number(headers[HTTP2_HEADER_STATUS]), headers, parseH2ResponseHeaders) + } + + /** + * @param {Error} error + */ + const onUpgradeError = (error) => { + upgradeResponseFinished = true + stream.off('response', onResponse) + request.onUpgradeError(error) + } + + const onReady = () => { + try { request.onUpgrade(null, null, stream) - ++session[kOpenStreams] - client[kQueue][client[kRunningIdx]++] = null - }) + } catch (error) { + stream.off('response', onResponse) + abort(error) + return + } + + if (request.aborted) { + return + } + + stream.off('error', abort) + stream.once(errorMonitor, onUpgradeError) + client[kQueue][client[kRunningIdx]++] = null } + stream.once('response', onResponse) + stream.once('error', abort) + ++session[kOpenStreams] + onReady() + stream.once('close', () => { + if (!upgradeResponseFinished && request.completed) { + stream.off('response', onResponse) + stream.off(errorMonitor, onUpgradeError) + request.onUpgradeError(new InformationalError(`HTTP/2: "stream error" received - code ${stream.rstCode}`)) + } session[kOpenStreams] -= 1 if (session[kOpenStreams] === 0) session.unref() }) @@ -7949,9 +8076,10 @@ class Client extends DispatcherBase { // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }) + super({ webSocket, eventSource }) if (keepAlive !== undefined) { throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') @@ -8473,6 +8601,7 @@ module.exports = Client "use strict"; +const buffer = __nccwpck_require__(4573) const Dispatcher = __nccwpck_require__(883) const { ClientDestroyedError, @@ -8485,6 +8614,7 @@ const kOnDestroyed = Symbol('onDestroyed') const kOnClosed = Symbol('onClosed') const kInterceptedDispatch = Symbol('Intercepted Dispatch') const kWebSocketOptions = Symbol('webSocketOptions') +const kEventSourceOptions = Symbol('eventSourceOptions') class DispatcherBase extends Dispatcher { constructor (opts) { @@ -8495,6 +8625,7 @@ class DispatcherBase extends Dispatcher { this[kClosed] = false this[kOnClosed] = [] this[kWebSocketOptions] = opts?.webSocket ?? {} + this[kEventSourceOptions] = opts?.eventSource ?? {} } get webSocketOptions () { @@ -8504,6 +8635,12 @@ class DispatcherBase extends Dispatcher { } } + get eventSourceOptions () { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + } + } + get destroyed () { return this[kDestroyed] } @@ -10266,7 +10403,10 @@ class RetryHandler { this.retryCount += 1 if (statusCode >= 300) { - if (this.retryOpts.statusCodes.includes(statusCode) === false) { + // Only expose a response if no earlier attempt has reached the caller. + // Otherwise abort this attempt so the error settles the existing body + // instead of replacing it with a new response. + if (!this.headersSent && this.retryOpts.statusCodes.includes(statusCode) === false) { this.headersSent = true this.checkpointResponseEnd(headers, resume) return this.handler.onHeaders( @@ -14898,6 +15038,7 @@ module.exports = { "use strict"; +const buffer = __nccwpck_require__(4573) const { Transform } = __nccwpck_require__(7075) const { isASCIINumber, isValidLastEventId } = __nccwpck_require__(4811) @@ -14922,11 +15063,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 @@ -14965,6 +15114,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} @@ -15013,6 +15168,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, @@ -15023,6 +15185,7 @@ class EventSourceStream extends Transform { /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -15034,6 +15197,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 } @@ -15051,6 +15220,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 @@ -15129,7 +15306,12 @@ class EventSourceStream extends Transform { // In any case, we can process the line as we reached an // end-of-line character - this.parseLine(this.readLine(), this.event) + 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 @@ -15138,15 +15320,28 @@ 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 {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine (line, event) { // If the line is empty (a blank line) @@ -15180,6 +15375,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) { @@ -15187,11 +15389,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 @@ -15199,20 +15403,29 @@ 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 (value.length > 0) { - event.event = value + if (valueStart < line.length) { + this.setEventFieldSize('event', line.length - valueStart) + event.event = line.toString('utf8', valueStart) } } } + 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 + } + /** * @param {EventSourceStreamEvent} event */ @@ -15243,6 +15456,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 () { @@ -15278,14 +15497,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) { @@ -15411,6 +15632,7 @@ const { isNetworkError } = __nccwpck_require__(9051) const { delay } = __nccwpck_require__(4811) const { kEnumerableProperty } = __nccwpck_require__(3440) const { environmentSettingsObject } = __nccwpck_require__(3168) +const { getGlobalDispatcher } = __nccwpck_require__(2581) let experimentalWarned = false @@ -15692,6 +15914,7 @@ class EventSource extends EventTarget { const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -15870,7 +16093,8 @@ webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([ }, { key: 'dispatcher', // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]) @@ -20977,8 +21201,10 @@ async function httpNetworkFetch ( // 19. Run these steps in parallel: // 1. Run these steps, but abort when fetchParams is canceled: - fetchParams.controller.onAborted = onAborted - fetchParams.controller.on('terminated', onAborted) + if (!fetchParams.controller.resume) { + fetchParams.controller.on('terminated', onAborted) + } + fetchParams.controller.resume = async () => { // 1. While true while (true) { @@ -21147,8 +21373,6 @@ async function httpNetworkFetch ( } location = headersList.get('location', true) - this.body = new Readable({ read: resume }) - const decoders = [] const willFollow = location && request.redirect === 'follow' && @@ -21166,7 +21390,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 } @@ -21199,6 +21423,8 @@ async function httpNetworkFetch ( } } + this.body = new Readable({ read: resume }) + const onError = this.onError.bind(this) resolve({ @@ -21245,10 +21471,6 @@ async function httpNetworkFetch ( fetchParams.controller.off('terminated', this.abort) } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off('terminated', fetchParams.controller.onAborted) - } - fetchParams.controller.ended = true this.body.push(null) @@ -27739,6 +27961,20 @@ 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. + const socket = this.ws[kResponse].socket + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false + socket.once('drain', () => { + if (this.destroyed) return + this.#loop = true + this.run(callback) + }) + return + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -29540,7 +29776,7 @@ const external_path_namespaceObject = require("path"); var external_http_ = __nccwpck_require__(8611); // EXTERNAL MODULE: external "https" var external_https_ = __nccwpck_require__(5692); -;// CONCATENATED MODULE: ./node_modules/@actions/core/node_modules/@actions/http-client/lib/proxy.js +;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/proxy.js function getProxyUrl(reqUrl) { const usingSsl = reqUrl.protocol === 'https:'; if (checkBypass(reqUrl)) { @@ -29635,7 +29871,7 @@ class DecodedURL extends URL { var node_modules_tunnel = __nccwpck_require__(770); // EXTERNAL MODULE: ./node_modules/undici/index.js var undici = __nccwpck_require__(6752); -;// CONCATENATED MODULE: ./node_modules/@actions/core/node_modules/@actions/http-client/lib/index.js +;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/index.js /* eslint-disable @typescript-eslint/no-explicit-any */ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } @@ -30332,7 +30568,7 @@ class lib_HttpClient { } const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); //# sourceMappingURL=index.js.map -;// CONCATENATED MODULE: ./node_modules/@actions/core/node_modules/@actions/http-client/lib/auth.js +;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/auth.js var auth_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -32363,8 +32599,8 @@ class Context { } } //# sourceMappingURL=context.js.map -// EXTERNAL MODULE: ./node_modules/@actions/http-client/lib/index.js -var lib = __nccwpck_require__(4844); +// EXTERNAL MODULE: ./node_modules/@actions/github/node_modules/@actions/http-client/lib/index.js +var lib = __nccwpck_require__(9659); ;// CONCATENATED MODULE: ./node_modules/@actions/github/lib/internal/utils.js var utils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } @@ -32930,20 +33166,44 @@ var endpoint = withDefaults(null, DEFAULTS); * Copyright(c) 2015 Douglas Christopher Wilson * MIT Licensed */ -const TEXT_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]*$/; -const TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; -/** - * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4 - */ -const QUOTE_REGEXP = /[\\"]/g; +const SP = 32; // " " +const HTAB = 9; // "\t" +const SEMI = 59; // ";" +const EQ = 61; // "=" +const DQUOTE = 34; // '"' +const BSLASH = 92; // "\\" +const COMMA = 44; // "," +const LOWER_CASE = 1; +const OWS = 2; +const SEMI_FLAG = 4; +const COMMA_FLAG = 8; +const TOKEN_FLAG = 16; +const NON_ASCII = 0xff00; +const CASE_FLAGS = LOWER_CASE | NON_ASCII; /** - * RegExp to match type in RFC 9110 sec 8.3.1 - * - * media-type = type "/" subtype - * type = token - * subtype = token + * Character flags used to normalize HTTP field values while scanning. + * Out-of-range reads intentionally coerce to zero in bitwise expressions. */ -const TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; +const CHAR_MAP = new Uint8Array(0x100); +CHAR_MAP[HTAB] |= OWS; +CHAR_MAP[SP] |= OWS; +CHAR_MAP[SEMI] |= SEMI_FLAG; +CHAR_MAP[COMMA] |= COMMA_FLAG; +for (let code = 0x80 /* non-ASCII */; code <= 0xff; code++) { + CHAR_MAP[code] |= LOWER_CASE; +} +for (const char of "!#$%&'*+-.^_`|~") { + CHAR_MAP[char.charCodeAt(0)] |= TOKEN_FLAG; +} +for (let code = 0x30 /* 0 */; code <= 0x39 /* 9 */; code++) { + CHAR_MAP[code] |= TOKEN_FLAG; +} +for (let code = 0x41 /* A */; code <= 0x5a /* Z */; code++) { + CHAR_MAP[code] |= LOWER_CASE | TOKEN_FLAG; +} +for (let code = 0x61 /* a */; code <= 0x7a /* z */; code++) { + CHAR_MAP[code] |= TOKEN_FLAG; +} /** * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`. */ @@ -32952,21 +33212,84 @@ const NullObject = /* @__PURE__ */ (() => { C.prototype = Object.create(null); return C; })(); +/** + * Validate a type string against RFC 9110. + */ +function isTypeValid(type, start = 0, end = type.length) { + let hasSlash = false; + for (let index = start; index < end; index++) { + const code = type.charCodeAt(index); + if (code === 47 /* / */) { + if (hasSlash || index === start || index >= end - 1) + return false; + hasSlash = true; + } + else if (!isTokenCode(code)) { + return false; + } + } + return hasSlash; +} +/** + * Validate a token against RFC 9110. + */ +function isTokenValid(token, start = 0, end = token.length) { + if (start >= end) + return false; + for (let index = start; index < end; index++) { + if (!isTokenCode(token.charCodeAt(index))) + return false; + } + return true; +} +/** + * Check whether a character code belongs to the token production in RFC 9110. + */ +function isTokenCode(code) { + return (CHAR_MAP[code] & TOKEN_FLAG) !== 0; +} +/** + * Serialize a parameter value. + */ +function parameterValue(str) { + const len = str.length; + if (len === 0) + return '""'; + let index = 0; + while (index < len && isTokenCode(str.charCodeAt(index))) + index++; + if (index === len) + return str; + let result = '"'; + let start = 0; + while (index < len) { + const code = str.charCodeAt(index); + if (code !== HTAB && (code < SP || code === 127 || code > 255)) { + throw new TypeError(`Invalid parameter value: ${str}`); + } + if (code === 34 /* " */ || code === 92 /* \\ */) { + result += `${str.slice(start, index)}\\`; + start = index; + } + index++; + } + return `${result}${str.slice(start)}"`; +} /** * Format an object into a `Content-Type` header. */ function format(obj) { const { type, parameters } = obj; - if (!type || !TYPE_REGEXP.test(type)) { + if (!type || !isTypeValid(type)) { throw new TypeError(`Invalid type: ${type}`); } let result = type; if (parameters) { for (const param of Object.keys(parameters)) { - if (!TOKEN_REGEXP.test(param)) { + if (!isTokenValid(param)) { throw new TypeError(`Invalid parameter name: ${param}`); } - result += `; ${param}=${qstring(parameters[param])}`; + result += `; ${param}=${parameterValue(parameters[param])}`; } } return result; @@ -32975,126 +33298,158 @@ function format(obj) { * Parse a `Content-Type` header. */ function dist_parse(header, options) { - const stopChar = options?.comma === true ? COMMA : 65_536; // Sentinel for "no stop char". + const stopFlags = SEMI_FLAG | (options?.comma === true ? COMMA_FLAG : 0); const len = header.length; - let index = skipOWS(header, options?.start ?? 0, len); - const valueStart = index; - index = skipValue(header, index, len, stopChar); - const valueEnd = trailingOWS(header, valueStart, index); - const type = header.slice(valueStart, valueEnd).toLowerCase(); - if (options?.parameters === false) { + let valueStart = options?.start ?? 0; + while ((CHAR_MAP[header.charCodeAt(valueStart)] & OWS) !== 0) { + valueStart++; + } + let index = valueStart; + let typeFlags = 0; + let whitespace = -1; + let stop = options?.parameters === false ? COMMA_FLAG : 0; + while (index < len) { + const code = header.charCodeAt(index); + const flags = CHAR_MAP[code]; + if ((flags & stopFlags) !== 0) { + stop |= flags & COMMA_FLAG; + break; + } + if ((flags & OWS) !== 0) { + if (whitespace === -1) + whitespace = index; + } + else { + whitespace = -1; + } + typeFlags |= (code & NON_ASCII) | flags; + index++; + } + const valueEnd = whitespace === -1 ? index : whitespace; + const value = header.slice(valueStart, valueEnd); + const type = (typeFlags & CASE_FLAGS) === 0 ? value : value.toLowerCase(); + if (index === len || stop !== 0) { return { type, index, parameters: new NullObject() }; } - return parseParameters(header, type, index, len, stopChar); + return parseParameters(header, type, index, len, stopFlags); } -const SP = 32; // " " -const HTAB = 9; // "\t" -const SEMI = 59; // ";" -const EQ = 61; // "=" -const DQUOTE = 34; // '"' -const BSLASH = 92; // "\\" -const COMMA = 44; // "," /** * Parses the parameters of a `Content-Type` header starting at the given index. */ -function parseParameters(header, type, index, len, stopChar) { +function parseParameters(header, type, index, len, stopFlags) { const parameters = new NullObject(); parameter: while (index < len) { - if (header.charCodeAt(index) === stopChar) - break; - index = skipOWS(header, index + 1 /* Skip over ; */, len); + index++; // Skip over ; + while ((CHAR_MAP[header.charCodeAt(index)] & OWS) !== 0) { + index++; + } const keyStart = index; + let keyFlags = 0; + let keyWhitespace = -1; while (index < len) { const code = header.charCodeAt(index); - if (code === stopChar) - break parameter; - if (code === SEMI) + const flags = CHAR_MAP[code]; + if ((flags & stopFlags) !== 0) { + if ((flags & COMMA_FLAG) !== 0) + break parameter; continue parameter; + } if (code === EQ) { - const keyEnd = trailingOWS(header, keyStart, index); - const key = header.slice(keyStart, keyEnd).toLowerCase(); - index = skipOWS(header, index + 1, len); - if (index < len && header.charCodeAt(index) === DQUOTE) { + const keyEnd = keyWhitespace === -1 ? index : keyWhitespace; + const value = header.slice(keyStart, keyEnd); + const key = (keyFlags & CASE_FLAGS) === 0 ? value : value.toLowerCase(); + index++; + while ((CHAR_MAP[header.charCodeAt(index)] & OWS) !== 0) { index++; - let value = ""; + } + if (index < len && header.charCodeAt(index) === DQUOTE) { + const quotedStart = ++index; + let escaped = false; while (index < len) { - const code = header.charCodeAt(index++); + const code = header.charCodeAt(index); if (code === DQUOTE) { - index = skipValue(header, index, len, stopChar); - if (parameters[key] === undefined) - parameters[key] = value; - break; + if (parameters[key] === undefined) { + parameters[key] = escaped + ? unescapeQuotedPairs(header, quotedStart, index) + : header.slice(quotedStart, index); + } + index++; + let stop = 0; + // Discard characters between quote and delimiter. + while (index < len) { + const code = header.charCodeAt(index); + const flags = CHAR_MAP[code]; + if ((flags & stopFlags) !== 0) { + stop = flags & COMMA_FLAG; + break; + } + index++; + } + if (stop !== 0) + break parameter; + continue parameter; } - if (code === BSLASH && index < len) { - value += header[index++]; + if (code === BSLASH && index + 1 < len) { + escaped = true; + index += 2; continue; } - value += String.fromCharCode(code); + index++; } continue parameter; } const valueStart = index; - index = skipValue(header, index, len, stopChar); + let stop = 0; + let valueWhitespace = -1; + while (index < len) { + const code = header.charCodeAt(index); + const flags = CHAR_MAP[code]; + if ((flags & stopFlags) !== 0) { + stop = flags & COMMA_FLAG; + break; + } + if ((flags & OWS) !== 0) { + if (valueWhitespace === -1) + valueWhitespace = index; + } + else { + valueWhitespace = -1; + } + index++; + } if (parameters[key] === undefined) { - const valueEnd = trailingOWS(header, valueStart, index); + const valueEnd = valueWhitespace === -1 ? index : valueWhitespace; parameters[key] = header.slice(valueStart, valueEnd); } + if (stop !== 0) + break parameter; continue parameter; } + if ((flags & OWS) !== 0) { + if (keyWhitespace === -1) + keyWhitespace = index; + } + else { + keyWhitespace = -1; + } + keyFlags |= (code & NON_ASCII) | flags; index++; } } return { type, index, parameters }; } /** - * Skip over characters until a semicolon or other exit character. - */ -function skipValue(str, index, len, stopChar) { - while (index < len) { - const code = str.charCodeAt(index); - if (code === SEMI || code === stopChar) - break; - index++; - } - return index; -} -/** - * Skip optional whitespace (OWS) in an HTTP header value. - * - * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t"). - */ -function skipOWS(header, index, len) { - while (index < len) { - const char = header.charCodeAt(index); - if (char !== SP && char !== HTAB) - break; - index++; - } - return index; -} -/** - * Trim optional whitespace (OWS) from the end of a substring. - * - * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t"). + * Remove backslashes from quoted pairs in a known-terminated quoted string body. */ -function trailingOWS(header, start, end) { - while (end > start) { - const char = header.charCodeAt(end - 1); - if (char !== SP && char !== HTAB) - break; - end--; +function unescapeQuotedPairs(str, start, end) { + let result = ""; + for (let index = start; index < end; index++) { + if (str.charCodeAt(index) === BSLASH) { + result += str.slice(start, index); + start = ++index; + } } - return end; -} -/** - * Serialize a parameter value. - */ -function qstring(str) { - if (TOKEN_REGEXP.test(str)) - return str; - if (TEXT_REGEXP.test(str)) - return `"${str.replace(QUOTE_REGEXP, "\\$&")}"`; - throw new TypeError(`Invalid parameter value: ${str}`); + return result + str.slice(start, end); } //# sourceMappingURL=index.js.map ;// CONCATENATED MODULE: ./node_modules/json-with-bigint/json-with-bigint.js @@ -37192,7 +37547,7 @@ function getOctokit(token, options, ...additionalPlugins) { // EXTERNAL MODULE: external "node:buffer" var external_node_buffer_ = __nccwpck_require__(4573); ;// CONCATENATED MODULE: ./node_modules/js-yaml/dist/js-yaml.mjs -/*! js-yaml 5.4.3 https://github.com/nodeca/js-yaml @license MIT */ +/*! js-yaml 5.5.0 https://github.com/nodeca/js-yaml @license MIT */ //#region src/tag.ts /** * Returned by a scalar resolver when the source does not match its tag. @@ -38018,10 +38373,8 @@ var Schema = class Schema { if (tag.matchByTagPrefix) prefix.sequence.push(tag); else exact.sequence[tag.tagName] = tag; break; - case "mapping": - if (tag.matchByTagPrefix) prefix.mapping.push(tag); - else exact.mapping[tag.tagName] = tag; - break; + case "mapping": if (tag.matchByTagPrefix) prefix.mapping.push(tag); + else exact.mapping[tag.tagName] = tag; } } const implicitScalarAnyFirstChar = implicitScalarTags.filter((tag) => tag.implicitFirstChars === null); @@ -38609,16 +38962,17 @@ function getBlockValue(input, start, end, indent, chomping, folded) { } const content = line.slice(textIndent); const first = content.charCodeAt(0); - if (folded) if (first === 32 || first === 9) { - atMoreIndented = true; - result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); - } else if (atMoreIndented) { - atMoreIndented = false; - result += "\n".repeat(emptyLines + 1); - } else if (emptyLines === 0) { - if (didReadContent) result += " "; - } else result += "\n".repeat(emptyLines); - else result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); + if (folded) { + if (first === 32 || first === 9) { + atMoreIndented = true; + result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); + } else if (atMoreIndented) { + atMoreIndented = false; + result += "\n".repeat(emptyLines + 1); + } else if (emptyLines === 0) { + if (didReadContent) result += " "; + } else result += "\n".repeat(emptyLines); + } else result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); result += content; didReadContent = true; emptyLines = 0; @@ -38652,24 +39006,69 @@ var DEFAULT_TAG_HANDLERS = Object.assign(Object.create(null), { "!": "!", "!!": "tag:yaml.org,2002:" }); -function tagPercentEncode(source) { - return encodeURI(source).replace(/!/g, "%21"); +var TAG_SUFFIX_CHARS = "-#;/?:@&=+$_.~*'()"; +var TAG_URI_CHARS = TAG_SUFFIX_CHARS + "!,[]"; +var HEX = "0123456789ABCDEF"; +function percentByte(byte) { + return "%" + HEX[byte >> 4] + HEX[byte & 15]; +} +function tagPercentEncode(source, isSuffix) { + const allowed = isSuffix ? TAG_SUFFIX_CHARS : TAG_URI_CHARS; + let result = ""; + for (let index = 0; index < source.length; index++) { + let ch = source.charCodeAt(index); + if (ch >= 48 && ch <= 57 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || allowed.includes(source[index])) { + result += source[index]; + continue; + } + if (ch >= 55296 && ch <= 56319) ch = 65536 + ((ch & 1023) << 10) + (source.charCodeAt(++index) & 1023); + if (ch < 128) result += percentByte(ch); + else if (ch < 2048) result += percentByte(192 | ch >> 6) + percentByte(128 | ch & 63); + else if (ch < 65536) result += percentByte(224 | ch >> 12) + percentByte(128 | ch >> 6 & 63) + percentByte(128 | ch & 63); + else result += percentByte(240 | ch >> 18) + percentByte(128 | ch >> 12 & 63) + percentByte(128 | ch >> 6 & 63) + percentByte(128 | ch & 63); + } + return result; +} +function tagPercentDecode(source) { + let result = ""; + let index = 0; + while (index < source.length) { + if (source.charCodeAt(index) !== 37) { + result += source[index++]; + continue; + } + let ch = parseInt(source.slice(index + 1, index + 3), 16); + index += 3; + if (ch >= 192) { + let remaining = ch < 224 ? 1 : ch < 240 ? 2 : 3; + ch &= (1 << 6 - remaining) - 1; + while (remaining-- > 0) { + ch = ch << 6 | parseInt(source.slice(index + 1, index + 3), 16) & 63; + index += 3; + } + } + if (ch < 65536) result += String.fromCharCode(ch); + else { + ch -= 65536; + result += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023); + } + } + return result; } function tagNameFull(rawTag, tagHandlers) { - if (rawTag.startsWith("!<") && rawTag.endsWith(">")) return decodeURIComponent(rawTag.slice(2, -1)); + if (rawTag.startsWith("!<") && rawTag.endsWith(">")) return tagPercentDecode(rawTag.slice(2, -1)); const handleEnd = rawTag.indexOf("!", 1); const handle = handleEnd === -1 ? "!" : rawTag.slice(0, handleEnd + 1); - const prefix = tagHandlers?.[handle] ?? DEFAULT_TAG_HANDLERS[handle] ?? handle; - return decodeURIComponent(prefix) + decodeURIComponent(rawTag.slice(handle.length)); + return tagPercentDecode(tagHandlers?.[handle] ?? DEFAULT_TAG_HANDLERS[handle] ?? handle) + tagPercentDecode(rawTag.slice(handle.length)); } function tagNameShort(fullTag) { let tag = fullTag; if (tag.charCodeAt(0) === 33) { tag = tag.slice(1); - return `!${tagPercentEncode(tag)}`; + return `!${tagPercentEncode(tag, true)}`; } - if (tag.slice(0, 18) === "tag:yaml.org,2002:") return `!!${tagPercentEncode(tag.slice(18))}`; - return `!<${tagPercentEncode(tag)}>`; + if (tag.slice(0, 18) === "tag:yaml.org,2002:") return `!!${tagPercentEncode(tag.slice(18), true)}`; + return `!<${tagPercentEncode(tag, false)}>`; } //#endregion //#region src/parser/constructor.ts @@ -39142,7 +39541,11 @@ function skipUntilLineEnd(state) { while (ch !== 0 && !isEol(ch)) ch = state.input.charCodeAt(++state.position); } function checkPrintable(state, start, end) { - if (PATTERN_NON_PRINTABLE.test(state.input.slice(start, end))) throwError(state, "the stream contains non-printable characters"); + const match = PATTERN_NON_PRINTABLE.exec(state.input.slice(start, end)); + if (match !== null) { + state.position = start + match.index + match[0].length - 1; + throwError(state, "the stream contains non-printable characters"); + } } function readTagProperty(state, props, inFlow) { if (state.input.charCodeAt(state.position) !== 33) return false; @@ -39169,12 +39572,14 @@ function readTagProperty(state, props, inFlow) { state.position++; } else { while (ch !== 0 && !isWsOrEol(ch) && !(inFlow && isFlowIndicator(ch))) { - if (ch === 33) if (!isNamed) { - tagHandle = state.input.slice(suffixStart - 1, state.position + 1); - if (!PATTERN_TAG_HANDLE.test(tagHandle)) throwError(state, "named tag handle cannot contain such characters"); - isNamed = true; - suffixStart = state.position + 1; - } else throwError(state, "tag suffix cannot contain exclamation marks"); + if (ch === 33) { + if (!isNamed) { + tagHandle = state.input.slice(suffixStart - 1, state.position + 1); + if (!PATTERN_TAG_HANDLE.test(tagHandle)) throwError(state, "named tag handle cannot contain such characters"); + isNamed = true; + suffixStart = state.position + 1; + } else throwError(state, "tag suffix cannot contain exclamation marks"); + } ch = state.input.charCodeAt(++state.position); } tagName = state.input.slice(suffixStart, state.position); @@ -39358,7 +39763,7 @@ function readBlockScalar(state, parentIndent, props) { function canStartPlainScalar(state, nodeContext) { const ch = state.input.charCodeAt(state.position); const inFlow = nodeContext === CONTEXT_FLOW_IN; - if (ch === 0 || isWsOrEol(ch) || ch === 35 || ch === 38 || ch === 42 || ch === 33 || ch === 124 || ch === 62 || ch === 39 || ch === 34 || ch === 37 || ch === 64 || ch === 96 || inFlow && isFlowIndicator(ch)) return false; + if (ch === 0 || isWsOrEol(ch) || ch === 35 || ch === 38 || ch === 42 || ch === 33 || ch === 124 || ch === 62 || ch === 39 || ch === 34 || ch === 37 || ch === 64 || ch === 96 || isFlowIndicator(ch)) return false; if (ch === 63 || ch === 45) { const following = state.input.charCodeAt(state.position + 1); if (isWsOrEolOrEnd(following) || inFlow && isFlowIndicator(following)) return false; @@ -39630,19 +40035,20 @@ function parseNode(state, parentIndent, nodeContext, allowToSeek, allowCompact, if (indentStatus === 1 || nodeContext === CONTEXT_BLOCK_OUT) { const flowIndent = nodeContext === CONTEXT_FLOW_IN || nodeContext === CONTEXT_FLOW_OUT ? parentIndent : parentIndent + 1; const blockIndent = state.position - state.lineStart; - if (indentStatus === 1) if (allowBlockCollections && (readBlockSequence(state, blockIndent, props) || readBlockMapping(state, blockIndent, flowIndent, props)) || readFlowCollection(state, flowIndent, props)) hasContent = true; - else { - const ch = state.input.charCodeAt(state.position); - if (propertyStart !== null && allowPropertyMapping && allowBlockStyles && !allowBlockCollections && ch !== 124 && ch !== 62) { - const fallbackState = snapshotState(state); - const propertyIndent = propertyStart.position - propertyStart.lineStart; - restoreState(state, propertyStart); - if (readBlockMapping(state, propertyIndent, flowIndent, emptyProperties()) && state.events[fallbackState.eventsLength]?.type === EVENT_ID.MAPPING) hasContent = true; - else restoreState(state, fallbackState); + if (indentStatus === 1) { + if (allowBlockCollections && (readBlockSequence(state, blockIndent, props) || readBlockMapping(state, blockIndent, flowIndent, props)) || readFlowCollection(state, flowIndent, props)) hasContent = true; + else { + const ch = state.input.charCodeAt(state.position); + if (propertyStart !== null && allowPropertyMapping && allowBlockStyles && !allowBlockCollections && ch !== 124 && ch !== 62) { + const fallbackState = snapshotState(state); + const propertyIndent = propertyStart.position - propertyStart.lineStart; + restoreState(state, propertyStart); + if (readBlockMapping(state, propertyIndent, flowIndent, emptyProperties()) && state.events[fallbackState.eventsLength]?.type === EVENT_ID.MAPPING) hasContent = true; + else restoreState(state, fallbackState); + } + if (!hasContent && (allowBlockScalars && readBlockScalar(state, flowIndent, props) || readSingleQuotedScalar(state, flowIndent, props) || readDoubleQuotedScalar(state, flowIndent, props) || readAlias(state, props) || readPlainScalar(state, flowIndent, nodeContext, props))) hasContent = true; } - if (!hasContent && (allowBlockScalars && readBlockScalar(state, flowIndent, props) || readSingleQuotedScalar(state, flowIndent, props) || readDoubleQuotedScalar(state, flowIndent, props) || readAlias(state, props) || readPlainScalar(state, flowIndent, nodeContext, props))) hasContent = true; - } - else if (indentStatus === 0) hasContent = allowBlockCollections && readBlockSequence(state, blockIndent, props); + } else if (indentStatus === 0) hasContent = allowBlockCollections && readBlockSequence(state, blockIndent, props); } allowBlockScalars = allowBlockScalars && !hasContent; if (!hasContent && (props.anchorStart !== NO_RANGE$1 || props.tagStart !== NO_RANGE$1 || allowBlockScalars)) { @@ -39989,20 +40395,18 @@ function visitNode(node, visitor, ctx) { isKey: false })) return true; break; - case "mapping": - for (const { key, value } of node.items) { - if (visitNode(key, visitor, { - depth, - parent: node, - isKey: true - })) return true; - if (visitNode(value, visitor, { - depth, - parent: node, - isKey: false - })) return true; - } - break; + case "mapping": for (const { key, value } of node.items) { + if (visitNode(key, visitor, { + depth, + parent: node, + isKey: true + })) return true; + if (visitNode(value, visitor, { + depth, + parent: node, + isKey: false + })) return true; + } } return false; } @@ -40434,8 +40838,10 @@ function writeBlockMapping(state, level, node, compact) { const keyHasLineBreak = key.kind === "scalar" && key.value.indexOf("\n") !== -1; const keyIsTooLong = keyText.length > 1024 && /^[\s\S]{1025}/u.test(keyText); const explicitPair = keyIsBlock || keyHasLineBreak || keyIsTooLong; - if (explicitPair) if (keyText && CHAR_LINE_FEED === keyText.charCodeAt(0)) pairBuffer += "?"; - else pairBuffer += "? "; + if (explicitPair) { + if (keyText && CHAR_LINE_FEED === keyText.charCodeAt(0)) pairBuffer += "?"; + else pairBuffer += "? "; + } pairBuffer += keyText; if (explicitPair) pairBuffer += generateNextLine(state, level); const valueText = writeNode(state, level + 1, value, node, { @@ -40471,12 +40877,15 @@ function writeNode(state, level, node, parent, ctx) { let body; let shouldPrintTag = node.tagged; const useBlockCollection = block && (node.kind === "mapping" || node.kind === "sequence") && node.style === COLLECTION_STYLE.BLOCK && node.items.length !== 0; - if (node.kind === "mapping") if (useBlockCollection) body = writeBlockMapping(state, level, node, compact); - else body = writeFlowMapping(state, level, node); - else if (node.kind === "sequence") if (useBlockCollection) if (state.seqNoIndent && !isblockseq && level > 0) body = writeBlockSequence(state, level - 1, node, compact); - else body = writeBlockSequence(state, level, node, compact); - else body = writeFlowSequence(state, level, node); - else { + if (node.kind === "mapping") { + if (useBlockCollection) body = writeBlockMapping(state, level, node, compact); + else body = writeFlowMapping(state, level, node); + } else if (node.kind === "sequence") { + if (useBlockCollection) { + if (state.seqNoIndent && !isblockseq && level > 0) body = writeBlockSequence(state, level - 1, node, compact); + else body = writeBlockSequence(state, level, node, compact); + } else body = writeFlowSequence(state, level, node); + } else { const layout = scalarLayout(state, node, parent, level, iskey, !block); detectAllowedStyles(layout); for (const rule of state.scalarStyleRules) rule(layout); @@ -40850,6 +41259,7 @@ const defaultAuthorization = { users: [], }; const defaultSweepLookback = '1h'; +const maxBlunderbussDelayMs = 24 * 3_600_000; const maxSweepLookbackMs = 24 * 3_600_000; /** repositories of the owner that may hold an organization wide prow.yaml, in precedence order */ const orgConfigRepos = ['.project', '.github']; @@ -41200,12 +41610,28 @@ function normalizeBlunderbuss(source, raw) { if (raw.ignore_authors !== undefined && !isStringList(raw.ignore_authors)) { throw new Error(`${source}: blunderbuss.ignore_authors must be a list of GitHub usernames`); } + if (raw.delay !== undefined) { + if (typeof raw.delay !== 'string') { + throw new TypeError(`${source}: blunderbuss.delay must be a duration string such as 1h or 30m`); + } + let ms; + try { + ms = parseDuration(raw.delay, 'blunderbuss.delay'); + } + catch (e) { + throw new Error(`${source}: ${e instanceof Error ? e.message : e}`); + } + if (ms > maxBlunderbussDelayMs) { + throw new Error(`${source}: blunderbuss.delay must not be longer than 24h`); + } + } return stripUndefined({ request_count: raw.request_count, max_request_count: raw.max_request_count, exclude_approvers: raw.exclude_approvers, ignore_drafts: raw.ignore_drafts, ignore_authors: raw.ignore_authors, + delay: raw.delay, }); } const approveFlags = ['require_self_approval', 'ignore_review_state', 'lgtm_acts_as_approve', 'github_review']; @@ -41614,11 +42040,11 @@ function labeling_isNotFound(error) { && error.status === 404); } -;// CONCATENATED MODULE: ./node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log/dist-src/version.js +;// CONCATENATED MODULE: ./node_modules/@octokit/plugin-request-log/dist-src/version.js const plugin_request_log_dist_src_version_VERSION = "6.0.0"; -;// CONCATENATED MODULE: ./node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log/dist-src/index.js +;// CONCATENATED MODULE: ./node_modules/@octokit/plugin-request-log/dist-src/index.js function requestLog(octokit) { octokit.hook.wrap("request", (request, options) => { @@ -44876,6 +45302,7 @@ async function evaluateOnOwnersRepo(context, pullNumber) { + /** * blunderbussSettings resolves the `blunderbuss` configuration with Prow's * defaults: two reviewers, approvers count, drafts wait for ready_for_review. @@ -44890,6 +45317,7 @@ function blunderbussSettings(config) { exclude_approvers: raw.exclude_approvers ?? false, ignore_drafts: raw.ignore_drafts ?? true, ignore_authors: (raw.ignore_authors ?? []).map(login => login.toLowerCase()), + delay: parseDuration(raw.delay, 'blunderbuss.delay'), }; } /** @@ -44931,6 +45359,7 @@ function sample(items, count, rng) { * blunderbuss is the `pull_request` handler modelled on Prow's blunderbuss * plugin: on `opened` (and `ready_for_review` when drafts are ignored) it * requests reviews from the OWNERS reviewers covering the changed files. + * With `blunderbuss.delay` it defers to the `sweep` job instead. * * @param context - the github context of the current action event * @param rng - a source of numbers in [0, 1), injectable for tests @@ -44951,6 +45380,10 @@ async function blunderbuss(context = github_context, rng = Math.random) { core_debug(`blunderbuss: skipping ${action} action`); return; } + if (settings.delay > 0) { + info(`blunderbuss: #${pullNumber} ${action}; blunderbuss.delay is set, so the sweep job requests reviewers once it is due and nobody has been asked`); + return; + } await requestOwnersReviewers(octokit, context, pullNumber, settings, { explicit: false, rng }); } /** @@ -45332,6 +45765,11 @@ const pageSize = 100; * failure on one is collected and the rest still run. The run fails at the * end listing the failures. * + * With `blunderbuss.delay` the window reaches back a further `delay`: a pull + * request opened (or marked ready) inside the shifted window is due for + * reviewers now, even when nothing has touched it since. Those older pull + * requests get the blunderbuss step only. + * * @param context - the github actions event context * @param now - the current time, injectable for tests */ @@ -45340,13 +45778,27 @@ async function sweep(context = github_context, now = new Date()) { const config = await loadProwConfig(octokit, context); const lookbackMs = resolveSweepLookback(config.sweep); const since = new Date(now.getTime() - lookbackMs); - const candidates = await recentlyUpdatedPulls(octokit, context, since); + const reviewers = blunderbussSettings(config); + const due = { from: new Date(since.getTime() - reviewers.delay), to: new Date(now.getTime() - reviewers.delay) }; + const listed = await recentlyUpdatedPulls(octokit, context, due.from); + const candidates = listed.filter(pr => new Date(pr.updated_at) >= since); + const delayedOnly = listed.filter(pr => new Date(pr.updated_at) < since); info(`sweep: ${candidates.length} candidate${candidates.length === 1 ? '' : 's'} updated since ${since.toISOString()}`); - const result = { candidates: candidates.map(pr => pr.number), merged: [], enqueued: [], failures: [] }; - if (candidates.length === 0) { - return result; + if (reviewers.delay > 0) { + info(`sweep: ${delayedOnly.length} more checked for delayed reviewers, updated since ${due.from.toISOString()}`); } - const plugins = { lgtm: lgtmSettings(config), config, since }; + const result = { candidates: candidates.map(pr => pr.number), merged: [], enqueued: [], failures: [] }; + const plugins = { lgtm: lgtmSettings(config), config, reviewers, since, due }; + await forEachLimited(delayedOnly, sweepConcurrency, async (pr) => { + try { + if (await branchHasOwners(octokit, context, pr.base.ref)) { + await requestReviewersIfDue(octokit, context, pr, plugins); + } + } + catch (e) { + result.failures.push({ number: pr.number, message: `blunderbuss: ${e instanceof Error ? e.message : String(e)}` }); + } + }); await forEachLimited(candidates, sweepConcurrency, async (pr) => { const outcome = await sweepPullRequest(octokit, context, pr, plugins); if (outcome.result === 'merged') { @@ -45372,7 +45824,9 @@ async function sweepPullRequest(octokit, context, pr, plugins) { const tide = await loadTide(octokit, context, pr.base.ref); const ownersSteps = [ ['owners-label', () => applyOwnersLabels(octokit, context, pr.number)], - ['blunderbuss', () => requestReviewersIfFresh(octokit, context, pr, plugins)], + ['blunderbuss', () => plugins.reviewers.delay > 0 + ? requestReviewersIfDue(octokit, context, pr, plugins) + : requestReviewersIfFresh(octokit, context, pr, plugins)], ['approve', () => evaluateApproval(octokit, context, pr.number)], ]; const steps = [ @@ -45421,7 +45875,58 @@ async function requestReviewersIfFresh(octokit, context, pr, plugins) { core_debug(`sweep: #${pr.number} already has reviews`); return; } - await requestOwnersReviewers(octokit, context, pr.number, blunderbussSettings(plugins.config), { explicit: false, rng: Math.random }); + await requestOwnersReviewers(octokit, context, pr.number, plugins.reviewers, { explicit: false, rng: Math.random }); +} +/** + * requestReviewersIfDue is blunderbuss with `delay`: a pull request whose + * review clock (opened, or the last `ready_for_review` when drafts are + * ignored) started inside the due window, and that still has no requested + * reviewer or team and no review, gets reviewers now. + */ +async function requestReviewersIfDue(octokit, context, pr, plugins) { + const { reviewers: settings, due } = plugins; + if (settings.ignore_drafts && pr.draft === true) { + core_debug(`sweep: #${pr.number} is a draft`); + return; + } + if ((pr.requested_reviewers ?? []).length > 0 || (pr.requested_teams ?? []).length > 0) { + core_debug(`sweep: #${pr.number} already has requested reviewers`); + return; + } + let start = new Date(pr.created_at); + if (start > due.to) { + core_debug(`sweep: #${pr.number} is not due for reviewers before ${new Date(start.getTime() + settings.delay).toISOString()}`); + return; + } + if (settings.ignore_drafts) { + const ready = await lastReadyForReview(octokit, context, pr.number); + if (ready !== undefined && ready > start) { + start = ready; + } + } + if (start < due.from || start > due.to) { + core_debug(`sweep: #${pr.number} became ready at ${start.toISOString()}, outside the due window`); + return; + } + const { data: reviews } = await octokit.pulls.listReviews({ ...context.repo, pull_number: pr.number, per_page: 1 }); + if (reviews.length > 0) { + core_debug(`sweep: #${pr.number} already has reviews`); + return; + } + await requestOwnersReviewers(octokit, context, pr.number, settings, { explicit: false, rng: Math.random }); +} +async function lastReadyForReview(octokit, context, pullNumber) { + let events; + try { + events = await octokit.paginate(octokit.issues.listEventsForTimeline, { ...context.repo, issue_number: pullNumber, per_page: 100 }); + } + catch (e) { + throw new Error(`could not read the timeline: ${e}`); + } + const times = events + .filter(event => event.event === 'ready_for_review' && event.created_at !== undefined) + .map(event => new Date(event.created_at).getTime()); + return times.length === 0 ? undefined : new Date(Math.max(...times)); } async function recentlyUpdatedPulls(octokit, context, since) { const candidates = []; diff --git a/docs/configuration.md b/docs/configuration.md index bc2348f6..2c3f0111 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -314,6 +314,7 @@ Field | Default | Meaning `exclude_approvers` | `false` | only `reviewers` are candidates, not `approvers` `ignore_drafts` | `true` | a draft waits for `ready_for_review`; `false` requests on `opened` and skips `ready_for_review` `ignore_authors` | `[]` | pull requests by these authors get no automatic request (case-insensitive) +`delay` | `0` | wait this long after `opened` (or `ready_for_review`), then request only if the pull request still has no requested reviewer or team and no review; a Go style duration (`30m`, `1h`), at most `24h`. The [`sweep` job](./cron-jobs.md#sweep) makes the delayed request, so it must run on a schedule Event | Action --- | --- @@ -329,6 +330,21 @@ random among equals. With `max_request_count`, `request_count` is reduced so tha already requested reviewers plus the new ones do not exceed it. Nobody left to request is a debug-logged no-op; a refused request fails the run. No comment is posted. +With `delay` the `opened` and `ready_for_review` handlers request nothing and log that the +request is deferred. Each [`sweep`](./cron-jobs.md#sweep) run then requests reviewers on every +pull request whose review clock started between `now − delay − lookback` and `now − delay` and +that nobody has been asked to review yet. The clock starts at `opened`, or at the last +`ready_for_review` when `ignore_drafts` is on (one timeline read per such pull request). The +sweep's list reaches back the extra `delay`, so a pull request nobody touched since it opened is +still found; those older pull requests get this step only. Install the sweep job even under +`pull_request_target`; its other steps are idempotent. A request lands up to one sweep interval +after it is due, plus GitHub's scheduling delay. `/auto-cc` is never delayed. + +```yaml +blunderbuss: + delay: 1h +``` + The workflow token needs `pull-requests: write` and the workflow must subscribe to `ready_for_review` for drafts; see [events](./events.md#issues-and-pull_request). diff --git a/docs/cron-jobs.md b/docs/cron-jobs.md index 3906b6f5..bd636cea 100644 --- a/docs/cron-jobs.md +++ b/docs/cron-jobs.md @@ -26,7 +26,7 @@ Step | Reuses | Does | Skipped when --- | --- | --- | --- 1 | [`require_matching_label`](./configuration.md#require_matching_label) | every PR rule, no grace period | no rule is configured 2 | [`owners-label`](./labeling.md#labels-from-owners-files) | adds the missing OWNERS `labels:` | the repository has no OWNERS files -3 | [`blunderbuss`](./configuration.md#blunderbuss) | requests reviewers like `opened` would; honours `ignore_authors` and `ignore_drafts` | no OWNERS files; the PR was created before the window; it has requested reviewers, reviews, or is a draft +3 | [`blunderbuss`](./configuration.md#blunderbuss) | requests reviewers like `opened` would; honours `ignore_authors` and `ignore_drafts` | no OWNERS files; the PR was created before the window; it has requested reviewers, reviews, or is a draft. With [`blunderbuss.delay`](./configuration.md#blunderbuss): the PR's review clock did not start inside the window shifted back by `delay`; it has requested reviewers or teams, or reviews 4 | [`approve`](./commands.md#approve) | recomputes `approved` and the notifier | no OWNERS files 5 | [`ok-to-test`](./commands.md#trigger) | approves the workflow runs waiting for approval on the head | the PR does not carry `ok-to-test` 6 | [`tide`](./automatic-merging.md) | the label gate, the [`lgtm` binding](./automatic-merging.md#lgtm-is-bound-to-a-commit) (a stale `lgtm` is stripped), `mergeable_state`, the merge | never; `tide.merge_on_events` does not apply, the sweep is a scheduled job like `lgtm` diff --git a/package-lock.json b/package-lock.json index 2ddcb706..2c2253d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,16 +38,6 @@ "@actions/http-client": "^4.0.0" } }, - "node_modules/@actions/core/node_modules/@actions/http-client": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", - "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", - "license": "MIT", - "dependencies": { - "tunnel": "^0.0.6", - "undici": "^6.23.0" - } - }, "node_modules/@actions/exec": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz", @@ -72,7 +62,7 @@ "undici": "^6.23.0" } }, - "node_modules/@actions/http-client": { + "node_modules/@actions/github/node_modules/@actions/http-client": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.2.tgz", "integrity": "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA==", @@ -82,6 +72,16 @@ "undici": "^6.23.0" } }, + "node_modules/@actions/http-client": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", + "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", + "license": "MIT", + "dependencies": { + "tunnel": "^0.0.6", + "undici": "^6.23.0" + } + }, "node_modules/@actions/io": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz", @@ -228,66 +228,15 @@ } } }, - "node_modules/@antfu/eslint-config/node_modules/entities": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", - "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=20.19.0" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/@antfu/eslint-config/node_modules/eslint-plugin-unicorn": { - "version": "74.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-74.0.0.tgz", - "integrity": "sha512-AGnsGi2SxHg1HEAXxn9nSnZfyjvTWkxm8E8hpd/9tD6dLjBUdcD7+D6ZN64HmmCXTSXlrwVyUqe20Uyb2CaurA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.10.1", - "@eslint/css-tree": "^4.0.5", - "browserslist": "^4.28.8", - "change-case": "^5.4.4", - "ci-info": "^4.4.0", - "core-js-compat": "^3.50.0", - "detect-indent": "^7.0.2", - "entities": "^8.0.0", - "find-up-simple": "^1.0.1", - "globals": "^17.11.0", - "indent-string": "^5.0.0", - "is-builtin-module": "^5.0.0", - "is-identifier": "^1.1.0", - "pluralize": "^8.0.0", - "quote-js-string": "^0.1.0", - "regjsparser": "^0.13.2", - "reserved-identifiers": "^1.2.0", - "semver": "^7.8.5", - "strip-indent": "^4.1.1", - "yaml": "^2.9.0" - }, - "engines": { - "node": ">=22" - }, - "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=10.4" - } - }, "node_modules/@antfu/install-pkg": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-2.0.1.tgz", - "integrity": "sha512-iCKVQcIC0e3oDxEfs3SHQGW+ovhBMZmS1TE+bTk50rVyMCBmCfClv7Qi3HQKlumYwvjb/iIMeWCW2i67q6kFfQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-2.1.0.tgz", + "integrity": "sha512-sdg9NxU3zR4Mnawfbc/x6GB5Wf17WYud5qOuEuxXjaKpYpMkISSJEjItGebXJ2bQ4DIcly4NYH23mtkGJjvKUw==", "dev": true, "license": "MIT", "dependencies": { - "package-manager-detector": "^1.7.0", - "tinyexec": "^1.2.4" + "package-manager-detector": "^1.8.0", + "tinyexec": "^1.3.1" }, "funding": { "url": "https://github.com/sponsors/antfu" @@ -314,9 +263,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", - "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", "dev": true, "license": "MIT", "dependencies": { @@ -378,9 +327,9 @@ } }, "node_modules/@clack/core": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.4.3.tgz", - "integrity": "sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.5.1.tgz", + "integrity": "sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==", "dev": true, "license": "MIT", "dependencies": { @@ -392,13 +341,13 @@ } }, "node_modules/@clack/prompts": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.7.0.tgz", - "integrity": "sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.8.1.tgz", + "integrity": "sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==", "dev": true, "license": "MIT", "dependencies": { - "@clack/core": "1.4.3", + "@clack/core": "1.5.1", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" @@ -408,15 +357,15 @@ } }, "node_modules/@e18e/eslint-plugin": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@e18e/eslint-plugin/-/eslint-plugin-0.8.0.tgz", - "integrity": "sha512-js/TeM+XJyoJ2Zk4if5uTEchv3MEbqugc9gLgq8YdB6Dy+LvwGACpQiAwcul0r4LUl0TvhuzAKUeIUPtGp2cew==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@e18e/eslint-plugin/-/eslint-plugin-0.8.1.tgz", + "integrity": "sha512-OV3T7l0r52/IglskdAuoO+BJyzsCs7AcIHpwpBMlIMO0+3RHskM2h5MuHdLuesIhSRhwCURGMKtp/XwnfXrfxg==", "dev": true, "license": "MIT", "dependencies": { "empathic": "^2.0.1", - "module-replacements": "^3.1.0", - "semver": "^7.8.5" + "module-replacements": "^3.3.0", + "verkit": "^0.4.0" }, "peerDependencies": { "eslint": "^9.0.0 || ^10.0.0", @@ -459,9 +408,9 @@ } }, "node_modules/@eslint-community/eslint-plugin-eslint-comments": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.8.0.tgz", - "integrity": "sha512-bzGg2H83F9p55TKzlNUS/LWb1WF2OqdVX67FK1OadDPLVOhabFRERC7TiDJzk//LedaVnRS5uqK/2f/AZ/+VyA==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.8.1.tgz", + "integrity": "sha512-vafrdi15JHBFh1qWOAucyJwlEEuhdoMof28jOdKdgnwZ7bXwd6v4wzHYSmAVLwnx0yc7bqAtfJ0EZQV1WAzV/Q==", "dev": true, "license": "MIT", "dependencies": { @@ -583,13 +532,13 @@ } }, "node_modules/@eslint/css-tree": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-4.1.0.tgz", - "integrity": "sha512-cg0ohyrAG3swyGqt8t1K/OK97DqBw/ftDvlvyY1fmEst5B40UOmsimwLENq74z2dyw5CDM+3zJIW+CV2nFNDdA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-4.1.2.tgz", + "integrity": "sha512-rVcxLmwSkEL3aWS3vAgsTRrQHoYE1b0XcgDtKHDJ92XOkyUpcbS/g0tUJKhvCtlEhYzgKBWsgDd+Z/aPhd166w==", "dev": true, "license": "MIT", "dependencies": { - "mdn-data": "2.34.0", + "mdn-data": "2.37.2", "source-map-js": "^1.2.1" }, "engines": { @@ -713,9 +662,9 @@ } }, "node_modules/@inquirer/ansi": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.8.tgz", - "integrity": "sha512-WpQM+Ti6Z40EFwwt+uL2p4UabT+W179zHp6HhLVOzfbwnVn05IPO/eXIZXGNqcT1jbQ15SujNLzQ39k4QPPxBQ==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.9.tgz", + "integrity": "sha512-0Ywt3S8tqM6TWUcsRlBFQ1x+X3/o8kktX0ZiKAnByYb9GFDknnOhse1PVtfiD2BXPI8ar+BWx9PV9R0lQIcygw==", "dev": true, "license": "MIT", "engines": { @@ -723,14 +672,14 @@ } }, "node_modules/@inquirer/confirm": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.3.2.tgz", - "integrity": "sha512-Xvr/0HggjddPtGppuqVmxhTw+Hr8PvsZ/k0HmOEaAqQEt80OITNkFWnsdNmyT0/eM4Ab+iJLx2R8rctlEyfSVg==", + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.3.4.tgz", + "integrity": "sha512-ZwnaZZDa1zxsyVrN32s447ydMnKcw7e8WWNT+R+Qsu0zAn8Rs6yi9d1B80Kob1Ul2cfUi7t8JD2t4/K7uEZpqA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^12.0.3", - "@inquirer/type": "4.1.1" + "@inquirer/core": "^12.0.5", + "@inquirer/type": "4.2.0" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" @@ -745,15 +694,15 @@ } }, "node_modules/@inquirer/core": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.3.tgz", - "integrity": "sha512-wsSy0sznmXwkty+2PzZwx00Cazc/E0r0B7mAzdGROz2Ct+DFZXaK7WDjGZvgjRldxH5ZhFVfF2lgkYrqgOw2KA==", + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.5.tgz", + "integrity": "sha512-c0ZSnO9oVk/IlEGoZK3u8b3IZQeu9I6jUkXJSQnQEVRXsjKvtAq3AGqFL2LgfJhlzMZne08pZHWRWasIcI3Rew==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^2.0.8", + "@inquirer/ansi": "^2.0.9", "@inquirer/figures": "^2.0.9", - "@inquirer/type": "4.1.1", + "@inquirer/type": "4.2.0", "cli-width": "^4.1.0", "fast-wrap-ansi": "^0.2.0", "mute-stream": "^3.0.0", @@ -782,9 +731,9 @@ } }, "node_modules/@inquirer/type": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.1.1.tgz", - "integrity": "sha512-yJoHYrMnxIsJZCY+0Vb66Dy3he3kL3e2wOBKhoSwWWAzZAY82emlxwgprCtp6yRixvNRNq9ztfRWQYPNr3Go7A==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.2.0.tgz", + "integrity": "sha512-2rnHX8RPo4glJYqnFc/v3nQeIhDcjyRRyaT7MGcfL/8xv/8K03SXYoA2tX06WVSKywWOE/ncbG3dtuzLjR5TCQ==", "dev": true, "license": "MIT", "engines": { @@ -859,9 +808,9 @@ "license": "MIT" }, "node_modules/@mswjs/interceptors": { - "version": "0.45.6", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.45.6.tgz", - "integrity": "sha512-qdBK6aOT5Qjt+cmU/XcobZjjmrIsdiQRR6hA0LP72uB7CRx+XfAjm8Opvgia8nX9kPOKqp+BKHuzMa1IFPTvyg==", + "version": "0.45.9", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.45.9.tgz", + "integrity": "sha512-NmEzpWbbiWpudgqKVZtGdSAvQGIYyj7Rf8ea+1hJEo+Dn0YvPHtiz577US7kGg0sCaZtPelrdqV4SfwwGJq1cA==", "dev": true, "license": "MIT", "dependencies": { @@ -966,6 +915,18 @@ "@octokit/openapi-types": "^27.0.0" } }, + "node_modules/@octokit/plugin-request-log": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", + "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, "node_modules/@octokit/plugin-rest-endpoint-methods": { "version": "17.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", @@ -1040,18 +1001,6 @@ "node": ">= 20" } }, - "node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", - "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, "node_modules/@octokit/types": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", @@ -1085,9 +1034,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.152.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz", - "integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==", + "version": "0.154.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.154.0.tgz", + "integrity": "sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==", "dev": true, "license": "MIT", "peer": true, @@ -1109,9 +1058,9 @@ } }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", - "integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.14.tgz", + "integrity": "sha512-aWR+XKH9+rW7m5fWq/5360J3mHycrx/o6xZM2DQFdJnTMdyP7/WzxPjhtLbVWdKo2y612/4U1bWqb3HQhiF7vg==", "cpu": [ "arm" ], @@ -1127,9 +1076,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz", - "integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.14.tgz", + "integrity": "sha512-QiVxHofl6A8lQU7WAtOUY4QMVZXohxwz7WJJoeh8NBEUyKfIkMRKhYyq8az/1RypNiIXzNTtiS6KwHz0erxYRQ==", "cpu": [ "arm64" ], @@ -1145,9 +1094,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz", - "integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.14.tgz", + "integrity": "sha512-lTQOzHuBIooh3jIr5XINQkjPGEuGy+Dsy0meXDr6Sjty0b99kYgGh4uBC/8mJX1T0kC8d6S0aPP1Y+bHkh6aBw==", "cpu": [ "arm64" ], @@ -1163,9 +1112,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz", - "integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.14.tgz", + "integrity": "sha512-hyMKEGatjmBYCs/Q4sbIcL/GqpFEqsX3wc+HYVQ/85A4rxc1o7rPm4DUI4GV4k/h0ITddwFSGpqQunI14GXjTA==", "cpu": [ "x64" ], @@ -1181,9 +1130,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz", - "integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.14.tgz", + "integrity": "sha512-u371GbXoVXrEgP20PwzoGNOdAOqAMhzo19JzzY+V4YmmnC+DTOoqdbMu+O+54emM59Mik/UdrtWgcuEDKWRPKA==", "cpu": [ "x64" ], @@ -1199,9 +1148,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz", - "integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.14.tgz", + "integrity": "sha512-BqwKsdZQf6EqVWr8fv2MrDYzAvOZ7+NYFSJESRGs87fkseEhs0TU9TXgRJTkZoRRkxTizyEg1LKUXfU3/78uqg==", "cpu": [ "arm" ], @@ -1217,9 +1166,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz", - "integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.14.tgz", + "integrity": "sha512-SD9kY8M009x/7s57Z1dgUVlP5+uYBgKQK0Tkr1WIWngrtUJmRCW1RJFMY7QDla2khXhmg2i5Io7MUjcmZNZ/KQ==", "cpu": [ "arm64" ], @@ -1238,9 +1187,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz", - "integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.14.tgz", + "integrity": "sha512-BJ2CL19M6uuWesMgnqJzgxoI+N+eV7b0A9O9vLV42y+gitC41fNa8KElau1tHVzuLWX5GzEuxMPhAO0tQXQMkg==", "cpu": [ "arm64" ], @@ -1259,9 +1208,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz", - "integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.14.tgz", + "integrity": "sha512-4+Kl8daPV8NDHaD7mfCcc1pRM+Qg7ab8DyMm5FG5WoZgv4h2i3KFN1CybYBNbQqmuYm7ftJLvmMI1eHYJ22S/Q==", "cpu": [ "ppc64" ], @@ -1280,9 +1229,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz", - "integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.14.tgz", + "integrity": "sha512-V/h8ePq1fKDrmtFMz6xcCN3DKvuvMRrwwD1q0PkBeeo4DpK64biaKvqWGVxqCeYKqeRk7gE7/iKPxLCn08O97A==", "cpu": [ "s390x" ], @@ -1301,9 +1250,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz", - "integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.14.tgz", + "integrity": "sha512-WxalXzgrLVpKC93xfpaJ3gCXUWzeCr+FRCbDVD2mUAy4L6Vo3lNVz0epUEUpxPWJkLNYUwM4OSIikv36OJ9mLg==", "cpu": [ "x64" ], @@ -1322,9 +1271,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz", - "integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.14.tgz", + "integrity": "sha512-3G3tnAmTpdk9jO3GQtyHXqeFD2SlecfTws/Y3M2mmj9nMBwwuLT4kur8sZKeu7ENUHSpVO3cIsm5A52LEWWwlg==", "cpu": [ "x64" ], @@ -1343,9 +1292,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz", - "integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.14.tgz", + "integrity": "sha512-qyr5XiNGxm2ytx17vvtcJ9nXn6v1gENETi503bJx3OGwZ1tSonj7BosxbMa/xeAfSl5iS9X6KjEWYXLu6v1L7Q==", "cpu": [ "arm64" ], @@ -1361,9 +1310,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz", - "integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.14.tgz", + "integrity": "sha512-oA4o5o0S2yB199YyYXDzKUv1Z56Rc+mgOjwm7Z/vJ9Z8igiDPYvoOuDyo6g7AK/ZaF09nPhDKVnGBcYHO11GXA==", "cpu": [ "arm64" ], @@ -1379,9 +1328,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz", - "integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.14.tgz", + "integrity": "sha512-9mE94bf2GZUaR/fUSXCMpBoWkctu421Mi0ORpm4zqfbkjKep7RxzPFa5etcGs5h+2KApoWBOA/hAJa/7saGgEQ==", "cpu": [ "x64" ], @@ -1549,17 +1498,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.0.tgz", - "integrity": "sha512-/v8HZt6RlyIZxB3ntehELOcUcfxKPVGWXnQdJuHRmzrqgF8nQypcC/oxGW+Ot4VGKDq81XugPKxx0n5PBtf9PA==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.72.0.tgz", + "integrity": "sha512-aysKgysPX9XOv/dk95UkvUDe++Q3n3dJPG9CEWT3RUccxfkPJ+Qn6nhKPDhZXU6Ofo9kgwGWwKyQCnZIXTgngg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.70.0", - "@typescript-eslint/type-utils": "8.70.0", - "@typescript-eslint/utils": "8.70.0", - "@typescript-eslint/visitor-keys": "8.70.0", + "@typescript-eslint/scope-manager": "8.72.0", + "@typescript-eslint/type-utils": "8.72.0", + "@typescript-eslint/utils": "8.72.0", + "@typescript-eslint/visitor-keys": "8.72.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1572,22 +1521,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.70.0", + "@typescript-eslint/parser": "^8.72.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.0.tgz", - "integrity": "sha512-zYvrmj9Yxd63UGaXw+kdt6A0F0s0qveJyuatIM77bYC2DE4pgmg7a50u8LR7PRtXd0x+h+Tl3eXabGm06SWd3Q==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.72.0.tgz", + "integrity": "sha512-0O+x3ynciD6zuXb1CKSu165haQV6ey53DKhHHUnujP7U+XlltJG+/keT0Xhd1HXCze+IHf7Tvt39ovyepX/LNw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.70.0", - "@typescript-eslint/types": "8.70.0", - "@typescript-eslint/typescript-estree": "8.70.0", - "@typescript-eslint/visitor-keys": "8.70.0", + "@typescript-eslint/scope-manager": "8.72.0", + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/typescript-estree": "8.72.0", + "@typescript-eslint/visitor-keys": "8.72.0", "debug": "^4.4.3" }, "engines": { @@ -1603,14 +1552,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.0.tgz", - "integrity": "sha512-hFHbTNqhU9G+2eKFXCBVb1tjFT/LceiJ4+HfLO4pTpDI0KHi6iajpcFFkaSQ9gXmCh7n82A0PthaayEdN6mspQ==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.72.0.tgz", + "integrity": "sha512-bzHngBbmIgzj6TsTjVUCntGx6FFLgE7mPjpO0PzHycOaZHXqS43XnrkFIHRS16LLr/xO6FHSXG3GJFo/F4bSBQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.70.0", - "@typescript-eslint/types": "^8.70.0", + "@typescript-eslint/tsconfig-utils": "^8.72.0", + "@typescript-eslint/types": "^8.72.0", "debug": "^4.4.3" }, "engines": { @@ -1625,14 +1574,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.0.tgz", - "integrity": "sha512-8nP3Kwh5hlgZ4FicGvmznAmJe8UL4sdU8tLukrPaMuQmDuk4Y8xYfzu/aYZW4xT2JCgc7H/TpDI5cGlxcWJSqQ==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.0.tgz", + "integrity": "sha512-JewPyJOYcXBSAS7PIgufscHOwZqhTGyBRiQJhhuDln66tMchxvvt7nJ90JKKIoOelmdHA3kAQbm9cEUHc4JSEA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.70.0", - "@typescript-eslint/visitor-keys": "8.70.0" + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/visitor-keys": "8.72.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1643,9 +1592,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.0.tgz", - "integrity": "sha512-adnkeeNq9Sq1sUf4+FRVc0KdgYghzsgFpZSQVZVvY0LCuUuN0FnQgyGzCJeC4fW1cdXseBAjU2EOqUIjbNcZUw==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.72.0.tgz", + "integrity": "sha512-0vbxCf7xLVPSjcOdm6eQbgViH8EDJ8xnl1laLT9yoqSz2YmcSfSg5Vdl0JUvZf6rcuJ0ZivJIuMD4edTg8obaA==", "dev": true, "license": "MIT", "engines": { @@ -1660,15 +1609,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.0.tgz", - "integrity": "sha512-NUMKIhYVaVIVLnRL9CRt+VVcuLgSHUCpXn4/+K8wql+vdInUzvx8BjUO1oJ7cG9shjFJKtF8F8Hh2kCh3/KBVw==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.72.0.tgz", + "integrity": "sha512-gEXxmmbSTSOVTC37IYYvremOM31v+UN2W772bJxmVYPhAOPSUxtacyb7wkm1EhkYKU6KzFJsdU44DCV4to0LWw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.70.0", - "@typescript-eslint/typescript-estree": "8.70.0", - "@typescript-eslint/utils": "8.70.0", + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/typescript-estree": "8.72.0", + "@typescript-eslint/utils": "8.72.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1685,9 +1634,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.0.tgz", - "integrity": "sha512-asTOIYhDg4zdzOScCyaytrsV3cR6B4ecPQlXw/dJIm7J/MZTtCtfVII9JD8Geh4jTCrK/Xe6cg5UevoleMcoJQ==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.0.tgz", + "integrity": "sha512-Adfoy59kxNEjT5E5fnyrp7GpHYuWs8ONbdohu4ez6IU46qDq8LltG90tLmkucZB2uhYL8mqBjtXqGd8yhfjXqQ==", "dev": true, "license": "MIT", "engines": { @@ -1699,16 +1648,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.0.tgz", - "integrity": "sha512-d9NmHMPEKQ7QCLLm1jI3zmoQBwT5KwFYjXBJ9ymZfKCUU+5rmTRykKAFvH5Qn/ZCds3CEAFS9OC9M/jkl0X2bA==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.72.0.tgz", + "integrity": "sha512-gwLfFgWcw15tN2KXDCJvxEOQjPn+P3j/n3eSqkZ5sX4VpW9Cosodr+tWwBZRvJT3TcKx6HnPRGZMCNAiP1Xhug==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.70.0", - "@typescript-eslint/tsconfig-utils": "8.70.0", - "@typescript-eslint/types": "8.70.0", - "@typescript-eslint/visitor-keys": "8.70.0", + "@typescript-eslint/project-service": "8.72.0", + "@typescript-eslint/tsconfig-utils": "8.72.0", + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/visitor-keys": "8.72.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1727,16 +1676,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.0.tgz", - "integrity": "sha512-oZmtKJz/4fufZ2p3+Cn3ijEojcdfR+1zYDH2xKYrEly0dR/Q/1xUPRCOlKGxod78nWlU2UnDe09GZ3TaknBFGA==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.72.0.tgz", + "integrity": "sha512-0up3oArJZBYnzOaEXKo8DmI43QvMZyPoFEt9LWzRJcyl/RcJjfKKPebknN1VbTgXBf3M/KggUh5uUMdURLnseg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.70.0", - "@typescript-eslint/types": "8.70.0", - "@typescript-eslint/typescript-estree": "8.70.0" + "@typescript-eslint/scope-manager": "8.72.0", + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/typescript-estree": "8.72.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1751,13 +1700,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.70.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.0.tgz", - "integrity": "sha512-BoC8PiO4Hkdo0TVJh9Ntxr5MxPDI7/oFsrygN5ADelFSeXG/qgNuucIGA+L5Z6JpPTE/uRfcTWtscjbUaufepQ==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.0.tgz", + "integrity": "sha512-E2mroviasaWecDzTGiGMtuEguuLVOeRggnrIn93CJuxYJzQBHbyymlT08aVQydbBal5538o+JkBKXh2sRuCyIA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/types": "8.72.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1792,9 +1741,9 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.0.4.tgz", - "integrity": "sha512-P5YcQY8Y6RmoE9xRXI38rT8pssbcubEzqtYTM2XQoxOXMDn04nRaTI1SM8qCl9/NfW3ag9GlzdSXu7IwO5Ft8A==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.0.5.tgz", + "integrity": "sha512-4KpkGdIrSqBihx/JyP/e+S+IKB98etg1XDQiLAxksLfcShnwi1VReGeOT9NI43hLHbknosKp/1CCLn9Zgcs8mg==", "dev": true, "license": "MIT", "dependencies": { @@ -1811,8 +1760,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "5.0.4", - "vitest": "5.0.4" + "@vitest/browser": "5.0.5", + "vitest": "5.0.5" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -1875,14 +1824,14 @@ } }, "node_modules/@vitest/mocker": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.4.tgz", - "integrity": "sha512-tqAlrYWce4iUxhr3ncNohejtCTOcHeE8XWrSNZY3OhPoDn01yeGv+gnaBy64ATp7o6pb03eIbBAjzmibpc9vIQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.5.tgz", + "integrity": "sha512-xLL3lkDegJZw+MGoGaCCsFayDZthGgpAtr3Vziyfc4p7xH89K7KRPcRBBh/kEYm0Aqkt5DtTmkYpBtRV/FrHZg==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.31", - "@vitest/spy": "5.0.4", + "@vitest/spy": "5.0.5", "estree-walker": "^3.0.3", "magic-string": "^1.4.3" }, @@ -1923,9 +1872,9 @@ } }, "node_modules/@vitest/spy": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.4.tgz", - "integrity": "sha512-MZKk/gSkm2q+ICobMxCpH1mA+cCAWm8WV7UhxlqGjq/sJ3AGc1BqFOs5CRVXxH78wQtme9q/NAAgBquj4AcyMw==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.5.tgz", + "integrity": "sha512-lwJRExuH417257Q5wv9QYugN9IMJkoxcrKrYxGPQkBzl7wlNpTUxD/5yNX4ESKVUIShKPgkGchYPFMWOOk0wzw==", "dev": true, "license": "MIT", "funding": { @@ -1933,75 +1882,75 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.42.tgz", - "integrity": "sha512-2Ye1ilMtKXxl8qZUrQ5j0CdgenFp/HFQmta6rfRyfEsTG69L6Wk+tWuNoHYHMx9E8tF2Slvdg1FuwDvAXdy1LQ==", + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.44.tgz", + "integrity": "sha512-k34nCytbK8PQ1gR2mGROYOw6Pnv/mumqIdrZ3x2tbyXZDWm7ViKGLTfdB+DRrWqEQsLgGJvn0WN9jBif5zCTLQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@babel/parser": "^7.29.8", - "@vue/shared": "3.5.42", + "@babel/parser": "^7.29.9", + "@vue/shared": "3.5.44", "entities": "^7.0.1", "estree-walker": "^2.0.2", - "source-map-js": "^1.2.1" + "source-map-js": "^1.2.2" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.42.tgz", - "integrity": "sha512-qbhQZEFmycr+ni/qyuccS4sucNN7VAbDfbkvNxWOX2VfgFm90MNs3/UhRNKoPMEIVn0F8gdlYjLPvqxHwHeQOA==", + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.44.tgz", + "integrity": "sha512-W5AoBFWdw1lQAKiHowkfgFKFab82oSRT6sGsPfw/q1GRjsy/ZJFLHGhJyBRIFN9APLTUduDH9U2JAiPOIyKuYg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vue/compiler-core": "3.5.42", - "@vue/shared": "3.5.42" + "@vue/compiler-core": "3.5.44", + "@vue/shared": "3.5.44" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.42.tgz", - "integrity": "sha512-fkCAFB4okcAANGMThboWnScp/gzWjU0ZSkVnjTIiplmMDq2uq0tIB3j+xVu4rhv5rvOgBySCysudmbMd6xRRqw==", + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.44.tgz", + "integrity": "sha512-dzHmQ4jXTpdr5FjIQUeykVakN/uzqFbUo9/C5ikBFg3a3PeM6uRxeczx1ZbXBML0/zJstEh3ygYipzR5Z7b2Pw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@babel/parser": "^7.29.8", - "@vue/compiler-core": "3.5.42", - "@vue/compiler-dom": "3.5.42", - "@vue/compiler-ssr": "3.5.42", - "@vue/shared": "3.5.42", + "@babel/parser": "^7.29.9", + "@vue/compiler-core": "3.5.44", + "@vue/compiler-dom": "3.5.44", + "@vue/compiler-ssr": "3.5.44", + "@vue/shared": "3.5.44", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", - "postcss": "^8.5.19", - "source-map-js": "^1.2.1" + "postcss": "^8.5.29", + "source-map-js": "^1.2.2" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.42.tgz", - "integrity": "sha512-xmLk3wLkbizPAiLyomjgFFosf2ys9b5Ghb+oh/k2tnvipNz8OFrQOiTcWCzyK7MpBp9KkyGtfvgfLUivbmuGYA==", + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.44.tgz", + "integrity": "sha512-xr5gb1JVHlfXJwSlRz1FeP6uxoazdzHuMTVLE7up+4Vrqxk219CvxLPxD9NXBt47yvZW7+p4DXfyp4O1fkByIA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vue/compiler-dom": "3.5.42", - "@vue/shared": "3.5.42" + "@vue/compiler-dom": "3.5.44", + "@vue/shared": "3.5.44" } }, "node_modules/@vue/shared": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.42.tgz", - "integrity": "sha512-2rPxex1jQf4jvl9MOHl6YaXCPcrNqz/FstMOEh3QWY+/OME9nQTvl9WYeCwhW7AFjaR0SnngZGlp/wkR6rkI6g==", + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.44.tgz", + "integrity": "sha512-H82XLH0DjmSOdbEwO15x3QTo1f5PWEtv237eLpYKc0mqLu+B8hnq16lFWmuBmNurkeiG3wr+oM1FhOll/YVFRg==", "dev": true, "license": "MIT", "peer": true }, "node_modules/acorn": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", - "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", "dev": true, "license": "MIT", "bin": { @@ -2065,9 +2014,9 @@ } }, "node_modules/ansis": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.3.1.tgz", - "integrity": "sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.4.0.tgz", + "integrity": "sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==", "dev": true, "license": "ISC", "engines": { @@ -2085,10 +2034,20 @@ } }, "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-3.0.3.tgz", + "integrity": "sha512-Sn98ftV3KfsO8xfLPHG6oT8y+b0yvbrLgZjgPDXsharNY15tTAjqIsIju4S32nl6/iEUNNE4v+yL2Zhm8ooP3w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "PSF-2.0" }, "node_modules/assertion-error": { "version": "2.0.1", @@ -2133,9 +2092,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.11.21", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.21.tgz", - "integrity": "sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==", + "version": "2.11.30", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.30.tgz", + "integrity": "sha512-YJs6Pz17RMNv8HoyKREtCY38E3BV1nPkWVmIb+XN1uHC1Vqt3KZCH/uJH9ZKRoiKb/icZ6tvehyee6RZNbFfRA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2172,9 +2131,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.9.tgz", - "integrity": "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==", + "version": "4.29.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.4.tgz", + "integrity": "sha512-2TcbbiwXEq+N0kD36tykpCfyyQigUXmuwNQbnPp4Xk4PX9JOqVIKjJlIDjpH7uY6tmRGoAd+apeT1p60T8wsdA==", "dev": true, "funding": [ { @@ -2192,11 +2151,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.11.20", - "caniuse-lite": "^1.0.30001810", - "electron-to-chromium": "^1.5.420", - "node-releases": "^2.0.54", - "update-browserslist-db": "^1.3.2" + "baseline-browser-mapping": "^2.11.29", + "caniuse-lite": "^1.0.30001816", + "electron-to-chromium": "^1.5.459", + "node-releases": "^2.0.59", + "update-browserslist-db": "^1.3.4" }, "bin": { "browserslist": "cli.js" @@ -2206,9 +2165,9 @@ } }, "node_modules/builtin-modules": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.3.0.tgz", - "integrity": "sha512-hMQUl2bUFG339QygPM97E+mc8OY1IAchORZxm4a/frcYwKzozMzRVDBwHW0NjOqGElLm2O37AVQE8ikxlZHrMQ==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.4.0.tgz", + "integrity": "sha512-JCWSCdun+4Ovd9BhM/Vtlmwb7oD6Wl4YiPRXXwhAuwlPhW1un/MKgXn7GZoFm53ginnoNzus69V8JWx0K393jg==", "dev": true, "license": "MIT", "engines": { @@ -2219,9 +2178,9 @@ } }, "node_modules/cac": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz", - "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.1.0.tgz", + "integrity": "sha512-LMDU/U2yA4IPIY8KT0NsNPWEYZvAMkbgyspxJ6btJaYV+WMDOHAZCmB0lsTObiHaRS1V/ztKAl7+TSkTqXyeoA==", "dev": true, "license": "MIT", "engines": { @@ -2243,9 +2202,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", - "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", + "version": "1.0.30001816", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001816.tgz", + "integrity": "sha512-+8Yx7BXCoqk6IF8yTicjfUR6D/ldJzdlsodlEOiOSPmhK844WIgk67/zIQaGAOxNkZyyvBlrRFnLvqKIoqbAFw==", "dev": true, "funding": [ { @@ -2389,9 +2348,9 @@ "license": "MIT" }, "node_modules/content-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-3.0.0.tgz", - "integrity": "sha512-AIi5H6p0xk5uknXcN3/rmhP8jgp69OfSe/JuKiQAFprJ7UGw7mwj7m4XcmDzlrnJDG+cGpphAINGdU3g3g7kDw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-3.1.1.tgz", + "integrity": "sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA==", "license": "MIT", "engines": { "node": ">=22" @@ -2429,13 +2388,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.50.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.50.0.tgz", - "integrity": "sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==", + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.51.0.tgz", + "integrity": "sha512-52r6fkXgxv4GLMjmFcMWRx7X9bw071xTTdrDcdyPGRqU2oE+9pCG0bAOMifSBdLw0JRBZKEF0q3B55qPlLuE8g==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.28.7" + "browserslist": "^4.29.3" }, "engines": { "node": ">=6.4.0" @@ -2571,9 +2530,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.422", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.422.tgz", - "integrity": "sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==", + "version": "1.5.459", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.459.tgz", + "integrity": "sha512-4SC9HHSFjO/liAhifpdOL5hG9b4BP7/5G3y3UPZVO8trlAXr1CaUEEJL0gWK3kOcYcZrOA5rkwG45Gra/lTIgg==", "dev": true, "license": "ISC" }, @@ -2585,9 +2544,9 @@ "license": "MIT" }, "node_modules/empathic": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.1.tgz", - "integrity": "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.1.0.tgz", + "integrity": "sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==", "dev": true, "license": "MIT", "engines": { @@ -2595,9 +2554,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.24.5", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", - "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.26.0.tgz", + "integrity": "sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==", "dev": true, "license": "MIT", "dependencies": { @@ -2653,9 +2612,9 @@ } }, "node_modules/eslint": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.12.0.tgz", - "integrity": "sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==", + "version": "10.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.13.0.tgz", + "integrity": "sha512-UohDjD4zSzEwhf58M3O7vc/ycc8O1I7dNlhtD0WxE8Px8EHNJKtUwzBqrzeGhisRuv2ag4sAYswszCJRgKXYUg==", "dev": true, "license": "MIT", "workspaces": [ @@ -2875,17 +2834,17 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "64.3.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-64.3.5.tgz", - "integrity": "sha512-BqRUwfREoBH+7pzDD+uIQ3aema5P7BnPYcHj3mU0DLm+p/5TEHdimkXgnQfYl0AGgB9PZxZW/Lk7D69FTJSLXw==", + "version": "64.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-64.5.4.tgz", + "integrity": "sha512-xfRhXPSSWT612muJ6XTvxuVJ8zYHv99qNgBqPVqF28aSqoy4s4XbSkrWXnYA2hl5ejC02yEpk6fqkj3BmJ6Xbg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@es-joy/jsdoccomment": "~0.96.0", + "@es-joy/jsdoccomment": "~0.98.0", "@es-joy/resolve.exports": "1.2.0", - "@typescript-eslint/utils": "^8.69.0", + "@typescript-eslint/utils": "^8.70.0", "are-docs-informative": "^0.1.1", - "comment-parser": "1.4.8", + "comment-parser": "1.4.9", "debug": "^4.4.3", "escape-string-regexp": "^5.0.0", "espree": "^11.2.0", @@ -2901,40 +2860,36 @@ "node": "^22.22.2 || >=24.15.0" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/eslint-plugin-jsdoc/node_modules/@es-joy/jsdoccomment": { - "version": "0.96.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.96.0.tgz", - "integrity": "sha512-nvtxrDqAJOKMPSsMHqshCnHvnCqFnJTsKpTaTSaZoUi9VxGVe2JvgQeAY/Qvh2wyqXByIAqNTgI7h9elXzn0yQ==", + "version": "0.98.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.98.0.tgz", + "integrity": "sha512-QS+b7I2aaSM+gZfDz1b9E4B367JJ2qTjFXRKF289iKkh9sYdZ21Q5MiF/Duzouy3J0C4VhM3I/8f2F4+zT8gYQ==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.9", - "@typescript-eslint/types": "^8.67.0", - "comment-parser": "1.4.8", + "@typescript-eslint/types": "^8.70.0", + "comment-parser": "1.4.9", "esquery": "^1.7.0", - "jsdoc-type-pratt-parser": "~9.2.0" + "jsdoc-type-pratt-parser": "~9.2.2" }, "engines": { "node": "^22.22.2 || >=24.15.0" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/@types/node": { - "version": "26.4.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.1.tgz", - "integrity": "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~8.3.0" - } - }, "node_modules/eslint-plugin-jsdoc/node_modules/comment-parser": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.8.tgz", - "integrity": "sha512-rKZTGo4fzKYna8UcL0isTg5wkBNla7bxTypLwZQXjIdi++IdP1OJ41rI5Mti3/jltkPujbu4i9LIARYA+zpotQ==", + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.9.tgz", + "integrity": "sha512-+2AvZKjJaNq9GQljm3tr0utwrig5BL+jgJGvz5rDpGKNIp+ojcRXWUwBbh/sGIi1QCprR6PsKFakub+w1v+4hQ==", "dev": true, "license": "MIT", "engines": { @@ -2986,26 +2941,18 @@ } }, "node_modules/eslint-plugin-jsdoc/node_modules/jsdoc-type-pratt-parser": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-9.2.1.tgz", - "integrity": "sha512-V4Ww4EHnTcTLSOMoB0FsF72JhQvcAsriCm/LWnxJeGWoxIjEL2l9na11abQok5SYShq8m0Gl02el/xAbTCulvQ==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-9.2.3.tgz", + "integrity": "sha512-xsCb5EbmLWNlQ8v5zQIgSYSyf1rSyVPjh8p9G2xviOl1weHm8a611fHWUOGn7ISquCL6LoBKZvh0tcKmpVGgzw==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.9", - "@types/node": "^26.4.0" + "@types/estree": "^1.0.9" }, "engines": { "node": "^22.22.2 || >=24.15.0" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/undici-types": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", - "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", - "dev": true, - "license": "MIT" - }, "node_modules/eslint-plugin-jsonc": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-3.4.2.tgz", @@ -3034,9 +2981,9 @@ } }, "node_modules/eslint-plugin-n": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-18.3.0.tgz", - "integrity": "sha512-cPVguuDe6DrIPb/qUXHf8P89MaVTUmiYWwpt5gX5AILsvRIiZAxMFXcFR6QHYBksqKJpjfUBlL/RleCJUWcD7w==", + "version": "18.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-18.5.0.tgz", + "integrity": "sha512-M7uF6MTN/An+AXqvyIbXq7npJIZOkd5eKo8iMMvWrcDVNyZVdA6TF2lw01aKQfCEidRfpnR78GhAjZorlXNHiw==", "dev": true, "license": "MIT", "dependencies": { @@ -3047,6 +2994,7 @@ "globals": "^15.11.0", "globrex": "^0.1.2", "ignore": "^5.3.2", + "js-yaml": "^5.4.1", "semver": "^7.6.3" }, "engines": { @@ -3103,13 +3051,14 @@ } }, "node_modules/eslint-plugin-perfectionist": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-5.11.0.tgz", - "integrity": "sha512-kZV1otBcu4xT5R1p+0x1N1wRv4pS+OIbxrA47n5a1fTnN3MWbexOx5eQgbQhGyCNbpvF/rqrbnpkGjumHF+Y0Q==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-5.12.1.tgz", + "integrity": "sha512-krdSE7Dz+TCtcVr2+rfNhlOIFFBJcUdoRvjaN7JQnsaVnxJw+BZh9wMkY3MSLCJat+yW+UPTQLKS82Epc7MGZA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^8.68.0", + "@typescript-eslint/types": "^8.70.0", + "@typescript-eslint/utils": "^8.70.0", "natural-orderby": "^5.0.0" }, "engines": { @@ -3117,6 +3066,11 @@ }, "peerDependencies": { "eslint": "^8.45.0 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/eslint-plugin-pnpm": { @@ -3150,9 +3104,9 @@ } }, "node_modules/eslint-plugin-regexp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-3.3.0.tgz", - "integrity": "sha512-TT0JTQbW7CRKohntpGAsMdQ1K3MsmJK4gdAhKJtIwlJ0JvuYxauymFgJdvqxIY4lqNj0EuRZWVrymQtEdJYEFg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-3.3.1.tgz", + "integrity": "sha512-58bGUci/AaWAo1ETj6Lsnmy6QXwnSyVONRA805828nnqp7vrTwdaQMc02vtowmYB3A5OB3SLr3r5HgmfxX4dLg==", "dev": true, "license": "MIT", "dependencies": { @@ -3194,6 +3148,57 @@ "eslint": ">=9.38.0" } }, + "node_modules/eslint-plugin-unicorn": { + "version": "74.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-74.0.0.tgz", + "integrity": "sha512-AGnsGi2SxHg1HEAXxn9nSnZfyjvTWkxm8E8hpd/9tD6dLjBUdcD7+D6ZN64HmmCXTSXlrwVyUqe20Uyb2CaurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.10.1", + "@eslint/css-tree": "^4.0.5", + "browserslist": "^4.28.8", + "change-case": "^5.4.4", + "ci-info": "^4.4.0", + "core-js-compat": "^3.50.0", + "detect-indent": "^7.0.2", + "entities": "^8.0.0", + "find-up-simple": "^1.0.1", + "globals": "^17.11.0", + "indent-string": "^5.0.0", + "is-builtin-module": "^5.0.0", + "is-identifier": "^1.1.0", + "pluralize": "^8.0.0", + "quote-js-string": "^0.1.0", + "regjsparser": "^0.13.2", + "reserved-identifiers": "^1.2.0", + "semver": "^7.8.5", + "strip-indent": "^4.1.1", + "yaml": "^2.9.0" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=10.4" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/entities": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.1.0.tgz", + "integrity": "sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/eslint-plugin-unused-imports": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.4.1.tgz", @@ -3211,9 +3216,9 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.11.0.tgz", - "integrity": "sha512-fGt38SsaPCZ2FmA3bX/3vOW2qdsPNx0/9x+7Aab6NMX++PhynMtK4LWC4vzXgfQBCqpUAler18H38GA+NBAd0Q==", + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.11.1.tgz", + "integrity": "sha512-pasVXhl7wUmIvhujoqs/m0mJ9r59QW1IR9XXYKGR0FETzSM+Hhlf4qKIYgWiDDP+9YKv4YfbwskD7LqIdVcgQw==", "dev": true, "license": "MIT", "dependencies": { @@ -3243,9 +3248,9 @@ } }, "node_modules/eslint-plugin-yml": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-3.8.1.tgz", - "integrity": "sha512-E/70psRwxz5EJ8dBtzrFfqSiiInuSytbdtFCjueb/GcKjsWzPBfxfhtQePImMAPjHwMA/VDurO7DJwStDJ4wWg==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-3.9.0.tgz", + "integrity": "sha512-o4ByMVFd/mGc0Q/vJmbG9pz7Kyg/BiKAGnWCzvMLqzpa2KMdpUrLgF5a6yYeL2mf1Br/9dckd0ADl3vw7uF+jA==", "dev": true, "license": "MIT", "dependencies": { @@ -3450,9 +3455,9 @@ } }, "node_modules/exsolve": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.1.tgz", - "integrity": "sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.3.tgz", + "integrity": "sha512-kuzL9zherLQoqDeQaS55AiiIg1kb4KYXaSusTtgZTPlvKP2gGCI82LNmBNh5RjDVUXIcmgx+/Mx7vPwRzBbhJA==", "dev": true, "license": "MIT" }, @@ -3690,9 +3695,9 @@ } }, "node_modules/globals": { - "version": "17.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz", - "integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==", + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.13.0.tgz", + "integrity": "sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==", "dev": true, "license": "MIT", "engines": { @@ -3781,9 +3786,9 @@ } }, "node_modules/ignore": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.8.tgz", - "integrity": "sha512-YYNsSlXBjMk92SKnkwvB5LOVSa6OznlFUGcsvrFgNJbJCd0M1XKeFVRc8ZByeCqz32FivYNHJVooLmdqrmvp/Q==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.13.tgz", + "integrity": "sha512-2E8Q6rh+1RRSq/YdaGsNfXsEZy9FVqv6BSSrkmZJP7BnaoPnRfKL+YaofPvP+5rzdk144qSm6i4+hvPgUcbV4Q==", "dev": true, "license": "MIT", "engines": { @@ -3891,9 +3896,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.3.tgz", - "integrity": "sha512-yzzNtgczwgoVHNigCyKTXcQJU4Y8t/ikU4UxXW0BvrLfHTGWZhsNcOT2s/a7vn81/4KqVnNmHjaUEPlvWnNwVw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.5.0.tgz", + "integrity": "sha512-paNr4LFIFPjeeSmwNYdrb8FafLLG/Cr2Af3GjbsHJ5CxIjH4r0c2emlmRdAtpPAieP1gRVzk6buBbVP5gBMGAg==", "funding": [ { "type": "github", @@ -3906,7 +3911,7 @@ ], "license": "MIT", "dependencies": { - "argparse": "^2.0.1" + "argparse": "^3.0.3" }, "bin": { "js-yaml": "bin/js-yaml.mjs" @@ -3989,6 +3994,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/jsonc-eslint-parser/node_modules/verkit": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/verkit/-/verkit-0.3.2.tgz", + "integrity": "sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/katex": { "version": "0.16.47", "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", @@ -4426,9 +4444,9 @@ } }, "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.3.tgz", + "integrity": "sha512-xPgpDNl0/OXHsI7TlaIs22lWnH3KlpvZdXG1ET/m/YT2Hhdkx8lJV4kLphE6l9simyM4KPDFBwas08BgEob6Jw==", "dev": true, "license": "MIT", "dependencies": { @@ -4456,9 +4474,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", - "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.1.0.tgz", + "integrity": "sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==", "dev": true, "license": "MIT", "dependencies": { @@ -4569,9 +4587,9 @@ } }, "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.1.tgz", + "integrity": "sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==", "dev": true, "license": "MIT", "dependencies": { @@ -4655,9 +4673,9 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.2.0.tgz", + "integrity": "sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==", "dev": true, "license": "MIT", "dependencies": { @@ -4666,8 +4684,10 @@ "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", + "micromark-util-character": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" }, @@ -4691,16 +4711,16 @@ } }, "node_modules/mdn-data": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.34.0.tgz", - "integrity": "sha512-OgIlLv0NxJKVW4GTSAoEgpRGd4F2XCqGinK0MsMlBCCS/Zcm2/LsbercNWNA7PeMMcjl75NnI97eqyo7zkdxWA==", + "version": "2.37.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.37.2.tgz", + "integrity": "sha512-rz9YOBGItdSbe7HcSArUbhiAv4SB/4DKRYg96CSFS2CcIYMbUvBtZlzA1NCbk2AdgbmYwMqwNblLpR441lLeiQ==", "dev": true, "license": "CC0-1.0" }, "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.3.tgz", + "integrity": "sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==", "dev": true, "funding": [ { @@ -4724,6 +4744,7 @@ "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", @@ -4734,9 +4755,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.4.tgz", + "integrity": "sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==", "dev": true, "funding": [ { @@ -4754,18 +4775,19 @@ "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", + "micromark-factory-space": "^2.1.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "micromark-util-types": "^2.0.3" } }, "node_modules/micromark-extension-frontmatter": { @@ -4864,9 +4886,9 @@ } }, "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.2.tgz", + "integrity": "sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==", "dev": true, "license": "MIT", "dependencies": { @@ -4979,9 +5001,9 @@ } }, "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.1.0.tgz", + "integrity": "sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==", "dev": true, "funding": [ { @@ -5172,6 +5194,26 @@ "micromark-util-symbol": "^2.0.0" } }, + "node_modules/micromark-util-edit-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-edit-map/-/micromark-util-edit-map-1.0.0.tgz", + "integrity": "sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, "node_modules/micromark-util-encode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", @@ -5309,9 +5351,9 @@ "license": "MIT" }, "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz", + "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==", "dev": true, "funding": [ { @@ -5374,9 +5416,9 @@ } }, "node_modules/module-replacements": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-3.3.0.tgz", - "integrity": "sha512-AVZL23uePazQOZlb/QMGwxsUa1oWA62Cfe6ApPzgasUoF4cdCWAiRPVq4KkaQzXbIDAlpLhLG61Jx8Lju4wjTg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-3.4.0.tgz", + "integrity": "sha512-NKBNFM/uAUvSs+LOYfSly4EwrC9bgMoFuEnqNNjcDb910W+5IgS2KMB2ERLm5YZZm7R187jx1dMA9pOPvqbSbw==", "dev": true, "license": "MIT" }, @@ -5444,9 +5486,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.18", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", - "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", "dev": true, "funding": [ { @@ -5481,9 +5523,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.54", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz", - "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==", + "version": "2.0.59", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.59.tgz", + "integrity": "sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA==", "dev": true, "license": "MIT", "engines": { @@ -5611,9 +5653,9 @@ } }, "node_modules/package-manager-detector": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.8.0.tgz", - "integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.9.0.tgz", + "integrity": "sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==", "dev": true, "license": "MIT" }, @@ -5734,9 +5776,9 @@ } }, "node_modules/postcss": { - "version": "8.5.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", - "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "version": "8.5.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.31.tgz", + "integrity": "sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==", "dev": true, "funding": [ { @@ -5755,9 +5797,9 @@ "license": "MIT", "peer": true, "dependencies": { - "nanoid": "^3.3.18", + "nanoid": "^3.3.20", "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "source-map-js": "^1.2.2" }, "engines": { "node": "^10 || ^12 || >=14" @@ -5875,9 +5917,9 @@ } }, "node_modules/regjsparser": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.2.tgz", - "integrity": "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==", + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.4.tgz", + "integrity": "sha512-EWV80YgFaVgFrjGCAsV7oybp4GOxbls5RzBg8OB0nKEVXsBJR1JlV8Di1JhCROg3MzTfe1RI8yitIm1eOs68iA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5918,14 +5960,14 @@ "license": "MIT" }, "node_modules/rolldown": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz", - "integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.14.tgz", + "integrity": "sha512-eTBTTqMR6uHKLgcUqpJP8ntzDI6V4LYA8negAMBEI7gkgVvOdrx6VsvS2Ym+83KhOPdLCHWJu0w7UQFJZhHKNw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@oxc-project/types": "=0.152.0", + "@oxc-project/types": "=0.154.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -5935,21 +5977,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.12", - "@rolldown/binding-android-arm64": "1.2.12", - "@rolldown/binding-darwin-arm64": "1.2.12", - "@rolldown/binding-darwin-x64": "1.2.12", - "@rolldown/binding-freebsd-x64": "1.2.12", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", - "@rolldown/binding-linux-arm64-gnu": "1.2.12", - "@rolldown/binding-linux-arm64-musl": "1.2.12", - "@rolldown/binding-linux-ppc64-gnu": "1.2.12", - "@rolldown/binding-linux-s390x-gnu": "1.2.12", - "@rolldown/binding-linux-x64-gnu": "1.2.12", - "@rolldown/binding-linux-x64-musl": "1.2.12", - "@rolldown/binding-openharmony-arm64": "1.2.12", - "@rolldown/binding-win32-arm64-msvc": "1.2.12", - "@rolldown/binding-win32-x64-msvc": "1.2.12" + "@rolldown/binding-android-arm-eabi": "1.2.14", + "@rolldown/binding-android-arm64": "1.2.14", + "@rolldown/binding-darwin-arm64": "1.2.14", + "@rolldown/binding-darwin-x64": "1.2.14", + "@rolldown/binding-freebsd-x64": "1.2.14", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.14", + "@rolldown/binding-linux-arm64-gnu": "1.2.14", + "@rolldown/binding-linux-arm64-musl": "1.2.14", + "@rolldown/binding-linux-ppc64-gnu": "1.2.14", + "@rolldown/binding-linux-s390x-gnu": "1.2.14", + "@rolldown/binding-linux-x64-gnu": "1.2.14", + "@rolldown/binding-linux-x64-musl": "1.2.14", + "@rolldown/binding-openharmony-arm64": "1.2.14", + "@rolldown/binding-win32-arm64-msvc": "1.2.14", + "@rolldown/binding-win32-x64-msvc": "1.2.14" } }, "node_modules/scslre": { @@ -5981,9 +6023,9 @@ } }, "node_modules/set-cookie-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.2.tgz", - "integrity": "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.4.tgz", + "integrity": "sha512-iEmdEew+Tn1BwMGMP8LzGBEPC7Mf1sySjglCeEPb/Vchm9bnGezePvacYcId+fGprQzIng+TBkzqfJ/qS7AsBg==", "dev": true, "license": "MIT" }, @@ -6059,9 +6101,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.23", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", - "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "version": "3.0.24", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.24.tgz", + "integrity": "sha512-cLS9TtWkIQFyLkJ3/5aFQAOHOSKTlOs/7WDut/XPSdjom1fJhUdkepeJAKXa9Y05+FabHd0sti+Et559vDtkpQ==", "dev": true, "license": "CC0-1.0" }, @@ -6243,22 +6285,22 @@ } }, "node_modules/tldts": { - "version": "7.4.12", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.12.tgz", - "integrity": "sha512-WylhSDKVeYnWXL3a+vKTaOxjnOeEGw938hImY8zoRWJjRRK/Jp1K+IihBzIONpUmW4e3WmXT6q5FW6vlESVZCA==", + "version": "7.4.18", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.18.tgz", + "integrity": "sha512-somxA8xKAUzlAxl0TX/jMSYIbRNFIVGnI96pVGJPeMc5BsHmfVXn6mOJT6U++ELnl04eGfzpfcEuZe8WiASkXg==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.4.12" + "tldts-core": "^7.4.18" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.4.12", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.12.tgz", - "integrity": "sha512-nYNzS2WRf4QJmjzFFgAxLOBjyBxAGRbCy9PVBPaglcYyYajh40VBn+v5Ngr96ZMc7oM0+aCJdtQnNejvdBnXMQ==", + "version": "7.4.18", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.18.tgz", + "integrity": "sha512-KI2PKvCmvQI/xD6ypPqkU0i7oxNXR/O58RLRaHR4svsgVUQ2JE/XC8BtMbG6PSehD27I8sZJRcC1ASnCy6lp3g==", "dev": true, "license": "MIT" }, @@ -6357,9 +6399,9 @@ } }, "node_modules/type-fest": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.9.0.tgz", - "integrity": "sha512-yANm3Jr3GiJ1qgJlxGAVxTOIcEOk1rhQHamlXtnrCK7EHP4HeM9OGxtMg/W7HFdrVzw/ZWJKGVIJusVH85sLtw==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.10.0.tgz", + "integrity": "sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==", "dev": true, "license": "(MIT OR CC0-1.0)", "dependencies": { @@ -6394,9 +6436,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.28.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", - "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", + "version": "6.29.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.1.tgz", + "integrity": "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==", "license": "MIT", "engines": { "node": ">=18.17" @@ -6500,9 +6542,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz", - "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", "dev": true, "funding": [ { @@ -6548,9 +6590,9 @@ "license": "MIT" }, "node_modules/verkit": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/verkit/-/verkit-0.3.2.tgz", - "integrity": "sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/verkit/-/verkit-0.4.1.tgz", + "integrity": "sha512-mMVzj0TXExtVdlDEq+Mzp0eyOuyznNpFobNM3uAqe3HVm/Ps2c+u17BligMkZjZCA6EiXpoon8iRTer3iu40SQ==", "dev": true, "license": "MIT", "engines": { @@ -6561,17 +6603,17 @@ } }, "node_modules/vite": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.1.tgz", - "integrity": "sha512-/bvH9E9tmCXRGp2uXY3WbOldqpTwFkbha/8ANaEQ6VkxhH60KyqLwgZq6lG2y+4uT55x9+9eUHMpQ7uGnOCKjA==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.4.tgz", + "integrity": "sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.7", - "postcss": "^8.5.28", - "rolldown": "~1.2.9", + "postcss": "^8.5.29", + "rolldown": "~1.2.12", "tinyglobby": "^0.2.17" }, "bin": { @@ -6640,14 +6682,14 @@ } }, "node_modules/vitest": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.4.tgz", - "integrity": "sha512-z0WxZRV2Sg48wF0FSgMq3TFG8JS38/Qr96vZVZdX6+Em9raQTvnXQvdTFJe2m3rfyJnEHeHQ/snceIdi8D1pVg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.5.tgz", + "integrity": "sha512-cPODOMF8YnkiiYtDdHo6n4wWmBrOBBbOIYH2d33M4l3CdNn72h+qMmO6uXffUN6A5AZFXNND/d+krS9mgkXRfg==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/mocker": "5.0.4", + "@vitest/mocker": "5.0.5", "chai": "^6.3.0", "es-module-lexer": "^2.3.2", "expect-type": "^1.4.0", @@ -6673,12 +6715,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "5.0.4", - "@vitest/browser-preview": "5.0.4", + "@vitest/browser-playwright": "5.0.5", + "@vitest/browser-preview": "5.0.5", "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", - "@vitest/coverage-istanbul": "5.0.4", - "@vitest/coverage-v8": "5.0.4", - "@vitest/ui": "5.0.4", + "@vitest/coverage-istanbul": "5.0.5", + "@vitest/coverage-v8": "5.0.5", + "@vitest/ui": "5.0.5", "happy-dom": "*", "jsdom": "*", "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" @@ -6859,9 +6901,9 @@ } }, "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", + "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", "dev": true, "license": "ISC", "bin": { diff --git a/src/cronJobs/sweep.ts b/src/cronJobs/sweep.ts index 303be450..43186e9f 100644 --- a/src/cronJobs/sweep.ts +++ b/src/cronJobs/sweep.ts @@ -1,4 +1,5 @@ import type { Octokit, RestEndpointMethodTypes } from '@octokit/rest' +import type { BlunderbussSettings } from '../plugins/blunderbuss' import type { ProwConfig } from '../utils/config' import type { Context } from '../utils/context' @@ -47,6 +48,11 @@ const pageSize = 100 * failure on one is collected and the rest still run. The run fails at the * end listing the failures. * + * With `blunderbuss.delay` the window reaches back a further `delay`: a pull + * request opened (or marked ready) inside the shifted window is due for + * reviewers now, even when nothing has touched it since. Those older pull + * requests get the blunderbuss step only. + * * @param context - the github actions event context * @param now - the current time, injectable for tests */ @@ -55,16 +61,30 @@ export async function sweep(context: Context = github.context, now: Date = new D const config = await loadProwConfig(octokit, context) const lookbackMs = resolveSweepLookback(config.sweep) const since = new Date(now.getTime() - lookbackMs) + const reviewers = blunderbussSettings(config) + const due: DueWindow = { from: new Date(since.getTime() - reviewers.delay), to: new Date(now.getTime() - reviewers.delay) } - const candidates = await recentlyUpdatedPulls(octokit, context, since) + const listed = await recentlyUpdatedPulls(octokit, context, due.from) + const candidates = listed.filter(pr => new Date(pr.updated_at) >= since) + const delayedOnly = listed.filter(pr => new Date(pr.updated_at) < since) core.info(`sweep: ${candidates.length} candidate${candidates.length === 1 ? '' : 's'} updated since ${since.toISOString()}`) + if (reviewers.delay > 0) { + core.info(`sweep: ${delayedOnly.length} more checked for delayed reviewers, updated since ${due.from.toISOString()}`) + } const result: SweepResult = { candidates: candidates.map(pr => pr.number), merged: [], enqueued: [], failures: [] } - if (candidates.length === 0) { - return result - } + const plugins = { lgtm: lgtmSettings(config), config, reviewers, since, due } - const plugins = { lgtm: lgtmSettings(config), config, since } + await forEachLimited(delayedOnly, sweepConcurrency, async (pr) => { + try { + if (await branchHasOwners(octokit, context, pr.base.ref)) { + await requestReviewersIfDue(octokit, context, pr, plugins) + } + } + catch (e) { + result.failures.push({ number: pr.number, message: `blunderbuss: ${e instanceof Error ? e.message : String(e)}` }) + } + }) await forEachLimited(candidates, sweepConcurrency, async (pr) => { const outcome = await sweepPullRequest(octokit, context, pr, plugins) @@ -86,10 +106,18 @@ export async function sweep(context: Context = github.context, now: Date = new D return result } +/** pull requests that became ready for review inside this window are due for delayed reviewers */ +interface DueWindow { + from: Date + to: Date +} + interface SweepPlugins { lgtm: ReturnType config: ProwConfig + reviewers: BlunderbussSettings since: Date + due: DueWindow } interface PullOutcome { @@ -106,7 +134,9 @@ async function sweepPullRequest(octokit: Octokit, context: Context, pr: PullsLis const tide = await loadTide(octokit, context, pr.base.ref) const ownersSteps: Step[] = [ ['owners-label', () => applyOwnersLabels(octokit, context, pr.number)], - ['blunderbuss', () => requestReviewersIfFresh(octokit, context, pr, plugins)], + ['blunderbuss', () => plugins.reviewers.delay > 0 + ? requestReviewersIfDue(octokit, context, pr, plugins) + : requestReviewersIfFresh(octokit, context, pr, plugins)], ['approve', () => evaluateApproval(octokit, context, pr.number)], ] const steps: Step[] = [ @@ -160,7 +190,63 @@ async function requestReviewersIfFresh(octokit: Octokit, context: Context, pr: P return } - await requestOwnersReviewers(octokit, context, pr.number, blunderbussSettings(plugins.config), { explicit: false, rng: Math.random }) + await requestOwnersReviewers(octokit, context, pr.number, plugins.reviewers, { explicit: false, rng: Math.random }) +} + +/** + * requestReviewersIfDue is blunderbuss with `delay`: a pull request whose + * review clock (opened, or the last `ready_for_review` when drafts are + * ignored) started inside the due window, and that still has no requested + * reviewer or team and no review, gets reviewers now. + */ +async function requestReviewersIfDue(octokit: Octokit, context: Context, pr: PullsListItem, plugins: SweepPlugins): Promise { + const { reviewers: settings, due } = plugins + if (settings.ignore_drafts && pr.draft === true) { + core.debug(`sweep: #${pr.number} is a draft`) + return + } + if ((pr.requested_reviewers ?? []).length > 0 || (pr.requested_teams ?? []).length > 0) { + core.debug(`sweep: #${pr.number} already has requested reviewers`) + return + } + + let start = new Date(pr.created_at) + if (start > due.to) { + core.debug(`sweep: #${pr.number} is not due for reviewers before ${new Date(start.getTime() + settings.delay).toISOString()}`) + return + } + if (settings.ignore_drafts) { + const ready = await lastReadyForReview(octokit, context, pr.number) + if (ready !== undefined && ready > start) { + start = ready + } + } + if (start < due.from || start > due.to) { + core.debug(`sweep: #${pr.number} became ready at ${start.toISOString()}, outside the due window`) + return + } + + const { data: reviews } = await octokit.pulls.listReviews({ ...context.repo, pull_number: pr.number, per_page: 1 }) + if (reviews.length > 0) { + core.debug(`sweep: #${pr.number} already has reviews`) + return + } + + await requestOwnersReviewers(octokit, context, pr.number, settings, { explicit: false, rng: Math.random }) +} + +async function lastReadyForReview(octokit: Octokit, context: Context, pullNumber: number): Promise { + let events: Array<{ event?: string, created_at?: string }> + try { + events = await octokit.paginate(octokit.issues.listEventsForTimeline, { ...context.repo, issue_number: pullNumber, per_page: 100 }) as Array<{ event?: string, created_at?: string }> + } + catch (e) { + throw new Error(`could not read the timeline: ${e}`) + } + const times = events + .filter(event => event.event === 'ready_for_review' && event.created_at !== undefined) + .map(event => new Date(event.created_at!).getTime()) + return times.length === 0 ? undefined : new Date(Math.max(...times)) } async function recentlyUpdatedPulls(octokit: Octokit, context: Context, since: Date): Promise { diff --git a/src/plugins/blunderbuss.ts b/src/plugins/blunderbuss.ts index 0f57ab3e..50831c3f 100644 --- a/src/plugins/blunderbuss.ts +++ b/src/plugins/blunderbuss.ts @@ -6,6 +6,7 @@ import * as core from '@actions/core' import * as github from '@actions/github' import { loadProwConfig } from '../utils/config' +import { parseDuration } from '../utils/duration' import { newOctokit } from '../utils/octokit' import { loadPullRequestOwners } from '../utils/pullRequestOwners' @@ -15,6 +16,8 @@ export interface BlunderbussSettings { exclude_approvers: boolean ignore_drafts: boolean ignore_authors: string[] + /** milliseconds to wait before requesting; 0 requests on the event itself */ + delay: number } export type Rng = () => number @@ -33,6 +36,7 @@ export function blunderbussSettings(config: ProwConfig): BlunderbussSettings { exclude_approvers: raw.exclude_approvers ?? false, ignore_drafts: raw.ignore_drafts ?? true, ignore_authors: (raw.ignore_authors ?? []).map(login => login.toLowerCase()), + delay: parseDuration(raw.delay, 'blunderbuss.delay'), } } @@ -78,6 +82,7 @@ function sample(items: string[], count: number, rng: Rng): string[] { * blunderbuss is the `pull_request` handler modelled on Prow's blunderbuss * plugin: on `opened` (and `ready_for_review` when drafts are ignored) it * requests reviews from the OWNERS reviewers covering the changed files. + * With `blunderbuss.delay` it defers to the `sweep` job instead. * * @param context - the github context of the current action event * @param rng - a source of numbers in [0, 1), injectable for tests @@ -102,6 +107,11 @@ export async function blunderbuss(context: Context = github.context, rng: Rng = return } + if (settings.delay > 0) { + core.info(`blunderbuss: #${pullNumber} ${action}; blunderbuss.delay is set, so the sweep job requests reviewers once it is due and nobody has been asked`) + return + } + await requestOwnersReviewers(octokit, context, pullNumber, settings, { explicit: false, rng }) } diff --git a/src/utils/config.ts b/src/utils/config.ts index c71efa2f..26e2a79a 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -72,6 +72,8 @@ export interface BlunderbussConfig { ignore_drafts?: boolean /** pull request authors that never get reviewers assigned */ ignore_authors?: string[] + /** wait this long after `opened` (or `ready_for_review`) and request only if nobody asked for a review meanwhile, ex: `1h`; default 0, at most 24h; the `sweep` job does the request */ + delay?: string } export interface ApproveConfig { @@ -169,6 +171,7 @@ export const defaultAuthorization: ResolvedAuthorization = { } export const defaultSweepLookback = '1h' +export const maxBlunderbussDelayMs = 24 * 3_600_000 export const maxSweepLookbackMs = 24 * 3_600_000 /** repositories of the owner that may hold an organization wide prow.yaml, in precedence order */ @@ -603,12 +606,29 @@ function normalizeBlunderbuss(source: string, raw: unknown): BlunderbussConfig { throw new Error(`${source}: blunderbuss.ignore_authors must be a list of GitHub usernames`) } + if (raw.delay !== undefined) { + if (typeof raw.delay !== 'string') { + throw new TypeError(`${source}: blunderbuss.delay must be a duration string such as 1h or 30m`) + } + let ms: number + try { + ms = parseDuration(raw.delay, 'blunderbuss.delay') + } + catch (e) { + throw new Error(`${source}: ${e instanceof Error ? e.message : e}`) + } + if (ms > maxBlunderbussDelayMs) { + throw new Error(`${source}: blunderbuss.delay must not be longer than 24h`) + } + } + return stripUndefined({ request_count: raw.request_count as number | undefined, max_request_count: raw.max_request_count as number | undefined, exclude_approvers: raw.exclude_approvers as boolean | undefined, ignore_drafts: raw.ignore_drafts as boolean | undefined, ignore_authors: raw.ignore_authors as string[] | undefined, + delay: raw.delay as string | undefined, }) } From 094c1f589abf3fe3ecb7d3f8ac2a34b167bf3417 Mon Sep 17 00:00:00 2001 From: Bob Killen Date: Wed, 21 Oct 2026 09:10:59 -0500 Subject: [PATCH 2/3] chore: isolate blunderbuss delay from dependency churn Retain only the focused dependency changes from cncf/prow-github-actions#546 and regenerate the bundle from a clean install. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Bob Killen --- dist/index.js | 871 +++++++++++---------------------------- package-lock.json | 1000 ++++++++++++++++++++++----------------------- 2 files changed, 710 insertions(+), 1161 deletions(-) diff --git a/dist/index.js b/dist/index.js index 602c3173..6a2f9265 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,7 +1,7 @@ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ -/***/ 9659: +/***/ 4844: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -55,7 +55,7 @@ exports.getProxyUrl = getProxyUrl; exports.isHttps = isHttps; const http = __importStar(__nccwpck_require__(8611)); const https = __importStar(__nccwpck_require__(5692)); -const pm = __importStar(__nccwpck_require__(3335)); +const pm = __importStar(__nccwpck_require__(4988)); const tunnel = __importStar(__nccwpck_require__(770)); const undici_1 = __nccwpck_require__(6752); var HttpCodes; @@ -745,7 +745,7 @@ const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCa /***/ }), -/***/ 3335: +/***/ 4988: /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -4102,77 +4102,11 @@ class Request { } } - /** - * @param {number|null} statusCode - * @param {Buffer[]|null} headers - * @param {import('node:stream').Duplex} socket - * @param {string} [statusText] - */ - onUpgrade (statusCode, headers, socket, statusText = '') { - this.onFinally() - + onUpgrade (statusCode, headers, socket) { assert(!this.aborted) assert(!this.completed) - if (statusCode !== null) { - this.#publishUpgradeHeaders(statusCode, headers, statusText) - } - - const result = this[kHandler].onUpgrade(statusCode, headers, socket) - - if (!this.aborted) { - this.completed = true - if (statusCode !== null) { - this.#publishUpgradeTrailers() - } - } - - return result - } - - /** - * @param {number} statusCode - * @param {import('node:http2').IncomingHttpHeaders} headers - * @param {(headers: import('node:http2').IncomingHttpHeaders) => Buffer[]} parseHeaders - * @param {string} [statusText] - */ - onUpgradeResponse (statusCode, headers, parseHeaders, statusText = '') { - assert(!this.aborted) - assert(this.completed) - - if (channels.headers.hasSubscribers) { - this.#publishUpgradeHeaders(statusCode, parseHeaders(headers), statusText) - } - this.#publishUpgradeTrailers() - } - - /** - * @param {Error} error - */ - onUpgradeError (error) { - assert(!this.aborted) - assert(this.completed) - - if (channels.error.hasSubscribers) { - channels.error.publish({ request: this, error }) - } - } - - /** - * @param {number} statusCode - * @param {Buffer[]} headers - * @param {string} statusText - */ - #publishUpgradeHeaders (statusCode, headers, statusText) { - if (channels.headers.hasSubscribers) { - channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) - } - } - - #publishUpgradeTrailers () { - if (channels.trailers.hasSubscribers) { - channels.trailers.publish({ request: this, trailers: [] }) - } + return this[kHandler].onUpgrade(statusCode, headers, socket) } onComplete (trailers) { @@ -5313,7 +5247,7 @@ function defaultFactory (origin, opts) { } class Agent extends DispatcherBase { - constructor ({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { + constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { if (typeof factory !== 'function') { throw new InvalidArgumentError('factory must be a function.') } @@ -5332,15 +5266,11 @@ class Agent extends DispatcherBase { connect = { ...connect } } - if (tls && typeof tls !== 'function') { - tls = { ...tls } - } - this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })] - this[kOptions] = { ...util.deepClone(options), connect, tls } + this[kOptions] = { ...util.deepClone(options), connect } this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : undefined @@ -6080,7 +6010,7 @@ class Parser { } onUpgrade (head) { - const { upgrade, client, socket, headers, statusCode, statusText } = this + const { upgrade, client, socket, headers, statusCode } = this assert(upgrade) assert(client[kSocket] === socket) @@ -6115,10 +6045,9 @@ class Parser { client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) try { - request.onUpgrade(statusCode, headers, socket, statusText) - } catch (error) { - util.errorRequest(client, request, error) - util.destroy(socket, error) + request.onUpgrade(statusCode, headers, socket) + } catch (err) { + util.destroy(socket, err) } client[kResume]() @@ -6375,6 +6304,8 @@ async function connectH1 (client, socket) { socket[kParser] = new Parser(client, socket, llhttpInstance) addListener(socket, 'error', function (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 @@ -6697,22 +6628,12 @@ function writeH1 (client, request) { const socket = client[kSocket] clearIdleSocketValidation(socket) - /** - * @param {Error} [error] - */ - const abort = (error) => { - if (request.aborted) { - return - } - - if (request.completed) { - if (request.upgrade || request.method === 'CONNECT') { - util.destroy(socket, new InformationalError('aborted')) - } + const abort = (err) => { + if (request.aborted || request.completed) { return } - util.errorRequest(client, request, error || new RequestAbortedError()) + util.errorRequest(client, request, err || new RequestAbortedError()) util.destroy(body) util.destroy(socket, new InformationalError('aborted')) @@ -7170,7 +7091,6 @@ module.exports = connectH1 const assert = __nccwpck_require__(4589) -const { errorMonitor } = __nccwpck_require__(8474) const { pipeline } = __nccwpck_require__(7075) const util = __nccwpck_require__(3440) const { @@ -7247,15 +7167,6 @@ function parseH2Headers (headers) { return result } -/** - * @param {import('node:http2').IncomingHttpHeaders} headers - * @returns {Buffer[]} - */ -function parseH2ResponseHeaders (headers) { - const { [HTTP2_HEADER_STATUS]: _statusCode, ...realHeaders } = headers - return parseH2Headers(realHeaders) -} - async function connectH2 (client, socket) { client[kSocket] = socket @@ -7305,6 +7216,8 @@ async function connectH2 (client, socket) { socket[kHTTP2Session] = session util.addListener(socket, 'error', function (err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + this[kError] = err this[kClient][kOnError](err) @@ -7378,6 +7291,8 @@ function resumeH2 (client) { } function onHttp2SessionError (err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + this[kSocket][kError] = err this[kClient][kOnError](err) } @@ -7472,32 +7387,22 @@ function writeH2 (client, request) { headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ''}` headers[HTTP2_HEADER_METHOD] = method - /** - * @param {Error} [error] - */ - const abort = (error) => { - if (request.aborted) { + const abort = (err) => { + if (request.aborted || request.completed) { return } - if (request.completed) { - if (method === 'CONNECT' && stream != null) { - util.destroy(stream, error || new RequestAbortedError()) - } - return - } - - error = error || new RequestAbortedError() + err = err || new RequestAbortedError() - util.errorRequest(client, request, error) + util.errorRequest(client, request, err) if (stream != null) { - util.destroy(stream, error) + util.destroy(stream, err) } // We do not destroy the socket as we can continue using the session // the stream get's destroyed and the session remains to create new streams - util.destroy(body, error) + util.destroy(body, err) client[kQueue][client[kRunningIdx]++] = null client[kResume]() } @@ -7516,57 +7421,25 @@ function writeH2 (client, request) { if (method === 'CONNECT') { session.ref() + // We are already connected, streams are pending, first request + // will create a new stream. We trigger a request to create the stream and wait until + // `ready` event is triggered // We disabled endStream to allow the user to write to the stream stream = session.request(headers, { endStream: false, signal }) - let upgradeResponseFinished = false - /** - * @param {import('node:http2').IncomingHttpHeaders} headers - */ - const onResponse = (headers) => { - upgradeResponseFinished = true - stream.off(errorMonitor, onUpgradeError) - request.onUpgradeResponse(Number(headers[HTTP2_HEADER_STATUS]), headers, parseH2ResponseHeaders) - } - - /** - * @param {Error} error - */ - const onUpgradeError = (error) => { - upgradeResponseFinished = true - stream.off('response', onResponse) - request.onUpgradeError(error) - } - - const onReady = () => { - try { - request.onUpgrade(null, null, stream) - } catch (error) { - stream.off('response', onResponse) - abort(error) - return - } - - if (request.aborted) { - return - } - - stream.off('error', abort) - stream.once(errorMonitor, onUpgradeError) + if (stream.id && !stream.pending) { + request.onUpgrade(null, null, stream) + ++session[kOpenStreams] client[kQueue][client[kRunningIdx]++] = null + } else { + stream.once('ready', () => { + request.onUpgrade(null, null, stream) + ++session[kOpenStreams] + client[kQueue][client[kRunningIdx]++] = null + }) } - stream.once('response', onResponse) - stream.once('error', abort) - ++session[kOpenStreams] - onReady() - stream.once('close', () => { - if (!upgradeResponseFinished && request.completed) { - stream.off('response', onResponse) - stream.off(errorMonitor, onUpgradeError) - request.onUpgradeError(new InformationalError(`HTTP/2: "stream error" received - code ${stream.rstCode}`)) - } session[kOpenStreams] -= 1 if (session[kOpenStreams] === 0) session.unref() }) @@ -8076,10 +7949,9 @@ class Client extends DispatcherBase { // h2 maxConcurrentStreams, allowH2, - webSocket, - eventSource + webSocket } = {}) { - super({ webSocket, eventSource }) + super({ webSocket }) if (keepAlive !== undefined) { throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') @@ -8601,7 +8473,6 @@ module.exports = Client "use strict"; -const buffer = __nccwpck_require__(4573) const Dispatcher = __nccwpck_require__(883) const { ClientDestroyedError, @@ -8614,7 +8485,6 @@ const kOnDestroyed = Symbol('onDestroyed') const kOnClosed = Symbol('onClosed') const kInterceptedDispatch = Symbol('Intercepted Dispatch') const kWebSocketOptions = Symbol('webSocketOptions') -const kEventSourceOptions = Symbol('eventSourceOptions') class DispatcherBase extends Dispatcher { constructor (opts) { @@ -8625,7 +8495,6 @@ class DispatcherBase extends Dispatcher { this[kClosed] = false this[kOnClosed] = [] this[kWebSocketOptions] = opts?.webSocket ?? {} - this[kEventSourceOptions] = opts?.eventSource ?? {} } get webSocketOptions () { @@ -8635,12 +8504,6 @@ class DispatcherBase extends Dispatcher { } } - get eventSourceOptions () { - return { - maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength - } - } - get destroyed () { return this[kDestroyed] } @@ -10403,10 +10266,7 @@ class RetryHandler { this.retryCount += 1 if (statusCode >= 300) { - // Only expose a response if no earlier attempt has reached the caller. - // Otherwise abort this attempt so the error settles the existing body - // instead of replacing it with a new response. - if (!this.headersSent && this.retryOpts.statusCodes.includes(statusCode) === false) { + if (this.retryOpts.statusCodes.includes(statusCode) === false) { this.headersSent = true this.checkpointResponseEnd(headers, resume) return this.handler.onHeaders( @@ -15038,7 +14898,6 @@ module.exports = { "use strict"; -const buffer = __nccwpck_require__(4573) const { Transform } = __nccwpck_require__(7075) const { isASCIINumber, isValidLastEventId } = __nccwpck_require__(4811) @@ -15063,19 +14922,11 @@ 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 @@ -15114,12 +14965,6 @@ 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} @@ -15168,13 +15013,6 @@ 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, @@ -15185,7 +15023,6 @@ class EventSourceStream extends Transform { /** * @param {object} options - * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -15197,12 +15034,6 @@ 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 } @@ -15220,14 +15051,6 @@ 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 @@ -15306,12 +15129,7 @@ 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.parseLine(this.readLine(), this.event) 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 @@ -15320,28 +15138,15 @@ 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 + * @param {EventStreamEvent} event */ parseLine (line, event) { // If the line is empty (a blank line) @@ -15375,13 +15180,6 @@ 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) { @@ -15389,13 +15187,11 @@ 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 @@ -15403,27 +15199,18 @@ 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)) { - if (valueStart < line.length) { - this.setEventFieldSize('event', line.length - valueStart) - event.event = line.toString('utf8', valueStart) - } - } - } + const value = line.toString('utf8', valueStart) - setEventFieldSize (field, size) { - const eventSize = this.eventSize - this.eventFieldSizes[field] + size - if (this.maxEventSize > 0 && eventSize > this.maxEventSize) { - throw createMaxEventSizeExceededError() + if (value.length > 0) { + event.event = value + } } - this.eventSize = eventSize - this.eventFieldSizes[field] = size } /** @@ -15456,12 +15243,6 @@ 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 () { @@ -15497,16 +15278,14 @@ class EventSourceStream extends Transform { syncLineStartToCursor () { this.lineChunkIndex = this.chunkIndex this.linePos = this.pos - this.lineLength = 0 this.dropConsumedChunks() } dropConsumedChunks () { - if (this.lineChunkIndex > 0) { - const consumed = this.lineChunkIndex - this.chunks.splice(0, consumed) - this.lineChunkIndex = 0 - this.chunkIndex -= consumed + while (this.lineChunkIndex > 0) { + this.chunks.shift() + this.lineChunkIndex-- + this.chunkIndex-- } if (this.chunkIndex === this.chunks.length) { @@ -15632,7 +15411,6 @@ const { isNetworkError } = __nccwpck_require__(9051) const { delay } = __nccwpck_require__(4811) const { kEnumerableProperty } = __nccwpck_require__(3440) const { environmentSettingsObject } = __nccwpck_require__(3168) -const { getGlobalDispatcher } = __nccwpck_require__(2581) let experimentalWarned = false @@ -15914,7 +15692,6 @@ class EventSource extends EventTarget { const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, - maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -16093,8 +15870,7 @@ webidl.converters.EventSourceInitDict = webidl.dictionaryConverter([ }, { key: 'dispatcher', // undici only - converter: webidl.converters.any, - defaultValue: () => getGlobalDispatcher() + converter: webidl.converters.any } ]) @@ -21201,10 +20977,8 @@ async function httpNetworkFetch ( // 19. Run these steps in parallel: // 1. Run these steps, but abort when fetchParams is canceled: - if (!fetchParams.controller.resume) { - fetchParams.controller.on('terminated', onAborted) - } - + fetchParams.controller.onAborted = onAborted + fetchParams.controller.on('terminated', onAborted) fetchParams.controller.resume = async () => { // 1. While true while (true) { @@ -21373,6 +21147,8 @@ async function httpNetworkFetch ( } location = headersList.get('location', true) + this.body = new Readable({ read: resume }) + const decoders = [] const willFollow = location && request.redirect === 'follow' && @@ -21390,7 +21166,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) { - this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)) + reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)) return true } @@ -21423,8 +21199,6 @@ async function httpNetworkFetch ( } } - this.body = new Readable({ read: resume }) - const onError = this.onError.bind(this) resolve({ @@ -21471,6 +21245,10 @@ async function httpNetworkFetch ( fetchParams.controller.off('terminated', this.abort) } + if (fetchParams.controller.onAborted) { + fetchParams.controller.off('terminated', fetchParams.controller.onAborted) + } + fetchParams.controller.ended = true this.body.push(null) @@ -27961,20 +27739,6 @@ 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. - const socket = this.ws[kResponse].socket - if (this.#loop && socket.writableNeedDrain) { - this.#loop = false - socket.once('drain', () => { - if (this.destroyed) return - this.#loop = true - this.run(callback) - }) - return - } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -29776,7 +29540,7 @@ const external_path_namespaceObject = require("path"); var external_http_ = __nccwpck_require__(8611); // EXTERNAL MODULE: external "https" var external_https_ = __nccwpck_require__(5692); -;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/proxy.js +;// CONCATENATED MODULE: ./node_modules/@actions/core/node_modules/@actions/http-client/lib/proxy.js function getProxyUrl(reqUrl) { const usingSsl = reqUrl.protocol === 'https:'; if (checkBypass(reqUrl)) { @@ -29871,7 +29635,7 @@ class DecodedURL extends URL { var node_modules_tunnel = __nccwpck_require__(770); // EXTERNAL MODULE: ./node_modules/undici/index.js var undici = __nccwpck_require__(6752); -;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/index.js +;// CONCATENATED MODULE: ./node_modules/@actions/core/node_modules/@actions/http-client/lib/index.js /* eslint-disable @typescript-eslint/no-explicit-any */ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } @@ -30568,7 +30332,7 @@ class lib_HttpClient { } const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); //# sourceMappingURL=index.js.map -;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/auth.js +;// CONCATENATED MODULE: ./node_modules/@actions/core/node_modules/@actions/http-client/lib/auth.js var auth_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -32599,8 +32363,8 @@ class Context { } } //# sourceMappingURL=context.js.map -// EXTERNAL MODULE: ./node_modules/@actions/github/node_modules/@actions/http-client/lib/index.js -var lib = __nccwpck_require__(9659); +// EXTERNAL MODULE: ./node_modules/@actions/http-client/lib/index.js +var lib = __nccwpck_require__(4844); ;// CONCATENATED MODULE: ./node_modules/@actions/github/lib/internal/utils.js var utils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } @@ -33166,44 +32930,20 @@ var endpoint = withDefaults(null, DEFAULTS); * Copyright(c) 2015 Douglas Christopher Wilson * MIT Licensed */ -const SP = 32; // " " -const HTAB = 9; // "\t" -const SEMI = 59; // ";" -const EQ = 61; // "=" -const DQUOTE = 34; // '"' -const BSLASH = 92; // "\\" -const COMMA = 44; // "," -const LOWER_CASE = 1; -const OWS = 2; -const SEMI_FLAG = 4; -const COMMA_FLAG = 8; -const TOKEN_FLAG = 16; -const NON_ASCII = 0xff00; -const CASE_FLAGS = LOWER_CASE | NON_ASCII; +const TEXT_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]*$/; +const TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; /** - * Character flags used to normalize HTTP field values while scanning. - * Out-of-range reads intentionally coerce to zero in bitwise expressions. + * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4 */ -const CHAR_MAP = new Uint8Array(0x100); -CHAR_MAP[HTAB] |= OWS; -CHAR_MAP[SP] |= OWS; -CHAR_MAP[SEMI] |= SEMI_FLAG; -CHAR_MAP[COMMA] |= COMMA_FLAG; -for (let code = 0x80 /* non-ASCII */; code <= 0xff; code++) { - CHAR_MAP[code] |= LOWER_CASE; -} -for (const char of "!#$%&'*+-.^_`|~") { - CHAR_MAP[char.charCodeAt(0)] |= TOKEN_FLAG; -} -for (let code = 0x30 /* 0 */; code <= 0x39 /* 9 */; code++) { - CHAR_MAP[code] |= TOKEN_FLAG; -} -for (let code = 0x41 /* A */; code <= 0x5a /* Z */; code++) { - CHAR_MAP[code] |= LOWER_CASE | TOKEN_FLAG; -} -for (let code = 0x61 /* a */; code <= 0x7a /* z */; code++) { - CHAR_MAP[code] |= TOKEN_FLAG; -} +const QUOTE_REGEXP = /[\\"]/g; +/** + * RegExp to match type in RFC 9110 sec 8.3.1 + * + * media-type = type "/" subtype + * type = token + * subtype = token + */ +const TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; /** * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`. */ @@ -33212,84 +32952,21 @@ const NullObject = /* @__PURE__ */ (() => { C.prototype = Object.create(null); return C; })(); -/** - * Validate a type string against RFC 9110. - */ -function isTypeValid(type, start = 0, end = type.length) { - let hasSlash = false; - for (let index = start; index < end; index++) { - const code = type.charCodeAt(index); - if (code === 47 /* / */) { - if (hasSlash || index === start || index >= end - 1) - return false; - hasSlash = true; - } - else if (!isTokenCode(code)) { - return false; - } - } - return hasSlash; -} -/** - * Validate a token against RFC 9110. - */ -function isTokenValid(token, start = 0, end = token.length) { - if (start >= end) - return false; - for (let index = start; index < end; index++) { - if (!isTokenCode(token.charCodeAt(index))) - return false; - } - return true; -} -/** - * Check whether a character code belongs to the token production in RFC 9110. - */ -function isTokenCode(code) { - return (CHAR_MAP[code] & TOKEN_FLAG) !== 0; -} -/** - * Serialize a parameter value. - */ -function parameterValue(str) { - const len = str.length; - if (len === 0) - return '""'; - let index = 0; - while (index < len && isTokenCode(str.charCodeAt(index))) - index++; - if (index === len) - return str; - let result = '"'; - let start = 0; - while (index < len) { - const code = str.charCodeAt(index); - if (code !== HTAB && (code < SP || code === 127 || code > 255)) { - throw new TypeError(`Invalid parameter value: ${str}`); - } - if (code === 34 /* " */ || code === 92 /* \\ */) { - result += `${str.slice(start, index)}\\`; - start = index; - } - index++; - } - return `${result}${str.slice(start)}"`; -} /** * Format an object into a `Content-Type` header. */ function format(obj) { const { type, parameters } = obj; - if (!type || !isTypeValid(type)) { + if (!type || !TYPE_REGEXP.test(type)) { throw new TypeError(`Invalid type: ${type}`); } let result = type; if (parameters) { for (const param of Object.keys(parameters)) { - if (!isTokenValid(param)) { + if (!TOKEN_REGEXP.test(param)) { throw new TypeError(`Invalid parameter name: ${param}`); } - result += `; ${param}=${parameterValue(parameters[param])}`; + result += `; ${param}=${qstring(parameters[param])}`; } } return result; @@ -33298,158 +32975,126 @@ function format(obj) { * Parse a `Content-Type` header. */ function dist_parse(header, options) { - const stopFlags = SEMI_FLAG | (options?.comma === true ? COMMA_FLAG : 0); + const stopChar = options?.comma === true ? COMMA : 65_536; // Sentinel for "no stop char". const len = header.length; - let valueStart = options?.start ?? 0; - while ((CHAR_MAP[header.charCodeAt(valueStart)] & OWS) !== 0) { - valueStart++; - } - let index = valueStart; - let typeFlags = 0; - let whitespace = -1; - let stop = options?.parameters === false ? COMMA_FLAG : 0; - while (index < len) { - const code = header.charCodeAt(index); - const flags = CHAR_MAP[code]; - if ((flags & stopFlags) !== 0) { - stop |= flags & COMMA_FLAG; - break; - } - if ((flags & OWS) !== 0) { - if (whitespace === -1) - whitespace = index; - } - else { - whitespace = -1; - } - typeFlags |= (code & NON_ASCII) | flags; - index++; - } - const valueEnd = whitespace === -1 ? index : whitespace; - const value = header.slice(valueStart, valueEnd); - const type = (typeFlags & CASE_FLAGS) === 0 ? value : value.toLowerCase(); - if (index === len || stop !== 0) { + let index = skipOWS(header, options?.start ?? 0, len); + const valueStart = index; + index = skipValue(header, index, len, stopChar); + const valueEnd = trailingOWS(header, valueStart, index); + const type = header.slice(valueStart, valueEnd).toLowerCase(); + if (options?.parameters === false) { return { type, index, parameters: new NullObject() }; } - return parseParameters(header, type, index, len, stopFlags); + return parseParameters(header, type, index, len, stopChar); } +const SP = 32; // " " +const HTAB = 9; // "\t" +const SEMI = 59; // ";" +const EQ = 61; // "=" +const DQUOTE = 34; // '"' +const BSLASH = 92; // "\\" +const COMMA = 44; // "," /** * Parses the parameters of a `Content-Type` header starting at the given index. */ -function parseParameters(header, type, index, len, stopFlags) { +function parseParameters(header, type, index, len, stopChar) { const parameters = new NullObject(); parameter: while (index < len) { - index++; // Skip over ; - while ((CHAR_MAP[header.charCodeAt(index)] & OWS) !== 0) { - index++; - } + if (header.charCodeAt(index) === stopChar) + break; + index = skipOWS(header, index + 1 /* Skip over ; */, len); const keyStart = index; - let keyFlags = 0; - let keyWhitespace = -1; while (index < len) { const code = header.charCodeAt(index); - const flags = CHAR_MAP[code]; - if ((flags & stopFlags) !== 0) { - if ((flags & COMMA_FLAG) !== 0) - break parameter; + if (code === stopChar) + break parameter; + if (code === SEMI) continue parameter; - } if (code === EQ) { - const keyEnd = keyWhitespace === -1 ? index : keyWhitespace; - const value = header.slice(keyStart, keyEnd); - const key = (keyFlags & CASE_FLAGS) === 0 ? value : value.toLowerCase(); - index++; - while ((CHAR_MAP[header.charCodeAt(index)] & OWS) !== 0) { - index++; - } + const keyEnd = trailingOWS(header, keyStart, index); + const key = header.slice(keyStart, keyEnd).toLowerCase(); + index = skipOWS(header, index + 1, len); if (index < len && header.charCodeAt(index) === DQUOTE) { - const quotedStart = ++index; - let escaped = false; + index++; + let value = ""; while (index < len) { - const code = header.charCodeAt(index); + const code = header.charCodeAt(index++); if (code === DQUOTE) { - if (parameters[key] === undefined) { - parameters[key] = escaped - ? unescapeQuotedPairs(header, quotedStart, index) - : header.slice(quotedStart, index); - } - index++; - let stop = 0; - // Discard characters between quote and delimiter. - while (index < len) { - const code = header.charCodeAt(index); - const flags = CHAR_MAP[code]; - if ((flags & stopFlags) !== 0) { - stop = flags & COMMA_FLAG; - break; - } - index++; - } - if (stop !== 0) - break parameter; - continue parameter; + index = skipValue(header, index, len, stopChar); + if (parameters[key] === undefined) + parameters[key] = value; + break; } - if (code === BSLASH && index + 1 < len) { - escaped = true; - index += 2; + if (code === BSLASH && index < len) { + value += header[index++]; continue; } - index++; + value += String.fromCharCode(code); } continue parameter; } const valueStart = index; - let stop = 0; - let valueWhitespace = -1; - while (index < len) { - const code = header.charCodeAt(index); - const flags = CHAR_MAP[code]; - if ((flags & stopFlags) !== 0) { - stop = flags & COMMA_FLAG; - break; - } - if ((flags & OWS) !== 0) { - if (valueWhitespace === -1) - valueWhitespace = index; - } - else { - valueWhitespace = -1; - } - index++; - } + index = skipValue(header, index, len, stopChar); if (parameters[key] === undefined) { - const valueEnd = valueWhitespace === -1 ? index : valueWhitespace; + const valueEnd = trailingOWS(header, valueStart, index); parameters[key] = header.slice(valueStart, valueEnd); } - if (stop !== 0) - break parameter; continue parameter; } - if ((flags & OWS) !== 0) { - if (keyWhitespace === -1) - keyWhitespace = index; - } - else { - keyWhitespace = -1; - } - keyFlags |= (code & NON_ASCII) | flags; index++; } } return { type, index, parameters }; } /** - * Remove backslashes from quoted pairs in a known-terminated quoted string body. + * Skip over characters until a semicolon or other exit character. */ -function unescapeQuotedPairs(str, start, end) { - let result = ""; - for (let index = start; index < end; index++) { - if (str.charCodeAt(index) === BSLASH) { - result += str.slice(start, index); - start = ++index; - } +function skipValue(str, index, len, stopChar) { + while (index < len) { + const code = str.charCodeAt(index); + if (code === SEMI || code === stopChar) + break; + index++; + } + return index; +} +/** + * Skip optional whitespace (OWS) in an HTTP header value. + * + * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t"). + */ +function skipOWS(header, index, len) { + while (index < len) { + const char = header.charCodeAt(index); + if (char !== SP && char !== HTAB) + break; + index++; } - return result + str.slice(start, end); + return index; +} +/** + * Trim optional whitespace (OWS) from the end of a substring. + * + * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t"). + */ +function trailingOWS(header, start, end) { + while (end > start) { + const char = header.charCodeAt(end - 1); + if (char !== SP && char !== HTAB) + break; + end--; + } + return end; +} +/** + * Serialize a parameter value. + */ +function qstring(str) { + if (TOKEN_REGEXP.test(str)) + return str; + if (TEXT_REGEXP.test(str)) + return `"${str.replace(QUOTE_REGEXP, "\\$&")}"`; + throw new TypeError(`Invalid parameter value: ${str}`); } //# sourceMappingURL=index.js.map ;// CONCATENATED MODULE: ./node_modules/json-with-bigint/json-with-bigint.js @@ -37547,7 +37192,7 @@ function getOctokit(token, options, ...additionalPlugins) { // EXTERNAL MODULE: external "node:buffer" var external_node_buffer_ = __nccwpck_require__(4573); ;// CONCATENATED MODULE: ./node_modules/js-yaml/dist/js-yaml.mjs -/*! js-yaml 5.5.0 https://github.com/nodeca/js-yaml @license MIT */ +/*! js-yaml 5.4.3 https://github.com/nodeca/js-yaml @license MIT */ //#region src/tag.ts /** * Returned by a scalar resolver when the source does not match its tag. @@ -38373,8 +38018,10 @@ var Schema = class Schema { if (tag.matchByTagPrefix) prefix.sequence.push(tag); else exact.sequence[tag.tagName] = tag; break; - case "mapping": if (tag.matchByTagPrefix) prefix.mapping.push(tag); - else exact.mapping[tag.tagName] = tag; + case "mapping": + if (tag.matchByTagPrefix) prefix.mapping.push(tag); + else exact.mapping[tag.tagName] = tag; + break; } } const implicitScalarAnyFirstChar = implicitScalarTags.filter((tag) => tag.implicitFirstChars === null); @@ -38962,17 +38609,16 @@ function getBlockValue(input, start, end, indent, chomping, folded) { } const content = line.slice(textIndent); const first = content.charCodeAt(0); - if (folded) { - if (first === 32 || first === 9) { - atMoreIndented = true; - result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); - } else if (atMoreIndented) { - atMoreIndented = false; - result += "\n".repeat(emptyLines + 1); - } else if (emptyLines === 0) { - if (didReadContent) result += " "; - } else result += "\n".repeat(emptyLines); - } else result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); + if (folded) if (first === 32 || first === 9) { + atMoreIndented = true; + result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); + } else if (atMoreIndented) { + atMoreIndented = false; + result += "\n".repeat(emptyLines + 1); + } else if (emptyLines === 0) { + if (didReadContent) result += " "; + } else result += "\n".repeat(emptyLines); + else result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); result += content; didReadContent = true; emptyLines = 0; @@ -39006,69 +38652,24 @@ var DEFAULT_TAG_HANDLERS = Object.assign(Object.create(null), { "!": "!", "!!": "tag:yaml.org,2002:" }); -var TAG_SUFFIX_CHARS = "-#;/?:@&=+$_.~*'()"; -var TAG_URI_CHARS = TAG_SUFFIX_CHARS + "!,[]"; -var HEX = "0123456789ABCDEF"; -function percentByte(byte) { - return "%" + HEX[byte >> 4] + HEX[byte & 15]; -} -function tagPercentEncode(source, isSuffix) { - const allowed = isSuffix ? TAG_SUFFIX_CHARS : TAG_URI_CHARS; - let result = ""; - for (let index = 0; index < source.length; index++) { - let ch = source.charCodeAt(index); - if (ch >= 48 && ch <= 57 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || allowed.includes(source[index])) { - result += source[index]; - continue; - } - if (ch >= 55296 && ch <= 56319) ch = 65536 + ((ch & 1023) << 10) + (source.charCodeAt(++index) & 1023); - if (ch < 128) result += percentByte(ch); - else if (ch < 2048) result += percentByte(192 | ch >> 6) + percentByte(128 | ch & 63); - else if (ch < 65536) result += percentByte(224 | ch >> 12) + percentByte(128 | ch >> 6 & 63) + percentByte(128 | ch & 63); - else result += percentByte(240 | ch >> 18) + percentByte(128 | ch >> 12 & 63) + percentByte(128 | ch >> 6 & 63) + percentByte(128 | ch & 63); - } - return result; -} -function tagPercentDecode(source) { - let result = ""; - let index = 0; - while (index < source.length) { - if (source.charCodeAt(index) !== 37) { - result += source[index++]; - continue; - } - let ch = parseInt(source.slice(index + 1, index + 3), 16); - index += 3; - if (ch >= 192) { - let remaining = ch < 224 ? 1 : ch < 240 ? 2 : 3; - ch &= (1 << 6 - remaining) - 1; - while (remaining-- > 0) { - ch = ch << 6 | parseInt(source.slice(index + 1, index + 3), 16) & 63; - index += 3; - } - } - if (ch < 65536) result += String.fromCharCode(ch); - else { - ch -= 65536; - result += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023); - } - } - return result; +function tagPercentEncode(source) { + return encodeURI(source).replace(/!/g, "%21"); } function tagNameFull(rawTag, tagHandlers) { - if (rawTag.startsWith("!<") && rawTag.endsWith(">")) return tagPercentDecode(rawTag.slice(2, -1)); + if (rawTag.startsWith("!<") && rawTag.endsWith(">")) return decodeURIComponent(rawTag.slice(2, -1)); const handleEnd = rawTag.indexOf("!", 1); const handle = handleEnd === -1 ? "!" : rawTag.slice(0, handleEnd + 1); - return tagPercentDecode(tagHandlers?.[handle] ?? DEFAULT_TAG_HANDLERS[handle] ?? handle) + tagPercentDecode(rawTag.slice(handle.length)); + const prefix = tagHandlers?.[handle] ?? DEFAULT_TAG_HANDLERS[handle] ?? handle; + return decodeURIComponent(prefix) + decodeURIComponent(rawTag.slice(handle.length)); } function tagNameShort(fullTag) { let tag = fullTag; if (tag.charCodeAt(0) === 33) { tag = tag.slice(1); - return `!${tagPercentEncode(tag, true)}`; + return `!${tagPercentEncode(tag)}`; } - if (tag.slice(0, 18) === "tag:yaml.org,2002:") return `!!${tagPercentEncode(tag.slice(18), true)}`; - return `!<${tagPercentEncode(tag, false)}>`; + if (tag.slice(0, 18) === "tag:yaml.org,2002:") return `!!${tagPercentEncode(tag.slice(18))}`; + return `!<${tagPercentEncode(tag)}>`; } //#endregion //#region src/parser/constructor.ts @@ -39541,11 +39142,7 @@ function skipUntilLineEnd(state) { while (ch !== 0 && !isEol(ch)) ch = state.input.charCodeAt(++state.position); } function checkPrintable(state, start, end) { - const match = PATTERN_NON_PRINTABLE.exec(state.input.slice(start, end)); - if (match !== null) { - state.position = start + match.index + match[0].length - 1; - throwError(state, "the stream contains non-printable characters"); - } + if (PATTERN_NON_PRINTABLE.test(state.input.slice(start, end))) throwError(state, "the stream contains non-printable characters"); } function readTagProperty(state, props, inFlow) { if (state.input.charCodeAt(state.position) !== 33) return false; @@ -39572,14 +39169,12 @@ function readTagProperty(state, props, inFlow) { state.position++; } else { while (ch !== 0 && !isWsOrEol(ch) && !(inFlow && isFlowIndicator(ch))) { - if (ch === 33) { - if (!isNamed) { - tagHandle = state.input.slice(suffixStart - 1, state.position + 1); - if (!PATTERN_TAG_HANDLE.test(tagHandle)) throwError(state, "named tag handle cannot contain such characters"); - isNamed = true; - suffixStart = state.position + 1; - } else throwError(state, "tag suffix cannot contain exclamation marks"); - } + if (ch === 33) if (!isNamed) { + tagHandle = state.input.slice(suffixStart - 1, state.position + 1); + if (!PATTERN_TAG_HANDLE.test(tagHandle)) throwError(state, "named tag handle cannot contain such characters"); + isNamed = true; + suffixStart = state.position + 1; + } else throwError(state, "tag suffix cannot contain exclamation marks"); ch = state.input.charCodeAt(++state.position); } tagName = state.input.slice(suffixStart, state.position); @@ -39763,7 +39358,7 @@ function readBlockScalar(state, parentIndent, props) { function canStartPlainScalar(state, nodeContext) { const ch = state.input.charCodeAt(state.position); const inFlow = nodeContext === CONTEXT_FLOW_IN; - if (ch === 0 || isWsOrEol(ch) || ch === 35 || ch === 38 || ch === 42 || ch === 33 || ch === 124 || ch === 62 || ch === 39 || ch === 34 || ch === 37 || ch === 64 || ch === 96 || isFlowIndicator(ch)) return false; + if (ch === 0 || isWsOrEol(ch) || ch === 35 || ch === 38 || ch === 42 || ch === 33 || ch === 124 || ch === 62 || ch === 39 || ch === 34 || ch === 37 || ch === 64 || ch === 96 || inFlow && isFlowIndicator(ch)) return false; if (ch === 63 || ch === 45) { const following = state.input.charCodeAt(state.position + 1); if (isWsOrEolOrEnd(following) || inFlow && isFlowIndicator(following)) return false; @@ -40035,20 +39630,19 @@ function parseNode(state, parentIndent, nodeContext, allowToSeek, allowCompact, if (indentStatus === 1 || nodeContext === CONTEXT_BLOCK_OUT) { const flowIndent = nodeContext === CONTEXT_FLOW_IN || nodeContext === CONTEXT_FLOW_OUT ? parentIndent : parentIndent + 1; const blockIndent = state.position - state.lineStart; - if (indentStatus === 1) { - if (allowBlockCollections && (readBlockSequence(state, blockIndent, props) || readBlockMapping(state, blockIndent, flowIndent, props)) || readFlowCollection(state, flowIndent, props)) hasContent = true; - else { - const ch = state.input.charCodeAt(state.position); - if (propertyStart !== null && allowPropertyMapping && allowBlockStyles && !allowBlockCollections && ch !== 124 && ch !== 62) { - const fallbackState = snapshotState(state); - const propertyIndent = propertyStart.position - propertyStart.lineStart; - restoreState(state, propertyStart); - if (readBlockMapping(state, propertyIndent, flowIndent, emptyProperties()) && state.events[fallbackState.eventsLength]?.type === EVENT_ID.MAPPING) hasContent = true; - else restoreState(state, fallbackState); - } - if (!hasContent && (allowBlockScalars && readBlockScalar(state, flowIndent, props) || readSingleQuotedScalar(state, flowIndent, props) || readDoubleQuotedScalar(state, flowIndent, props) || readAlias(state, props) || readPlainScalar(state, flowIndent, nodeContext, props))) hasContent = true; + if (indentStatus === 1) if (allowBlockCollections && (readBlockSequence(state, blockIndent, props) || readBlockMapping(state, blockIndent, flowIndent, props)) || readFlowCollection(state, flowIndent, props)) hasContent = true; + else { + const ch = state.input.charCodeAt(state.position); + if (propertyStart !== null && allowPropertyMapping && allowBlockStyles && !allowBlockCollections && ch !== 124 && ch !== 62) { + const fallbackState = snapshotState(state); + const propertyIndent = propertyStart.position - propertyStart.lineStart; + restoreState(state, propertyStart); + if (readBlockMapping(state, propertyIndent, flowIndent, emptyProperties()) && state.events[fallbackState.eventsLength]?.type === EVENT_ID.MAPPING) hasContent = true; + else restoreState(state, fallbackState); } - } else if (indentStatus === 0) hasContent = allowBlockCollections && readBlockSequence(state, blockIndent, props); + if (!hasContent && (allowBlockScalars && readBlockScalar(state, flowIndent, props) || readSingleQuotedScalar(state, flowIndent, props) || readDoubleQuotedScalar(state, flowIndent, props) || readAlias(state, props) || readPlainScalar(state, flowIndent, nodeContext, props))) hasContent = true; + } + else if (indentStatus === 0) hasContent = allowBlockCollections && readBlockSequence(state, blockIndent, props); } allowBlockScalars = allowBlockScalars && !hasContent; if (!hasContent && (props.anchorStart !== NO_RANGE$1 || props.tagStart !== NO_RANGE$1 || allowBlockScalars)) { @@ -40395,18 +39989,20 @@ function visitNode(node, visitor, ctx) { isKey: false })) return true; break; - case "mapping": for (const { key, value } of node.items) { - if (visitNode(key, visitor, { - depth, - parent: node, - isKey: true - })) return true; - if (visitNode(value, visitor, { - depth, - parent: node, - isKey: false - })) return true; - } + case "mapping": + for (const { key, value } of node.items) { + if (visitNode(key, visitor, { + depth, + parent: node, + isKey: true + })) return true; + if (visitNode(value, visitor, { + depth, + parent: node, + isKey: false + })) return true; + } + break; } return false; } @@ -40838,10 +40434,8 @@ function writeBlockMapping(state, level, node, compact) { const keyHasLineBreak = key.kind === "scalar" && key.value.indexOf("\n") !== -1; const keyIsTooLong = keyText.length > 1024 && /^[\s\S]{1025}/u.test(keyText); const explicitPair = keyIsBlock || keyHasLineBreak || keyIsTooLong; - if (explicitPair) { - if (keyText && CHAR_LINE_FEED === keyText.charCodeAt(0)) pairBuffer += "?"; - else pairBuffer += "? "; - } + if (explicitPair) if (keyText && CHAR_LINE_FEED === keyText.charCodeAt(0)) pairBuffer += "?"; + else pairBuffer += "? "; pairBuffer += keyText; if (explicitPair) pairBuffer += generateNextLine(state, level); const valueText = writeNode(state, level + 1, value, node, { @@ -40877,15 +40471,12 @@ function writeNode(state, level, node, parent, ctx) { let body; let shouldPrintTag = node.tagged; const useBlockCollection = block && (node.kind === "mapping" || node.kind === "sequence") && node.style === COLLECTION_STYLE.BLOCK && node.items.length !== 0; - if (node.kind === "mapping") { - if (useBlockCollection) body = writeBlockMapping(state, level, node, compact); - else body = writeFlowMapping(state, level, node); - } else if (node.kind === "sequence") { - if (useBlockCollection) { - if (state.seqNoIndent && !isblockseq && level > 0) body = writeBlockSequence(state, level - 1, node, compact); - else body = writeBlockSequence(state, level, node, compact); - } else body = writeFlowSequence(state, level, node); - } else { + if (node.kind === "mapping") if (useBlockCollection) body = writeBlockMapping(state, level, node, compact); + else body = writeFlowMapping(state, level, node); + else if (node.kind === "sequence") if (useBlockCollection) if (state.seqNoIndent && !isblockseq && level > 0) body = writeBlockSequence(state, level - 1, node, compact); + else body = writeBlockSequence(state, level, node, compact); + else body = writeFlowSequence(state, level, node); + else { const layout = scalarLayout(state, node, parent, level, iskey, !block); detectAllowedStyles(layout); for (const rule of state.scalarStyleRules) rule(layout); @@ -42040,11 +41631,11 @@ function labeling_isNotFound(error) { && error.status === 404); } -;// CONCATENATED MODULE: ./node_modules/@octokit/plugin-request-log/dist-src/version.js +;// CONCATENATED MODULE: ./node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log/dist-src/version.js const plugin_request_log_dist_src_version_VERSION = "6.0.0"; -;// CONCATENATED MODULE: ./node_modules/@octokit/plugin-request-log/dist-src/index.js +;// CONCATENATED MODULE: ./node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log/dist-src/index.js function requestLog(octokit) { octokit.hook.wrap("request", (request, options) => { diff --git a/package-lock.json b/package-lock.json index 2c2253d7..7fe36122 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,16 @@ "@actions/http-client": "^4.0.0" } }, + "node_modules/@actions/core/node_modules/@actions/http-client": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", + "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", + "license": "MIT", + "dependencies": { + "tunnel": "^0.0.6", + "undici": "^6.23.0" + } + }, "node_modules/@actions/exec": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz", @@ -62,7 +72,7 @@ "undici": "^6.23.0" } }, - "node_modules/@actions/github/node_modules/@actions/http-client": { + "node_modules/@actions/http-client": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.2.tgz", "integrity": "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA==", @@ -72,16 +82,6 @@ "undici": "^6.23.0" } }, - "node_modules/@actions/http-client": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", - "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", - "license": "MIT", - "dependencies": { - "tunnel": "^0.0.6", - "undici": "^6.23.0" - } - }, "node_modules/@actions/io": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz", @@ -228,15 +228,66 @@ } } }, + "node_modules/@antfu/eslint-config/node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@antfu/eslint-config/node_modules/eslint-plugin-unicorn": { + "version": "74.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-74.0.0.tgz", + "integrity": "sha512-AGnsGi2SxHg1HEAXxn9nSnZfyjvTWkxm8E8hpd/9tD6dLjBUdcD7+D6ZN64HmmCXTSXlrwVyUqe20Uyb2CaurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.10.1", + "@eslint/css-tree": "^4.0.5", + "browserslist": "^4.28.8", + "change-case": "^5.4.4", + "ci-info": "^4.4.0", + "core-js-compat": "^3.50.0", + "detect-indent": "^7.0.2", + "entities": "^8.0.0", + "find-up-simple": "^1.0.1", + "globals": "^17.11.0", + "indent-string": "^5.0.0", + "is-builtin-module": "^5.0.0", + "is-identifier": "^1.1.0", + "pluralize": "^8.0.0", + "quote-js-string": "^0.1.0", + "regjsparser": "^0.13.2", + "reserved-identifiers": "^1.2.0", + "semver": "^7.8.5", + "strip-indent": "^4.1.1", + "yaml": "^2.9.0" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=10.4" + } + }, "node_modules/@antfu/install-pkg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-2.1.0.tgz", - "integrity": "sha512-sdg9NxU3zR4Mnawfbc/x6GB5Wf17WYud5qOuEuxXjaKpYpMkISSJEjItGebXJ2bQ4DIcly4NYH23mtkGJjvKUw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-2.0.1.tgz", + "integrity": "sha512-iCKVQcIC0e3oDxEfs3SHQGW+ovhBMZmS1TE+bTk50rVyMCBmCfClv7Qi3HQKlumYwvjb/iIMeWCW2i67q6kFfQ==", "dev": true, "license": "MIT", "dependencies": { - "package-manager-detector": "^1.8.0", - "tinyexec": "^1.3.1" + "package-manager-detector": "^1.7.0", + "tinyexec": "^1.2.4" }, "funding": { "url": "https://github.com/sponsors/antfu" @@ -263,9 +314,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", - "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "dev": true, "license": "MIT", "dependencies": { @@ -327,9 +378,9 @@ } }, "node_modules/@clack/core": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.5.1.tgz", - "integrity": "sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.4.3.tgz", + "integrity": "sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==", "dev": true, "license": "MIT", "dependencies": { @@ -341,13 +392,13 @@ } }, "node_modules/@clack/prompts": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.8.1.tgz", - "integrity": "sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.7.0.tgz", + "integrity": "sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==", "dev": true, "license": "MIT", "dependencies": { - "@clack/core": "1.5.1", + "@clack/core": "1.4.3", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" @@ -357,15 +408,15 @@ } }, "node_modules/@e18e/eslint-plugin": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@e18e/eslint-plugin/-/eslint-plugin-0.8.1.tgz", - "integrity": "sha512-OV3T7l0r52/IglskdAuoO+BJyzsCs7AcIHpwpBMlIMO0+3RHskM2h5MuHdLuesIhSRhwCURGMKtp/XwnfXrfxg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@e18e/eslint-plugin/-/eslint-plugin-0.8.0.tgz", + "integrity": "sha512-js/TeM+XJyoJ2Zk4if5uTEchv3MEbqugc9gLgq8YdB6Dy+LvwGACpQiAwcul0r4LUl0TvhuzAKUeIUPtGp2cew==", "dev": true, "license": "MIT", "dependencies": { "empathic": "^2.0.1", - "module-replacements": "^3.3.0", - "verkit": "^0.4.0" + "module-replacements": "^3.1.0", + "semver": "^7.8.5" }, "peerDependencies": { "eslint": "^9.0.0 || ^10.0.0", @@ -408,9 +459,9 @@ } }, "node_modules/@eslint-community/eslint-plugin-eslint-comments": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.8.1.tgz", - "integrity": "sha512-vafrdi15JHBFh1qWOAucyJwlEEuhdoMof28jOdKdgnwZ7bXwd6v4wzHYSmAVLwnx0yc7bqAtfJ0EZQV1WAzV/Q==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.8.0.tgz", + "integrity": "sha512-bzGg2H83F9p55TKzlNUS/LWb1WF2OqdVX67FK1OadDPLVOhabFRERC7TiDJzk//LedaVnRS5uqK/2f/AZ/+VyA==", "dev": true, "license": "MIT", "dependencies": { @@ -532,13 +583,13 @@ } }, "node_modules/@eslint/css-tree": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-4.1.2.tgz", - "integrity": "sha512-rVcxLmwSkEL3aWS3vAgsTRrQHoYE1b0XcgDtKHDJ92XOkyUpcbS/g0tUJKhvCtlEhYzgKBWsgDd+Z/aPhd166w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-4.1.0.tgz", + "integrity": "sha512-cg0ohyrAG3swyGqt8t1K/OK97DqBw/ftDvlvyY1fmEst5B40UOmsimwLENq74z2dyw5CDM+3zJIW+CV2nFNDdA==", "dev": true, "license": "MIT", "dependencies": { - "mdn-data": "2.37.2", + "mdn-data": "2.34.0", "source-map-js": "^1.2.1" }, "engines": { @@ -662,9 +713,9 @@ } }, "node_modules/@inquirer/ansi": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.9.tgz", - "integrity": "sha512-0Ywt3S8tqM6TWUcsRlBFQ1x+X3/o8kktX0ZiKAnByYb9GFDknnOhse1PVtfiD2BXPI8ar+BWx9PV9R0lQIcygw==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.8.tgz", + "integrity": "sha512-WpQM+Ti6Z40EFwwt+uL2p4UabT+W179zHp6HhLVOzfbwnVn05IPO/eXIZXGNqcT1jbQ15SujNLzQ39k4QPPxBQ==", "dev": true, "license": "MIT", "engines": { @@ -672,14 +723,14 @@ } }, "node_modules/@inquirer/confirm": { - "version": "6.3.4", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.3.4.tgz", - "integrity": "sha512-ZwnaZZDa1zxsyVrN32s447ydMnKcw7e8WWNT+R+Qsu0zAn8Rs6yi9d1B80Kob1Ul2cfUi7t8JD2t4/K7uEZpqA==", + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.3.2.tgz", + "integrity": "sha512-Xvr/0HggjddPtGppuqVmxhTw+Hr8PvsZ/k0HmOEaAqQEt80OITNkFWnsdNmyT0/eM4Ab+iJLx2R8rctlEyfSVg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^12.0.5", - "@inquirer/type": "4.2.0" + "@inquirer/core": "^12.0.3", + "@inquirer/type": "4.1.1" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" @@ -694,15 +745,15 @@ } }, "node_modules/@inquirer/core": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.5.tgz", - "integrity": "sha512-c0ZSnO9oVk/IlEGoZK3u8b3IZQeu9I6jUkXJSQnQEVRXsjKvtAq3AGqFL2LgfJhlzMZne08pZHWRWasIcI3Rew==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-12.0.3.tgz", + "integrity": "sha512-wsSy0sznmXwkty+2PzZwx00Cazc/E0r0B7mAzdGROz2Ct+DFZXaK7WDjGZvgjRldxH5ZhFVfF2lgkYrqgOw2KA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^2.0.9", + "@inquirer/ansi": "^2.0.8", "@inquirer/figures": "^2.0.9", - "@inquirer/type": "4.2.0", + "@inquirer/type": "4.1.1", "cli-width": "^4.1.0", "fast-wrap-ansi": "^0.2.0", "mute-stream": "^3.0.0", @@ -731,9 +782,9 @@ } }, "node_modules/@inquirer/type": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.2.0.tgz", - "integrity": "sha512-2rnHX8RPo4glJYqnFc/v3nQeIhDcjyRRyaT7MGcfL/8xv/8K03SXYoA2tX06WVSKywWOE/ncbG3dtuzLjR5TCQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.1.1.tgz", + "integrity": "sha512-yJoHYrMnxIsJZCY+0Vb66Dy3he3kL3e2wOBKhoSwWWAzZAY82emlxwgprCtp6yRixvNRNq9ztfRWQYPNr3Go7A==", "dev": true, "license": "MIT", "engines": { @@ -808,9 +859,9 @@ "license": "MIT" }, "node_modules/@mswjs/interceptors": { - "version": "0.45.9", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.45.9.tgz", - "integrity": "sha512-NmEzpWbbiWpudgqKVZtGdSAvQGIYyj7Rf8ea+1hJEo+Dn0YvPHtiz577US7kGg0sCaZtPelrdqV4SfwwGJq1cA==", + "version": "0.45.6", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.45.6.tgz", + "integrity": "sha512-qdBK6aOT5Qjt+cmU/XcobZjjmrIsdiQRR6hA0LP72uB7CRx+XfAjm8Opvgia8nX9kPOKqp+BKHuzMa1IFPTvyg==", "dev": true, "license": "MIT", "dependencies": { @@ -915,18 +966,6 @@ "@octokit/openapi-types": "^27.0.0" } }, - "node_modules/@octokit/plugin-request-log": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", - "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, "node_modules/@octokit/plugin-rest-endpoint-methods": { "version": "17.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", @@ -1001,6 +1040,18 @@ "node": ">= 20" } }, + "node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", + "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, "node_modules/@octokit/types": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", @@ -1034,9 +1085,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.154.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.154.0.tgz", - "integrity": "sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==", + "version": "0.152.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz", + "integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==", "dev": true, "license": "MIT", "peer": true, @@ -1058,9 +1109,9 @@ } }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.14.tgz", - "integrity": "sha512-aWR+XKH9+rW7m5fWq/5360J3mHycrx/o6xZM2DQFdJnTMdyP7/WzxPjhtLbVWdKo2y612/4U1bWqb3HQhiF7vg==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", + "integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==", "cpu": [ "arm" ], @@ -1076,9 +1127,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.14.tgz", - "integrity": "sha512-QiVxHofl6A8lQU7WAtOUY4QMVZXohxwz7WJJoeh8NBEUyKfIkMRKhYyq8az/1RypNiIXzNTtiS6KwHz0erxYRQ==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz", + "integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==", "cpu": [ "arm64" ], @@ -1094,9 +1145,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.14.tgz", - "integrity": "sha512-lTQOzHuBIooh3jIr5XINQkjPGEuGy+Dsy0meXDr6Sjty0b99kYgGh4uBC/8mJX1T0kC8d6S0aPP1Y+bHkh6aBw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz", + "integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==", "cpu": [ "arm64" ], @@ -1112,9 +1163,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.14.tgz", - "integrity": "sha512-hyMKEGatjmBYCs/Q4sbIcL/GqpFEqsX3wc+HYVQ/85A4rxc1o7rPm4DUI4GV4k/h0ITddwFSGpqQunI14GXjTA==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz", + "integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==", "cpu": [ "x64" ], @@ -1130,9 +1181,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.14.tgz", - "integrity": "sha512-u371GbXoVXrEgP20PwzoGNOdAOqAMhzo19JzzY+V4YmmnC+DTOoqdbMu+O+54emM59Mik/UdrtWgcuEDKWRPKA==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz", + "integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==", "cpu": [ "x64" ], @@ -1148,9 +1199,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.14.tgz", - "integrity": "sha512-BqwKsdZQf6EqVWr8fv2MrDYzAvOZ7+NYFSJESRGs87fkseEhs0TU9TXgRJTkZoRRkxTizyEg1LKUXfU3/78uqg==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz", + "integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==", "cpu": [ "arm" ], @@ -1166,9 +1217,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.14.tgz", - "integrity": "sha512-SD9kY8M009x/7s57Z1dgUVlP5+uYBgKQK0Tkr1WIWngrtUJmRCW1RJFMY7QDla2khXhmg2i5Io7MUjcmZNZ/KQ==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz", + "integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==", "cpu": [ "arm64" ], @@ -1187,9 +1238,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.14.tgz", - "integrity": "sha512-BJ2CL19M6uuWesMgnqJzgxoI+N+eV7b0A9O9vLV42y+gitC41fNa8KElau1tHVzuLWX5GzEuxMPhAO0tQXQMkg==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz", + "integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==", "cpu": [ "arm64" ], @@ -1208,9 +1259,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.14.tgz", - "integrity": "sha512-4+Kl8daPV8NDHaD7mfCcc1pRM+Qg7ab8DyMm5FG5WoZgv4h2i3KFN1CybYBNbQqmuYm7ftJLvmMI1eHYJ22S/Q==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz", + "integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==", "cpu": [ "ppc64" ], @@ -1229,9 +1280,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.14.tgz", - "integrity": "sha512-V/h8ePq1fKDrmtFMz6xcCN3DKvuvMRrwwD1q0PkBeeo4DpK64biaKvqWGVxqCeYKqeRk7gE7/iKPxLCn08O97A==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz", + "integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==", "cpu": [ "s390x" ], @@ -1250,9 +1301,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.14.tgz", - "integrity": "sha512-WxalXzgrLVpKC93xfpaJ3gCXUWzeCr+FRCbDVD2mUAy4L6Vo3lNVz0epUEUpxPWJkLNYUwM4OSIikv36OJ9mLg==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz", + "integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==", "cpu": [ "x64" ], @@ -1271,9 +1322,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.14.tgz", - "integrity": "sha512-3G3tnAmTpdk9jO3GQtyHXqeFD2SlecfTws/Y3M2mmj9nMBwwuLT4kur8sZKeu7ENUHSpVO3cIsm5A52LEWWwlg==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz", + "integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==", "cpu": [ "x64" ], @@ -1292,9 +1343,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.14.tgz", - "integrity": "sha512-qyr5XiNGxm2ytx17vvtcJ9nXn6v1gENETi503bJx3OGwZ1tSonj7BosxbMa/xeAfSl5iS9X6KjEWYXLu6v1L7Q==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz", + "integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==", "cpu": [ "arm64" ], @@ -1310,9 +1361,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.14.tgz", - "integrity": "sha512-oA4o5o0S2yB199YyYXDzKUv1Z56Rc+mgOjwm7Z/vJ9Z8igiDPYvoOuDyo6g7AK/ZaF09nPhDKVnGBcYHO11GXA==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz", + "integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==", "cpu": [ "arm64" ], @@ -1328,9 +1379,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.14.tgz", - "integrity": "sha512-9mE94bf2GZUaR/fUSXCMpBoWkctu421Mi0ORpm4zqfbkjKep7RxzPFa5etcGs5h+2KApoWBOA/hAJa/7saGgEQ==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz", + "integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==", "cpu": [ "x64" ], @@ -1498,17 +1549,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.72.0.tgz", - "integrity": "sha512-aysKgysPX9XOv/dk95UkvUDe++Q3n3dJPG9CEWT3RUccxfkPJ+Qn6nhKPDhZXU6Ofo9kgwGWwKyQCnZIXTgngg==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.0.tgz", + "integrity": "sha512-/v8HZt6RlyIZxB3ntehELOcUcfxKPVGWXnQdJuHRmzrqgF8nQypcC/oxGW+Ot4VGKDq81XugPKxx0n5PBtf9PA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.72.0", - "@typescript-eslint/type-utils": "8.72.0", - "@typescript-eslint/utils": "8.72.0", - "@typescript-eslint/visitor-keys": "8.72.0", + "@typescript-eslint/scope-manager": "8.70.0", + "@typescript-eslint/type-utils": "8.70.0", + "@typescript-eslint/utils": "8.70.0", + "@typescript-eslint/visitor-keys": "8.70.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1521,22 +1572,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.72.0", + "@typescript-eslint/parser": "^8.70.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.72.0.tgz", - "integrity": "sha512-0O+x3ynciD6zuXb1CKSu165haQV6ey53DKhHHUnujP7U+XlltJG+/keT0Xhd1HXCze+IHf7Tvt39ovyepX/LNw==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.0.tgz", + "integrity": "sha512-zYvrmj9Yxd63UGaXw+kdt6A0F0s0qveJyuatIM77bYC2DE4pgmg7a50u8LR7PRtXd0x+h+Tl3eXabGm06SWd3Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.72.0", - "@typescript-eslint/types": "8.72.0", - "@typescript-eslint/typescript-estree": "8.72.0", - "@typescript-eslint/visitor-keys": "8.72.0", + "@typescript-eslint/scope-manager": "8.70.0", + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/typescript-estree": "8.70.0", + "@typescript-eslint/visitor-keys": "8.70.0", "debug": "^4.4.3" }, "engines": { @@ -1552,14 +1603,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.72.0.tgz", - "integrity": "sha512-bzHngBbmIgzj6TsTjVUCntGx6FFLgE7mPjpO0PzHycOaZHXqS43XnrkFIHRS16LLr/xO6FHSXG3GJFo/F4bSBQ==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.0.tgz", + "integrity": "sha512-hFHbTNqhU9G+2eKFXCBVb1tjFT/LceiJ4+HfLO4pTpDI0KHi6iajpcFFkaSQ9gXmCh7n82A0PthaayEdN6mspQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.72.0", - "@typescript-eslint/types": "^8.72.0", + "@typescript-eslint/tsconfig-utils": "^8.70.0", + "@typescript-eslint/types": "^8.70.0", "debug": "^4.4.3" }, "engines": { @@ -1574,14 +1625,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.0.tgz", - "integrity": "sha512-JewPyJOYcXBSAS7PIgufscHOwZqhTGyBRiQJhhuDln66tMchxvvt7nJ90JKKIoOelmdHA3kAQbm9cEUHc4JSEA==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.0.tgz", + "integrity": "sha512-8nP3Kwh5hlgZ4FicGvmznAmJe8UL4sdU8tLukrPaMuQmDuk4Y8xYfzu/aYZW4xT2JCgc7H/TpDI5cGlxcWJSqQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.72.0", - "@typescript-eslint/visitor-keys": "8.72.0" + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/visitor-keys": "8.70.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1592,9 +1643,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.72.0.tgz", - "integrity": "sha512-0vbxCf7xLVPSjcOdm6eQbgViH8EDJ8xnl1laLT9yoqSz2YmcSfSg5Vdl0JUvZf6rcuJ0ZivJIuMD4edTg8obaA==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.0.tgz", + "integrity": "sha512-adnkeeNq9Sq1sUf4+FRVc0KdgYghzsgFpZSQVZVvY0LCuUuN0FnQgyGzCJeC4fW1cdXseBAjU2EOqUIjbNcZUw==", "dev": true, "license": "MIT", "engines": { @@ -1609,15 +1660,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.72.0.tgz", - "integrity": "sha512-gEXxmmbSTSOVTC37IYYvremOM31v+UN2W772bJxmVYPhAOPSUxtacyb7wkm1EhkYKU6KzFJsdU44DCV4to0LWw==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.0.tgz", + "integrity": "sha512-NUMKIhYVaVIVLnRL9CRt+VVcuLgSHUCpXn4/+K8wql+vdInUzvx8BjUO1oJ7cG9shjFJKtF8F8Hh2kCh3/KBVw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.72.0", - "@typescript-eslint/typescript-estree": "8.72.0", - "@typescript-eslint/utils": "8.72.0", + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/typescript-estree": "8.70.0", + "@typescript-eslint/utils": "8.70.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1634,9 +1685,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.0.tgz", - "integrity": "sha512-Adfoy59kxNEjT5E5fnyrp7GpHYuWs8ONbdohu4ez6IU46qDq8LltG90tLmkucZB2uhYL8mqBjtXqGd8yhfjXqQ==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.0.tgz", + "integrity": "sha512-asTOIYhDg4zdzOScCyaytrsV3cR6B4ecPQlXw/dJIm7J/MZTtCtfVII9JD8Geh4jTCrK/Xe6cg5UevoleMcoJQ==", "dev": true, "license": "MIT", "engines": { @@ -1648,16 +1699,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.72.0.tgz", - "integrity": "sha512-gwLfFgWcw15tN2KXDCJvxEOQjPn+P3j/n3eSqkZ5sX4VpW9Cosodr+tWwBZRvJT3TcKx6HnPRGZMCNAiP1Xhug==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.0.tgz", + "integrity": "sha512-d9NmHMPEKQ7QCLLm1jI3zmoQBwT5KwFYjXBJ9ymZfKCUU+5rmTRykKAFvH5Qn/ZCds3CEAFS9OC9M/jkl0X2bA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.72.0", - "@typescript-eslint/tsconfig-utils": "8.72.0", - "@typescript-eslint/types": "8.72.0", - "@typescript-eslint/visitor-keys": "8.72.0", + "@typescript-eslint/project-service": "8.70.0", + "@typescript-eslint/tsconfig-utils": "8.70.0", + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/visitor-keys": "8.70.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1676,16 +1727,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.72.0.tgz", - "integrity": "sha512-0up3oArJZBYnzOaEXKo8DmI43QvMZyPoFEt9LWzRJcyl/RcJjfKKPebknN1VbTgXBf3M/KggUh5uUMdURLnseg==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.0.tgz", + "integrity": "sha512-oZmtKJz/4fufZ2p3+Cn3ijEojcdfR+1zYDH2xKYrEly0dR/Q/1xUPRCOlKGxod78nWlU2UnDe09GZ3TaknBFGA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.72.0", - "@typescript-eslint/types": "8.72.0", - "@typescript-eslint/typescript-estree": "8.72.0" + "@typescript-eslint/scope-manager": "8.70.0", + "@typescript-eslint/types": "8.70.0", + "@typescript-eslint/typescript-estree": "8.70.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1700,13 +1751,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.72.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.0.tgz", - "integrity": "sha512-E2mroviasaWecDzTGiGMtuEguuLVOeRggnrIn93CJuxYJzQBHbyymlT08aVQydbBal5538o+JkBKXh2sRuCyIA==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.0.tgz", + "integrity": "sha512-BoC8PiO4Hkdo0TVJh9Ntxr5MxPDI7/oFsrygN5ADelFSeXG/qgNuucIGA+L5Z6JpPTE/uRfcTWtscjbUaufepQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/types": "8.70.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1741,9 +1792,9 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.0.5.tgz", - "integrity": "sha512-4KpkGdIrSqBihx/JyP/e+S+IKB98etg1XDQiLAxksLfcShnwi1VReGeOT9NI43hLHbknosKp/1CCLn9Zgcs8mg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.0.4.tgz", + "integrity": "sha512-P5YcQY8Y6RmoE9xRXI38rT8pssbcubEzqtYTM2XQoxOXMDn04nRaTI1SM8qCl9/NfW3ag9GlzdSXu7IwO5Ft8A==", "dev": true, "license": "MIT", "dependencies": { @@ -1760,8 +1811,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "5.0.5", - "vitest": "5.0.5" + "@vitest/browser": "5.0.4", + "vitest": "5.0.4" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -1824,14 +1875,14 @@ } }, "node_modules/@vitest/mocker": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.5.tgz", - "integrity": "sha512-xLL3lkDegJZw+MGoGaCCsFayDZthGgpAtr3Vziyfc4p7xH89K7KRPcRBBh/kEYm0Aqkt5DtTmkYpBtRV/FrHZg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.4.tgz", + "integrity": "sha512-tqAlrYWce4iUxhr3ncNohejtCTOcHeE8XWrSNZY3OhPoDn01yeGv+gnaBy64ATp7o6pb03eIbBAjzmibpc9vIQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.31", - "@vitest/spy": "5.0.5", + "@vitest/spy": "5.0.4", "estree-walker": "^3.0.3", "magic-string": "^1.4.3" }, @@ -1872,9 +1923,9 @@ } }, "node_modules/@vitest/spy": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.5.tgz", - "integrity": "sha512-lwJRExuH417257Q5wv9QYugN9IMJkoxcrKrYxGPQkBzl7wlNpTUxD/5yNX4ESKVUIShKPgkGchYPFMWOOk0wzw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.4.tgz", + "integrity": "sha512-MZKk/gSkm2q+ICobMxCpH1mA+cCAWm8WV7UhxlqGjq/sJ3AGc1BqFOs5CRVXxH78wQtme9q/NAAgBquj4AcyMw==", "dev": true, "license": "MIT", "funding": { @@ -1882,75 +1933,75 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.44", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.44.tgz", - "integrity": "sha512-k34nCytbK8PQ1gR2mGROYOw6Pnv/mumqIdrZ3x2tbyXZDWm7ViKGLTfdB+DRrWqEQsLgGJvn0WN9jBif5zCTLQ==", + "version": "3.5.42", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.42.tgz", + "integrity": "sha512-2Ye1ilMtKXxl8qZUrQ5j0CdgenFp/HFQmta6rfRyfEsTG69L6Wk+tWuNoHYHMx9E8tF2Slvdg1FuwDvAXdy1LQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@babel/parser": "^7.29.9", - "@vue/shared": "3.5.44", + "@babel/parser": "^7.29.8", + "@vue/shared": "3.5.42", "entities": "^7.0.1", "estree-walker": "^2.0.2", - "source-map-js": "^1.2.2" + "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.44", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.44.tgz", - "integrity": "sha512-W5AoBFWdw1lQAKiHowkfgFKFab82oSRT6sGsPfw/q1GRjsy/ZJFLHGhJyBRIFN9APLTUduDH9U2JAiPOIyKuYg==", + "version": "3.5.42", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.42.tgz", + "integrity": "sha512-qbhQZEFmycr+ni/qyuccS4sucNN7VAbDfbkvNxWOX2VfgFm90MNs3/UhRNKoPMEIVn0F8gdlYjLPvqxHwHeQOA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vue/compiler-core": "3.5.44", - "@vue/shared": "3.5.44" + "@vue/compiler-core": "3.5.42", + "@vue/shared": "3.5.42" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.44", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.44.tgz", - "integrity": "sha512-dzHmQ4jXTpdr5FjIQUeykVakN/uzqFbUo9/C5ikBFg3a3PeM6uRxeczx1ZbXBML0/zJstEh3ygYipzR5Z7b2Pw==", + "version": "3.5.42", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.42.tgz", + "integrity": "sha512-fkCAFB4okcAANGMThboWnScp/gzWjU0ZSkVnjTIiplmMDq2uq0tIB3j+xVu4rhv5rvOgBySCysudmbMd6xRRqw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@babel/parser": "^7.29.9", - "@vue/compiler-core": "3.5.44", - "@vue/compiler-dom": "3.5.44", - "@vue/compiler-ssr": "3.5.44", - "@vue/shared": "3.5.44", + "@babel/parser": "^7.29.8", + "@vue/compiler-core": "3.5.42", + "@vue/compiler-dom": "3.5.42", + "@vue/compiler-ssr": "3.5.42", + "@vue/shared": "3.5.42", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", - "postcss": "^8.5.29", - "source-map-js": "^1.2.2" + "postcss": "^8.5.19", + "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.44", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.44.tgz", - "integrity": "sha512-xr5gb1JVHlfXJwSlRz1FeP6uxoazdzHuMTVLE7up+4Vrqxk219CvxLPxD9NXBt47yvZW7+p4DXfyp4O1fkByIA==", + "version": "3.5.42", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.42.tgz", + "integrity": "sha512-xmLk3wLkbizPAiLyomjgFFosf2ys9b5Ghb+oh/k2tnvipNz8OFrQOiTcWCzyK7MpBp9KkyGtfvgfLUivbmuGYA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vue/compiler-dom": "3.5.44", - "@vue/shared": "3.5.44" + "@vue/compiler-dom": "3.5.42", + "@vue/shared": "3.5.42" } }, "node_modules/@vue/shared": { - "version": "3.5.44", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.44.tgz", - "integrity": "sha512-H82XLH0DjmSOdbEwO15x3QTo1f5PWEtv237eLpYKc0mqLu+B8hnq16lFWmuBmNurkeiG3wr+oM1FhOll/YVFRg==", + "version": "3.5.42", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.42.tgz", + "integrity": "sha512-2rPxex1jQf4jvl9MOHl6YaXCPcrNqz/FstMOEh3QWY+/OME9nQTvl9WYeCwhW7AFjaR0SnngZGlp/wkR6rkI6g==", "dev": true, "license": "MIT", "peer": true }, "node_modules/acorn": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", - "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "dev": true, "license": "MIT", "bin": { @@ -2014,9 +2065,9 @@ } }, "node_modules/ansis": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.4.0.tgz", - "integrity": "sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.3.1.tgz", + "integrity": "sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==", "dev": true, "license": "ISC", "engines": { @@ -2034,20 +2085,10 @@ } }, "node_modules/argparse": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-3.0.3.tgz", - "integrity": "sha512-Sn98ftV3KfsO8xfLPHG6oT8y+b0yvbrLgZjgPDXsharNY15tTAjqIsIju4S32nl6/iEUNNE4v+yL2Zhm8ooP3w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "PSF-2.0" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/assertion-error": { "version": "2.0.1", @@ -2092,9 +2133,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.11.30", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.30.tgz", - "integrity": "sha512-YJs6Pz17RMNv8HoyKREtCY38E3BV1nPkWVmIb+XN1uHC1Vqt3KZCH/uJH9ZKRoiKb/icZ6tvehyee6RZNbFfRA==", + "version": "2.11.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.21.tgz", + "integrity": "sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2131,9 +2172,9 @@ } }, "node_modules/browserslist": { - "version": "4.29.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.4.tgz", - "integrity": "sha512-2TcbbiwXEq+N0kD36tykpCfyyQigUXmuwNQbnPp4Xk4PX9JOqVIKjJlIDjpH7uY6tmRGoAd+apeT1p60T8wsdA==", + "version": "4.28.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.9.tgz", + "integrity": "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==", "dev": true, "funding": [ { @@ -2151,11 +2192,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.11.29", - "caniuse-lite": "^1.0.30001816", - "electron-to-chromium": "^1.5.459", - "node-releases": "^2.0.59", - "update-browserslist-db": "^1.3.4" + "baseline-browser-mapping": "^2.11.20", + "caniuse-lite": "^1.0.30001810", + "electron-to-chromium": "^1.5.420", + "node-releases": "^2.0.54", + "update-browserslist-db": "^1.3.2" }, "bin": { "browserslist": "cli.js" @@ -2165,9 +2206,9 @@ } }, "node_modules/builtin-modules": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.4.0.tgz", - "integrity": "sha512-JCWSCdun+4Ovd9BhM/Vtlmwb7oD6Wl4YiPRXXwhAuwlPhW1un/MKgXn7GZoFm53ginnoNzus69V8JWx0K393jg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.3.0.tgz", + "integrity": "sha512-hMQUl2bUFG339QygPM97E+mc8OY1IAchORZxm4a/frcYwKzozMzRVDBwHW0NjOqGElLm2O37AVQE8ikxlZHrMQ==", "dev": true, "license": "MIT", "engines": { @@ -2178,9 +2219,9 @@ } }, "node_modules/cac": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cac/-/cac-7.1.0.tgz", - "integrity": "sha512-LMDU/U2yA4IPIY8KT0NsNPWEYZvAMkbgyspxJ6btJaYV+WMDOHAZCmB0lsTObiHaRS1V/ztKAl7+TSkTqXyeoA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz", + "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==", "dev": true, "license": "MIT", "engines": { @@ -2202,9 +2243,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001816", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001816.tgz", - "integrity": "sha512-+8Yx7BXCoqk6IF8yTicjfUR6D/ldJzdlsodlEOiOSPmhK844WIgk67/zIQaGAOxNkZyyvBlrRFnLvqKIoqbAFw==", + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", "dev": true, "funding": [ { @@ -2348,9 +2389,9 @@ "license": "MIT" }, "node_modules/content-type": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-3.1.1.tgz", - "integrity": "sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-3.0.0.tgz", + "integrity": "sha512-AIi5H6p0xk5uknXcN3/rmhP8jgp69OfSe/JuKiQAFprJ7UGw7mwj7m4XcmDzlrnJDG+cGpphAINGdU3g3g7kDw==", "license": "MIT", "engines": { "node": ">=22" @@ -2388,13 +2429,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.51.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.51.0.tgz", - "integrity": "sha512-52r6fkXgxv4GLMjmFcMWRx7X9bw071xTTdrDcdyPGRqU2oE+9pCG0bAOMifSBdLw0JRBZKEF0q3B55qPlLuE8g==", + "version": "3.50.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.50.0.tgz", + "integrity": "sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.29.3" + "browserslist": "^4.28.7" }, "engines": { "node": ">=6.4.0" @@ -2530,9 +2571,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.459", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.459.tgz", - "integrity": "sha512-4SC9HHSFjO/liAhifpdOL5hG9b4BP7/5G3y3UPZVO8trlAXr1CaUEEJL0gWK3kOcYcZrOA5rkwG45Gra/lTIgg==", + "version": "1.5.422", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.422.tgz", + "integrity": "sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==", "dev": true, "license": "ISC" }, @@ -2544,9 +2585,9 @@ "license": "MIT" }, "node_modules/empathic": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.1.0.tgz", - "integrity": "sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.1.tgz", + "integrity": "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==", "dev": true, "license": "MIT", "engines": { @@ -2554,9 +2595,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.26.0.tgz", - "integrity": "sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==", + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", "dev": true, "license": "MIT", "dependencies": { @@ -2612,9 +2653,9 @@ } }, "node_modules/eslint": { - "version": "10.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.13.0.tgz", - "integrity": "sha512-UohDjD4zSzEwhf58M3O7vc/ycc8O1I7dNlhtD0WxE8Px8EHNJKtUwzBqrzeGhisRuv2ag4sAYswszCJRgKXYUg==", + "version": "10.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.12.0.tgz", + "integrity": "sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==", "dev": true, "license": "MIT", "workspaces": [ @@ -2834,17 +2875,17 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "64.5.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-64.5.4.tgz", - "integrity": "sha512-xfRhXPSSWT612muJ6XTvxuVJ8zYHv99qNgBqPVqF28aSqoy4s4XbSkrWXnYA2hl5ejC02yEpk6fqkj3BmJ6Xbg==", + "version": "64.3.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-64.3.5.tgz", + "integrity": "sha512-BqRUwfREoBH+7pzDD+uIQ3aema5P7BnPYcHj3mU0DLm+p/5TEHdimkXgnQfYl0AGgB9PZxZW/Lk7D69FTJSLXw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@es-joy/jsdoccomment": "~0.98.0", + "@es-joy/jsdoccomment": "~0.96.0", "@es-joy/resolve.exports": "1.2.0", - "@typescript-eslint/utils": "^8.70.0", + "@typescript-eslint/utils": "^8.69.0", "are-docs-informative": "^0.1.1", - "comment-parser": "1.4.9", + "comment-parser": "1.4.8", "debug": "^4.4.3", "escape-string-regexp": "^5.0.0", "espree": "^11.2.0", @@ -2860,36 +2901,40 @@ "node": "^22.22.2 || >=24.15.0" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" } }, "node_modules/eslint-plugin-jsdoc/node_modules/@es-joy/jsdoccomment": { - "version": "0.98.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.98.0.tgz", - "integrity": "sha512-QS+b7I2aaSM+gZfDz1b9E4B367JJ2qTjFXRKF289iKkh9sYdZ21Q5MiF/Duzouy3J0C4VhM3I/8f2F4+zT8gYQ==", + "version": "0.96.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.96.0.tgz", + "integrity": "sha512-nvtxrDqAJOKMPSsMHqshCnHvnCqFnJTsKpTaTSaZoUi9VxGVe2JvgQeAY/Qvh2wyqXByIAqNTgI7h9elXzn0yQ==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.9", - "@typescript-eslint/types": "^8.70.0", - "comment-parser": "1.4.9", + "@typescript-eslint/types": "^8.67.0", + "comment-parser": "1.4.8", "esquery": "^1.7.0", - "jsdoc-type-pratt-parser": "~9.2.2" + "jsdoc-type-pratt-parser": "~9.2.0" }, "engines": { "node": "^22.22.2 || >=24.15.0" } }, + "node_modules/eslint-plugin-jsdoc/node_modules/@types/node": { + "version": "26.4.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.1.tgz", + "integrity": "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, "node_modules/eslint-plugin-jsdoc/node_modules/comment-parser": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.9.tgz", - "integrity": "sha512-+2AvZKjJaNq9GQljm3tr0utwrig5BL+jgJGvz5rDpGKNIp+ojcRXWUwBbh/sGIi1QCprR6PsKFakub+w1v+4hQ==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.8.tgz", + "integrity": "sha512-rKZTGo4fzKYna8UcL0isTg5wkBNla7bxTypLwZQXjIdi++IdP1OJ41rI5Mti3/jltkPujbu4i9LIARYA+zpotQ==", "dev": true, "license": "MIT", "engines": { @@ -2941,18 +2986,26 @@ } }, "node_modules/eslint-plugin-jsdoc/node_modules/jsdoc-type-pratt-parser": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-9.2.3.tgz", - "integrity": "sha512-xsCb5EbmLWNlQ8v5zQIgSYSyf1rSyVPjh8p9G2xviOl1weHm8a611fHWUOGn7ISquCL6LoBKZvh0tcKmpVGgzw==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-9.2.1.tgz", + "integrity": "sha512-V4Ww4EHnTcTLSOMoB0FsF72JhQvcAsriCm/LWnxJeGWoxIjEL2l9na11abQok5SYShq8m0Gl02el/xAbTCulvQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.9" + "@types/estree": "^1.0.9", + "@types/node": "^26.4.0" }, "engines": { "node": "^22.22.2 || >=24.15.0" } }, + "node_modules/eslint-plugin-jsdoc/node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint-plugin-jsonc": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-3.4.2.tgz", @@ -2981,9 +3034,9 @@ } }, "node_modules/eslint-plugin-n": { - "version": "18.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-18.5.0.tgz", - "integrity": "sha512-M7uF6MTN/An+AXqvyIbXq7npJIZOkd5eKo8iMMvWrcDVNyZVdA6TF2lw01aKQfCEidRfpnR78GhAjZorlXNHiw==", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-18.3.0.tgz", + "integrity": "sha512-cPVguuDe6DrIPb/qUXHf8P89MaVTUmiYWwpt5gX5AILsvRIiZAxMFXcFR6QHYBksqKJpjfUBlL/RleCJUWcD7w==", "dev": true, "license": "MIT", "dependencies": { @@ -2994,7 +3047,6 @@ "globals": "^15.11.0", "globrex": "^0.1.2", "ignore": "^5.3.2", - "js-yaml": "^5.4.1", "semver": "^7.6.3" }, "engines": { @@ -3051,14 +3103,13 @@ } }, "node_modules/eslint-plugin-perfectionist": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-5.12.1.tgz", - "integrity": "sha512-krdSE7Dz+TCtcVr2+rfNhlOIFFBJcUdoRvjaN7JQnsaVnxJw+BZh9wMkY3MSLCJat+yW+UPTQLKS82Epc7MGZA==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-5.11.0.tgz", + "integrity": "sha512-kZV1otBcu4xT5R1p+0x1N1wRv4pS+OIbxrA47n5a1fTnN3MWbexOx5eQgbQhGyCNbpvF/rqrbnpkGjumHF+Y0Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "^8.70.0", - "@typescript-eslint/utils": "^8.70.0", + "@typescript-eslint/utils": "^8.68.0", "natural-orderby": "^5.0.0" }, "engines": { @@ -3066,11 +3117,6 @@ }, "peerDependencies": { "eslint": "^8.45.0 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } } }, "node_modules/eslint-plugin-pnpm": { @@ -3104,9 +3150,9 @@ } }, "node_modules/eslint-plugin-regexp": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-3.3.1.tgz", - "integrity": "sha512-58bGUci/AaWAo1ETj6Lsnmy6QXwnSyVONRA805828nnqp7vrTwdaQMc02vtowmYB3A5OB3SLr3r5HgmfxX4dLg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-3.3.0.tgz", + "integrity": "sha512-TT0JTQbW7CRKohntpGAsMdQ1K3MsmJK4gdAhKJtIwlJ0JvuYxauymFgJdvqxIY4lqNj0EuRZWVrymQtEdJYEFg==", "dev": true, "license": "MIT", "dependencies": { @@ -3148,57 +3194,6 @@ "eslint": ">=9.38.0" } }, - "node_modules/eslint-plugin-unicorn": { - "version": "74.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-74.0.0.tgz", - "integrity": "sha512-AGnsGi2SxHg1HEAXxn9nSnZfyjvTWkxm8E8hpd/9tD6dLjBUdcD7+D6ZN64HmmCXTSXlrwVyUqe20Uyb2CaurA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.10.1", - "@eslint/css-tree": "^4.0.5", - "browserslist": "^4.28.8", - "change-case": "^5.4.4", - "ci-info": "^4.4.0", - "core-js-compat": "^3.50.0", - "detect-indent": "^7.0.2", - "entities": "^8.0.0", - "find-up-simple": "^1.0.1", - "globals": "^17.11.0", - "indent-string": "^5.0.0", - "is-builtin-module": "^5.0.0", - "is-identifier": "^1.1.0", - "pluralize": "^8.0.0", - "quote-js-string": "^0.1.0", - "regjsparser": "^0.13.2", - "reserved-identifiers": "^1.2.0", - "semver": "^7.8.5", - "strip-indent": "^4.1.1", - "yaml": "^2.9.0" - }, - "engines": { - "node": ">=22" - }, - "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=10.4" - } - }, - "node_modules/eslint-plugin-unicorn/node_modules/entities": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-8.1.0.tgz", - "integrity": "sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=20.19.0" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/eslint-plugin-unused-imports": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.4.1.tgz", @@ -3216,9 +3211,9 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.11.1.tgz", - "integrity": "sha512-pasVXhl7wUmIvhujoqs/m0mJ9r59QW1IR9XXYKGR0FETzSM+Hhlf4qKIYgWiDDP+9YKv4YfbwskD7LqIdVcgQw==", + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.11.0.tgz", + "integrity": "sha512-fGt38SsaPCZ2FmA3bX/3vOW2qdsPNx0/9x+7Aab6NMX++PhynMtK4LWC4vzXgfQBCqpUAler18H38GA+NBAd0Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3248,9 +3243,9 @@ } }, "node_modules/eslint-plugin-yml": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-3.9.0.tgz", - "integrity": "sha512-o4ByMVFd/mGc0Q/vJmbG9pz7Kyg/BiKAGnWCzvMLqzpa2KMdpUrLgF5a6yYeL2mf1Br/9dckd0ADl3vw7uF+jA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-3.8.1.tgz", + "integrity": "sha512-E/70psRwxz5EJ8dBtzrFfqSiiInuSytbdtFCjueb/GcKjsWzPBfxfhtQePImMAPjHwMA/VDurO7DJwStDJ4wWg==", "dev": true, "license": "MIT", "dependencies": { @@ -3455,9 +3450,9 @@ } }, "node_modules/exsolve": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.3.tgz", - "integrity": "sha512-kuzL9zherLQoqDeQaS55AiiIg1kb4KYXaSusTtgZTPlvKP2gGCI82LNmBNh5RjDVUXIcmgx+/Mx7vPwRzBbhJA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.1.tgz", + "integrity": "sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==", "dev": true, "license": "MIT" }, @@ -3695,9 +3690,9 @@ } }, "node_modules/globals": { - "version": "17.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.13.0.tgz", - "integrity": "sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==", + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz", + "integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==", "dev": true, "license": "MIT", "engines": { @@ -3786,9 +3781,9 @@ } }, "node_modules/ignore": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.13.tgz", - "integrity": "sha512-2E8Q6rh+1RRSq/YdaGsNfXsEZy9FVqv6BSSrkmZJP7BnaoPnRfKL+YaofPvP+5rzdk144qSm6i4+hvPgUcbV4Q==", + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.8.tgz", + "integrity": "sha512-YYNsSlXBjMk92SKnkwvB5LOVSa6OznlFUGcsvrFgNJbJCd0M1XKeFVRc8ZByeCqz32FivYNHJVooLmdqrmvp/Q==", "dev": true, "license": "MIT", "engines": { @@ -3896,9 +3891,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.5.0.tgz", - "integrity": "sha512-paNr4LFIFPjeeSmwNYdrb8FafLLG/Cr2Af3GjbsHJ5CxIjH4r0c2emlmRdAtpPAieP1gRVzk6buBbVP5gBMGAg==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.3.tgz", + "integrity": "sha512-yzzNtgczwgoVHNigCyKTXcQJU4Y8t/ikU4UxXW0BvrLfHTGWZhsNcOT2s/a7vn81/4KqVnNmHjaUEPlvWnNwVw==", "funding": [ { "type": "github", @@ -3911,7 +3906,7 @@ ], "license": "MIT", "dependencies": { - "argparse": "^3.0.3" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.mjs" @@ -3994,19 +3989,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/jsonc-eslint-parser/node_modules/verkit": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/verkit/-/verkit-0.3.2.tgz", - "integrity": "sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/sxzz" - } - }, "node_modules/katex": { "version": "0.16.47", "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", @@ -4444,9 +4426,9 @@ } }, "node_modules/mdast-util-find-and-replace": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.3.tgz", - "integrity": "sha512-xPgpDNl0/OXHsI7TlaIs22lWnH3KlpvZdXG1ET/m/YT2Hhdkx8lJV4kLphE6l9simyM4KPDFBwas08BgEob6Jw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", "dev": true, "license": "MIT", "dependencies": { @@ -4474,9 +4456,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.1.0.tgz", - "integrity": "sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4587,9 +4569,9 @@ } }, "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.1.tgz", - "integrity": "sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", "dev": true, "license": "MIT", "dependencies": { @@ -4673,9 +4655,9 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.2.0.tgz", - "integrity": "sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", "dev": true, "license": "MIT", "dependencies": { @@ -4684,10 +4666,8 @@ "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", - "micromark-util-character": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" }, @@ -4711,16 +4691,16 @@ } }, "node_modules/mdn-data": { - "version": "2.37.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.37.2.tgz", - "integrity": "sha512-rz9YOBGItdSbe7HcSArUbhiAv4SB/4DKRYg96CSFS2CcIYMbUvBtZlzA1NCbk2AdgbmYwMqwNblLpR441lLeiQ==", + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.34.0.tgz", + "integrity": "sha512-OgIlLv0NxJKVW4GTSAoEgpRGd4F2XCqGinK0MsMlBCCS/Zcm2/LsbercNWNA7PeMMcjl75NnI97eqyo7zkdxWA==", "dev": true, "license": "CC0-1.0" }, "node_modules/micromark": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.3.tgz", - "integrity": "sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", "dev": true, "funding": [ { @@ -4744,7 +4724,6 @@ "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-edit-map": "^1.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", @@ -4755,9 +4734,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.4.tgz", - "integrity": "sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", "dev": true, "funding": [ { @@ -4775,19 +4754,18 @@ "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.1.0", + "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", - "micromark-util-edit-map": "^1.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.3" + "micromark-util-types": "^2.0.0" } }, "node_modules/micromark-extension-frontmatter": { @@ -4886,9 +4864,9 @@ } }, "node_modules/micromark-extension-gfm-table": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.2.tgz", - "integrity": "sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", "dev": true, "license": "MIT", "dependencies": { @@ -5001,9 +4979,9 @@ } }, "node_modules/micromark-factory-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.1.0.tgz", - "integrity": "sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "dev": true, "funding": [ { @@ -5194,26 +5172,6 @@ "micromark-util-symbol": "^2.0.0" } }, - "node_modules/micromark-util-edit-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-edit-map/-/micromark-util-edit-map-1.0.0.tgz", - "integrity": "sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, "node_modules/micromark-util-encode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", @@ -5351,9 +5309,9 @@ "license": "MIT" }, "node_modules/micromark-util-types": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz", - "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", "dev": true, "funding": [ { @@ -5416,9 +5374,9 @@ } }, "node_modules/module-replacements": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-3.4.0.tgz", - "integrity": "sha512-NKBNFM/uAUvSs+LOYfSly4EwrC9bgMoFuEnqNNjcDb910W+5IgS2KMB2ERLm5YZZm7R187jx1dMA9pOPvqbSbw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-3.3.0.tgz", + "integrity": "sha512-AVZL23uePazQOZlb/QMGwxsUa1oWA62Cfe6ApPzgasUoF4cdCWAiRPVq4KkaQzXbIDAlpLhLG61Jx8Lju4wjTg==", "dev": true, "license": "MIT" }, @@ -5523,9 +5481,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.59", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.59.tgz", - "integrity": "sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA==", + "version": "2.0.54", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz", + "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==", "dev": true, "license": "MIT", "engines": { @@ -5653,9 +5611,9 @@ } }, "node_modules/package-manager-detector": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.9.0.tgz", - "integrity": "sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.8.0.tgz", + "integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==", "dev": true, "license": "MIT" }, @@ -5917,9 +5875,9 @@ } }, "node_modules/regjsparser": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.4.tgz", - "integrity": "sha512-EWV80YgFaVgFrjGCAsV7oybp4GOxbls5RzBg8OB0nKEVXsBJR1JlV8Di1JhCROg3MzTfe1RI8yitIm1eOs68iA==", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.2.tgz", + "integrity": "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5960,14 +5918,14 @@ "license": "MIT" }, "node_modules/rolldown": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.14.tgz", - "integrity": "sha512-eTBTTqMR6uHKLgcUqpJP8ntzDI6V4LYA8negAMBEI7gkgVvOdrx6VsvS2Ym+83KhOPdLCHWJu0w7UQFJZhHKNw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz", + "integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@oxc-project/types": "=0.154.0", + "@oxc-project/types": "=0.152.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -5977,21 +5935,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.14", - "@rolldown/binding-android-arm64": "1.2.14", - "@rolldown/binding-darwin-arm64": "1.2.14", - "@rolldown/binding-darwin-x64": "1.2.14", - "@rolldown/binding-freebsd-x64": "1.2.14", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.14", - "@rolldown/binding-linux-arm64-gnu": "1.2.14", - "@rolldown/binding-linux-arm64-musl": "1.2.14", - "@rolldown/binding-linux-ppc64-gnu": "1.2.14", - "@rolldown/binding-linux-s390x-gnu": "1.2.14", - "@rolldown/binding-linux-x64-gnu": "1.2.14", - "@rolldown/binding-linux-x64-musl": "1.2.14", - "@rolldown/binding-openharmony-arm64": "1.2.14", - "@rolldown/binding-win32-arm64-msvc": "1.2.14", - "@rolldown/binding-win32-x64-msvc": "1.2.14" + "@rolldown/binding-android-arm-eabi": "1.2.12", + "@rolldown/binding-android-arm64": "1.2.12", + "@rolldown/binding-darwin-arm64": "1.2.12", + "@rolldown/binding-darwin-x64": "1.2.12", + "@rolldown/binding-freebsd-x64": "1.2.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", + "@rolldown/binding-linux-arm64-gnu": "1.2.12", + "@rolldown/binding-linux-arm64-musl": "1.2.12", + "@rolldown/binding-linux-ppc64-gnu": "1.2.12", + "@rolldown/binding-linux-s390x-gnu": "1.2.12", + "@rolldown/binding-linux-x64-gnu": "1.2.12", + "@rolldown/binding-linux-x64-musl": "1.2.12", + "@rolldown/binding-openharmony-arm64": "1.2.12", + "@rolldown/binding-win32-arm64-msvc": "1.2.12", + "@rolldown/binding-win32-x64-msvc": "1.2.12" } }, "node_modules/scslre": { @@ -6023,9 +5981,9 @@ } }, "node_modules/set-cookie-parser": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.4.tgz", - "integrity": "sha512-iEmdEew+Tn1BwMGMP8LzGBEPC7Mf1sySjglCeEPb/Vchm9bnGezePvacYcId+fGprQzIng+TBkzqfJ/qS7AsBg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.2.tgz", + "integrity": "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==", "dev": true, "license": "MIT" }, @@ -6101,9 +6059,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.24", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.24.tgz", - "integrity": "sha512-cLS9TtWkIQFyLkJ3/5aFQAOHOSKTlOs/7WDut/XPSdjom1fJhUdkepeJAKXa9Y05+FabHd0sti+Et559vDtkpQ==", + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", "dev": true, "license": "CC0-1.0" }, @@ -6285,22 +6243,22 @@ } }, "node_modules/tldts": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.18.tgz", - "integrity": "sha512-somxA8xKAUzlAxl0TX/jMSYIbRNFIVGnI96pVGJPeMc5BsHmfVXn6mOJT6U++ELnl04eGfzpfcEuZe8WiASkXg==", + "version": "7.4.12", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.12.tgz", + "integrity": "sha512-WylhSDKVeYnWXL3a+vKTaOxjnOeEGw938hImY8zoRWJjRRK/Jp1K+IihBzIONpUmW4e3WmXT6q5FW6vlESVZCA==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.4.18" + "tldts-core": "^7.4.12" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.18.tgz", - "integrity": "sha512-KI2PKvCmvQI/xD6ypPqkU0i7oxNXR/O58RLRaHR4svsgVUQ2JE/XC8BtMbG6PSehD27I8sZJRcC1ASnCy6lp3g==", + "version": "7.4.12", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.12.tgz", + "integrity": "sha512-nYNzS2WRf4QJmjzFFgAxLOBjyBxAGRbCy9PVBPaglcYyYajh40VBn+v5Ngr96ZMc7oM0+aCJdtQnNejvdBnXMQ==", "dev": true, "license": "MIT" }, @@ -6399,9 +6357,9 @@ } }, "node_modules/type-fest": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.10.0.tgz", - "integrity": "sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.9.0.tgz", + "integrity": "sha512-yANm3Jr3GiJ1qgJlxGAVxTOIcEOk1rhQHamlXtnrCK7EHP4HeM9OGxtMg/W7HFdrVzw/ZWJKGVIJusVH85sLtw==", "dev": true, "license": "(MIT OR CC0-1.0)", "dependencies": { @@ -6436,9 +6394,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.29.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.1.tgz", - "integrity": "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==", + "version": "6.28.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", + "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", "license": "MIT", "engines": { "node": ">=18.17" @@ -6542,9 +6500,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", - "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz", + "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==", "dev": true, "funding": [ { @@ -6590,9 +6548,9 @@ "license": "MIT" }, "node_modules/verkit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/verkit/-/verkit-0.4.1.tgz", - "integrity": "sha512-mMVzj0TXExtVdlDEq+Mzp0eyOuyznNpFobNM3uAqe3HVm/Ps2c+u17BligMkZjZCA6EiXpoon8iRTer3iu40SQ==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/verkit/-/verkit-0.3.2.tgz", + "integrity": "sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==", "dev": true, "license": "MIT", "engines": { @@ -6682,14 +6640,14 @@ } }, "node_modules/vitest": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.5.tgz", - "integrity": "sha512-cPODOMF8YnkiiYtDdHo6n4wWmBrOBBbOIYH2d33M4l3CdNn72h+qMmO6uXffUN6A5AZFXNND/d+krS9mgkXRfg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.4.tgz", + "integrity": "sha512-z0WxZRV2Sg48wF0FSgMq3TFG8JS38/Qr96vZVZdX6+Em9raQTvnXQvdTFJe2m3rfyJnEHeHQ/snceIdi8D1pVg==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/mocker": "5.0.5", + "@vitest/mocker": "5.0.4", "chai": "^6.3.0", "es-module-lexer": "^2.3.2", "expect-type": "^1.4.0", @@ -6715,12 +6673,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "5.0.5", - "@vitest/browser-preview": "5.0.5", + "@vitest/browser-playwright": "5.0.4", + "@vitest/browser-preview": "5.0.4", "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", - "@vitest/coverage-istanbul": "5.0.5", - "@vitest/coverage-v8": "5.0.5", - "@vitest/ui": "5.0.5", + "@vitest/coverage-istanbul": "5.0.4", + "@vitest/coverage-v8": "5.0.4", + "@vitest/ui": "5.0.4", "happy-dom": "*", "jsdom": "*", "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" @@ -6901,9 +6859,9 @@ } }, "node_modules/yaml": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", - "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "dev": true, "license": "ISC", "bin": { From 84d942ab56fbcf2cc6d74ca908c588ca9902d329 Mon Sep 17 00:00:00 2001 From: Bob Killen Date: Wed, 21 Oct 2026 10:01:08 -0500 Subject: [PATCH 3/3] test: cover delayed blunderbuss in the bundle Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Bob Killen --- __tests__/bundle/blunderbussDelay.test.ts | 243 ++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 __tests__/bundle/blunderbussDelay.test.ts diff --git a/__tests__/bundle/blunderbussDelay.test.ts b/__tests__/bundle/blunderbussDelay.test.ts new file mode 100644 index 00000000..b771bfe3 --- /dev/null +++ b/__tests__/bundle/blunderbussDelay.test.ts @@ -0,0 +1,243 @@ +import type { FakeGithub } from './fakeGithub' +import { Buffer } from 'node:buffer' +import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest' + +import labelFileContents from '../fixtures/labels/labelFileContentsResp.json' +import pullReqListPulls from '../fixtures/pullReq/pullReqListPulls.json' +import pullReqOpenedEvent from '../fixtures/pullReq/pullReqOpenedEvent.json' +import { blobSha } from '../utils/ownersData' +import { start } from './fakeGithub' +import { comment, configReads, helpersFor, repo, token } from './helpers' +import { runBundle } from './runBundle' + +vi.setConfig({ testTimeout: 30_000 }) + +describe('dist/index.js delayed blunderbuss', () => { + let gh: FakeGithub + const { routeOwners, expectRequests } = helpersFor(() => gh) + const owners = { OWNERS: 'reviewers:\n- bob\n' } + const timelinePath = `${repo}/issues/1/timeline` + + beforeAll(async () => { + gh = await start() + }) + afterEach(() => gh.reset()) + afterAll(() => gh.close()) + + function configure(section = ' delay: 1h\n') { + const file = structuredClone(labelFileContents) + file.content = Buffer.from(`blunderbuss:\n${section}`).toString('base64') + gh.route('GET', '/repos/Codertocat/.project/contents/prow.yaml', { status: 200, body: file }) + } + + function ago(minutes: number) { + return new Date(Date.now() - minutes * 60_000).toISOString() + } + + function pull(overrides: Record = {}) { + return { + ...structuredClone(pullReqListPulls[0]), + number: 1, + created_at: ago(70), + updated_at: ago(70), + labels: [], + requested_reviewers: [], + requested_teams: [], + assignees: [], + draft: false, + user: { login: 'Codertocat' }, + base: { ref: 'master', sha: 'basesha' }, + head: { sha: 'sha1', repo: { full_name: 'Codertocat/Hello-World' } }, + ...overrides, + } + } + + function routeSweep(pr = pull(), timeline: unknown[] = [], reviews: unknown[] = []) { + gh.route('GET', new RegExp(`^${repo}/pulls\\?`), { status: 200, body: [pr] }) + gh.route('GET', `${repo}/git/trees/master`, { + status: 200, + body: { sha: 'master', truncated: false, tree: [{ path: 'OWNERS', type: 'blob', sha: blobSha('OWNERS') }] }, + }) + routeOwners(owners, ['x.go'], pr) + gh.route('GET', timelinePath, { status: 200, body: timeline }) + gh.route('GET', `${repo}/pulls/1/reviews`, { status: 200, body: reviews }) + gh.route('POST', `${repo}/pulls/1/requested_reviewers`, { status: 201, body: {} }) + // Recent candidates still run the other sweep plugins. + gh.route('GET', `${repo}/issues/1`, { status: 200, body: { labels: [] } }) + gh.route('GET', `${repo}/labels`, { status: 200, body: [{ name: 'approved' }, { name: 'lgtm' }] }) + gh.route('GET', `${repo}/issues/1/comments`, { status: 200, body: [] }) + gh.route('POST', `${repo}/issues/1/comments`, { status: 201, body: {} }) + } + + function runSweep() { + return runBundle({ eventName: 'schedule', payload: {}, inputs: { ...token, jobs: 'sweep' }, apiUrl: gh.url }) + } + + function requested() { + return gh.requestsMatching('POST', /\/requested_reviewers$/).map(r => r.body) + } + + function timelineReads() { + return gh.requestsMatching('GET', /\/timeline\?per_page=100$/) + } + + function reviewReads() { + return gh.requestsMatching('GET', /\/reviews\?per_page=1$/) + } + + it.each(['opened', 'ready_for_review'])('%s defers reviewer assignment to the scheduled sweep', async (action) => { + configure() + routeOwners(owners, ['x.go']) + + const result = await runBundle({ + eventName: 'pull_request', + payload: { ...pullReqOpenedEvent, action }, + inputs: token, + apiUrl: gh.url, + }) + + expect(result.status, result.stdout).toBe(0) + expect(result.errors).toEqual([]) + expect(result.stdout).toContain(`#1 ${action}; blunderbuss.delay is set`) + expect(requested()).toEqual([]) + expect(timelineReads()).toEqual([]) + }) + + it('/auto-cc still immediately requests reviewers on a draft when delay is configured', async () => { + configure() + routeOwners(owners, ['x.go'], { draft: true }) + gh.route('POST', `${repo}/pulls/1/requested_reviewers`, { status: 201, body: {} }) + const payload = comment('/auto-cc') + Object.assign(payload.issue, { pull_request: { url: `${gh.url}${repo}/pulls/1` } }) + + const result = await runBundle({ + eventName: 'issue_comment', + payload, + inputs: { ...token, 'prow-commands': '/auto-cc' }, + apiUrl: gh.url, + }) + + expect(result.status, result.stdout).toBe(0) + expect(result.errors).toEqual([]) + expect(requested()).toEqual([{ reviewers: ['bob'] }]) + expect(timelineReads()).toEqual([]) + }) + + it('requests reviewers for an untouched due pull outside the normal lookback without running other sweep steps', async () => { + configure() + routeSweep() + + const result = await runSweep() + + expect(result.status, result.stdout).toBe(0) + expect(result.errors).toEqual([]) + expect(result.stdout).toContain('sweep: 0 candidates updated since') + expect(result.stdout).toContain('sweep: 1 more checked for delayed reviewers') + expect(requested()).toEqual([{ reviewers: ['bob'] }]) + expect(timelineReads()).toHaveLength(1) + expect(reviewReads()).toHaveLength(1) + expect(gh.requests.filter(r => r.method !== 'GET').map(r => r.path)).toEqual([`${repo}/pulls/1/requested_reviewers`]) + expect(gh.requestsMatching('GET', /\/issues\/1\/comments|\/actions\/runs/)).toEqual([]) + }) + + it.each([ + ['a draft', { draft: true }, [], 'is a draft', 0], + ['a manual reviewer', { requested_reviewers: [{ login: 'alice' }] }, [], 'already has requested reviewers', 0], + ['a manual team', { requested_teams: [{ slug: 'sdk' }] }, [], 'already has requested reviewers', 0], + ['an existing review', {}, [{ id: 7, user: { login: 'alice' }, state: 'COMMENTED' }], 'already has reviews', 1], + ])('does not assign a due pull with %s', async (_name, overrides, reviews, message, reads) => { + configure() + routeSweep(pull(overrides), [], reviews) + + const result = await runSweep() + + expect(result.status, result.stdout).toBe(0) + expect(result.errors).toEqual([]) + expect(result.stdout).toContain(`sweep: #1 ${message}`) + expect(requested()).toEqual([]) + expect(timelineReads()).toHaveLength(reads) + expect(reviewReads()).toHaveLength(reads) + }) + + it.each([ + ['not yet due', 30, 30, 'is not due for reviewers', 0], + ['opened before the due window', 180, 70, 'outside the due window', 1], + ])('leaves a pull %s alone', async (_name, created, updated, message, reads) => { + configure() + routeSweep(pull({ created_at: ago(created), updated_at: ago(updated) })) + + const result = await runSweep() + + expect(result.status, result.stdout).toBe(0) + expect(result.errors).toEqual([]) + expect(result.stdout).toContain(message) + expect(requested()).toEqual([]) + expect(timelineReads()).toHaveLength(reads) + expect(reviewReads()).toEqual([]) + }) + + it.each([ + ['due', 70, true], + ['recently marked ready again', 10, false], + ])('uses the latest ready_for_review clock for a former draft that is %s', async (_name, latest, due) => { + configure() + routeSweep(pull({ created_at: ago(300), updated_at: ago(latest) }), [ + { event: 'ready_for_review', created_at: ago(latest) }, + { event: 'ready_for_review', created_at: ago(240) }, + { event: 'labeled', created_at: ago(5) }, + { event: 'ready_for_review' }, + ]) + + const result = await runSweep() + + expect(result.status, result.stdout).toBe(0) + expect(result.errors).toEqual([]) + expect(timelineReads()).toHaveLength(1) + expect(reviewReads()).toHaveLength(due ? 1 : 0) + expect(requested()).toEqual(due ? [{ reviewers: ['bob'] }] : []) + if (!due) { + expect(result.stdout).toContain('outside the due window') + expect(result.stdout).toContain('sweep: #1 evaluated') + } + }) + + it('uses creation time and requests on a due draft when ignore_drafts is false', async () => { + configure(' delay: 1h\n ignore_drafts: false\n') + routeSweep(pull({ draft: true })) + + const result = await runSweep() + + expect(result.status, result.stdout).toBe(0) + expect(result.errors).toEqual([]) + expect(requested()).toEqual([{ reviewers: ['bob'] }]) + expect(timelineReads()).toEqual([]) + }) + + it('fails closed when a delayed pull timeline cannot be read', async () => { + configure() + gh.route('GET', timelinePath, { status: 403, body: { message: 'timeline denied' } }) + routeSweep() + + const result = await runSweep() + + expect(result.status, result.stdout).toBe(1) + expect(result.errors.join('\n')).toContain('sweep: 1 pull request(s) failed: #1 (blunderbuss: could not read the timeline: HttpError: timeline denied)') + expect(timelineReads()).toHaveLength(1) + expect(reviewReads()).toEqual([]) + expect(requested()).toEqual([]) + }) + + it.each([ + ['3600', 'blunderbuss.delay must be a duration string such as 1h or 30m'], + ['later', 'invalid blunderbuss.delay \'later\': expected a duration such as 5s, 2m or 500ms'], + ['25h', 'blunderbuss.delay must not be longer than 24h'], + ])('refuses invalid delay %s before listing or mutating pulls', async (delay, message) => { + configure(` delay: ${delay}\n`) + + const result = await runSweep() + + expect(result.status, result.stdout).toBe(1) + expect(result.errors.join('\n')).toContain(`Codertocat/.project:prow.yaml: ${message}`) + expectRequests(configReads({ org: '.project' }), []) + }) +})