diff --git a/dist/index.js b/dist/index.js index 3973ef8..2c036d1 100644 --- a/dist/index.js +++ b/dist/index.js @@ -21004,7 +21004,7 @@ async function connectH1 (client, socket) { function clearIdleSocketValidation (socket) { if (socket[kIdleSocketValidationTimeout]) { - clearTimeout(socket[kIdleSocketValidationTimeout]) + clearImmediate(socket[kIdleSocketValidationTimeout]) socket[kIdleSocketValidationTimeout] = null } @@ -21013,15 +21013,23 @@ function clearIdleSocketValidation (socket) { function scheduleIdleSocketValidation (client, socket) { socket[kIdleSocketValidation] = 1 - socket[kIdleSocketValidationTimeout] = setTimeout(() => { + // Yield to the check phase (after poll) so unsolicited bytes / FIN / RST + // already pending on this idle keep-alive socket are processed before the + // next request is written (GHSA-35p6-xmwp-9g52). + // + // setTimeout(0) pays Node's ~1ms timer floor on every sequential reuse + // (#5493). setImmediate avoids that, but an *unref'd* Immediate lets poll + // block for ~500ms when the event loop is otherwise idle (#5600 / #5606). + // A ref'd Immediate both keeps the pending request alive and makes poll + // return immediately — the hybrid those issues asked for. + socket[kIdleSocketValidationTimeout] = setImmediate(() => { socket[kIdleSocketValidationTimeout] = null socket[kIdleSocketValidation] = 2 if (client[kSocket] === socket && !socket.destroyed) { client[kResume]() } - }, 0) - socket[kIdleSocketValidationTimeout].unref?.() + }) } /** @@ -24679,6 +24687,7 @@ class RetryHandler { this.end = null this.etag = null this.resume = null + this.headersSent = false // Handle possible onConnect duplication this.handler.onConnect(reason => { @@ -24691,6 +24700,20 @@ class RetryHandler { }) } + checkpointResponseEnd (headers, resume) { + if (this.end == null && this.opts.method !== 'HEAD') { + const contentLength = headers['content-length'] + this.end = contentLength != null ? Number(contentLength) - 1 : null + + assert( + this.end == null || Number.isFinite(this.end), + 'invalid content-length' + ) + } + + this.resume = this.end != null ? resume : null + } + onRequestSent () { if (this.handler.onRequestSent) { this.handler.onRequestSent() @@ -24780,6 +24803,8 @@ class RetryHandler { if (statusCode >= 300) { if (this.retryOpts.statusCodes.includes(statusCode) === false) { + this.headersSent = true + this.checkpointResponseEnd(headers, resume) return this.handler.onHeaders( statusCode, rawHeaders, @@ -24848,8 +24873,15 @@ class RetryHandler { const { start, size, end = size - 1 } = contentRange - assert(this.start === start, 'content-range mismatch') - assert(this.end == null || this.end === end, 'content-range mismatch') + if (this.start !== start || (this.end != null && this.end !== end)) { + this.abort( + new RequestRetryError('Content-Range mismatch', statusCode, { + headers, + data: { count: this.retryCount } + }) + ) + return false + } this.resume = resume return true @@ -24861,6 +24893,7 @@ class RetryHandler { const range = parseRangeHeader(headers['content-range']) if (range == null) { + this.headersSent = true return this.handler.onHeaders( statusCode, rawHeaders, @@ -24899,6 +24932,7 @@ class RetryHandler { ) this.resume = resume + this.headersSent = true this.etag = headers.etag != null ? headers.etag : null // Weak etags are not useful for comparison nor cache @@ -24938,7 +24972,7 @@ class RetryHandler { } onError (err) { - if (this.aborted || isDisturbed(this.opts.body)) { + if (this.aborted || isDisturbed(this.opts.body) || (this.headersSent && this.resume == null)) { return this.handler.onError(err) } @@ -29396,6 +29430,49 @@ const COLON = 0x3A */ const SPACE = 0x20 +const DATA = Buffer.from('data') +const EVENT = Buffer.from('event') +const ID = Buffer.from('id') +const RETRY = Buffer.from('retry') + +function isASCIINumberBytes (buffer, start) { + if (start >= buffer.length) { + return false + } + + for (let i = start; i < buffer.length; i++) { + if (buffer[i] < 0x30 || buffer[i] > 0x39) { + return false + } + } + + return true +} + +function isValidLastEventIdBytes (buffer, start) { + for (let i = start; i < buffer.length; i++) { + if (buffer[i] === 0x00) { + return false + } + } + + return true +} + +function isFieldName (line, length, field) { + if (length !== field.length) { + return false + } + + for (let i = 0; i < length; i++) { + if (line[i] !== field[i]) { + return false + } + } + + return true +} + /** * @typedef {object} EventSourceStreamEvent * @type {object} @@ -29436,11 +29513,14 @@ class EventSourceStream extends Transform { eventEndCheck = false /** - * @type {Buffer} + * @type {Buffer[]} */ - buffer = null + chunks = [] + chunkIndex = 0 pos = 0 + lineChunkIndex = 0 + linePos = 0 event = { data: undefined, @@ -29479,92 +29559,20 @@ class EventSourceStream extends Transform { return } - // Cache the chunk in the buffer, as the data might not be complete while - // processing it - // TODO: Investigate if there is a more performant way to handle - // incoming chunks - // see: https://github.com/nodejs/undici/issues/2630 - if (this.buffer) { - this.buffer = Buffer.concat([this.buffer, chunk]) - } else { - this.buffer = chunk - } + this.chunks.push(chunk) // Strip leading byte-order-mark if we opened the stream and started // the processing of the incoming data if (this.checkBOM) { - switch (this.buffer.length) { - case 1: - // Check if the first byte is the same as the first byte of the BOM - if (this.buffer[0] === BOM[0]) { - // If it is, we need to wait for more data - callback() - return - } - // Set the checkBOM flag to false as we don't need to check for the - // BOM anymore - this.checkBOM = false - - // The buffer only contains one byte so we need to wait for more data - callback() - return - case 2: - // Check if the first two bytes are the same as the first two bytes - // of the BOM - if ( - this.buffer[0] === BOM[0] && - this.buffer[1] === BOM[1] - ) { - // If it is, we need to wait for more data, because the third byte - // is needed to determine if it is the BOM or not - callback() - return - } - - // Set the checkBOM flag to false as we don't need to check for the - // BOM anymore - this.checkBOM = false - break - case 3: - // Check if the first three bytes are the same as the first three - // bytes of the BOM - if ( - this.buffer[0] === BOM[0] && - this.buffer[1] === BOM[1] && - this.buffer[2] === BOM[2] - ) { - // If it is, we can drop the buffered data, as it is only the BOM - this.buffer = Buffer.alloc(0) - // Set the checkBOM flag to false as we don't need to check for the - // BOM anymore - this.checkBOM = false - - // Await more data - callback() - return - } - // If it is not the BOM, we can start processing the data - this.checkBOM = false - break - default: - // The buffer is longer than 3 bytes, so we can drop the BOM if it is - // present - if ( - this.buffer[0] === BOM[0] && - this.buffer[1] === BOM[1] && - this.buffer[2] === BOM[2] - ) { - // Remove the BOM from the buffer - this.buffer = this.buffer.subarray(3) - } - - // Set the checkBOM flag to false as we don't need to check for the - this.checkBOM = false - break + if (this.handleBOM()) { + callback() + return } } - while (this.pos < this.buffer.length) { + while (this.hasCurrentByte()) { + const byte = this.currentByte() + // If the previous line ended with an end-of-line, we need to check // if the next character is also an end-of-line. if (this.eventEndCheck) { @@ -29577,10 +29585,9 @@ class EventSourceStream extends Transform { if (this.crlfCheck) { // If the current character is a line feed, we can remove it // from the buffer and reset the crlfCheck flag - if (this.buffer[this.pos] === LF) { - this.buffer = this.buffer.subarray(this.pos + 1) - this.pos = 0 + if (byte === LF) { this.crlfCheck = false + this.consumeCurrentByte() // It is possible that the line feed is not the end of the // event. We need to check if the next character is an @@ -29596,19 +29603,17 @@ class EventSourceStream extends Transform { this.crlfCheck = false } - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { + if (byte === LF || byte === CR) { // If the current character is a carriage return, we need to // set the crlfCheck flag to true, as we need to check if the // next character is a line feed so we can remove it from the // buffer - if (this.buffer[this.pos] === CR) { + if (byte === CR) { this.crlfCheck = true } - this.buffer = this.buffer.subarray(this.pos + 1) - this.pos = 0 - if ( - this.event.data !== undefined || this.event.event || this.event.id || this.event.retry) { + this.consumeCurrentByte() + if (this.hasPendingEvent()) { this.processEvent(this.event) } this.clearEvent() @@ -29622,22 +29627,18 @@ class EventSourceStream extends Transform { // If the current character is an end-of-line, we can process the // line - if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) { + if (byte === LF || byte === CR) { // If the current character is a carriage return, we need to // set the crlfCheck flag to true, as we need to check if the // next character is a line feed - if (this.buffer[this.pos] === CR) { + if (byte === CR) { this.crlfCheck = true } // In any case, we can process the line as we reached an // end-of-line character - this.parseLine(this.buffer.subarray(0, this.pos), this.event) - - // Remove the processed line from the buffer - this.buffer = this.buffer.subarray(this.pos + 1) - // Reset the position as we removed the processed line from the buffer - this.pos = 0 + 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 // finished. @@ -29645,7 +29646,7 @@ class EventSourceStream extends Transform { continue } - this.pos++ + this.advanceCursor() } callback() @@ -29670,64 +29671,53 @@ class EventSourceStream extends Transform { return } - let field = '' - let value = '' + let fieldLength = line.length + let valueStart = line.length // If the line contains a U+003A COLON character (:) if (colonPosition !== -1) { - // Collect the characters on the line before the first U+003A COLON - // character (:), and let field be that string. - // TODO: Investigate if there is a more performant way to extract the - // field - // see: https://github.com/nodejs/undici/issues/2630 - field = line.subarray(0, colonPosition).toString('utf8') + fieldLength = colonPosition // Collect the characters on the line after the first U+003A COLON // character (:), and let value be that string. // If value starts with a U+0020 SPACE character, remove it from value. - let valueStart = colonPosition + 1 + valueStart = colonPosition + 1 if (line[valueStart] === SPACE) { ++valueStart } - // TODO: Investigate if there is a more performant way to extract the - // value - // see: https://github.com/nodejs/undici/issues/2630 - value = line.subarray(valueStart).toString('utf8') + } - // Otherwise, the string is not empty but does not contain a U+003A COLON - // character (:) - } else { - // Process the field using the steps described below, using the whole - // line as the field name, and the empty string as the field value. - field = line.toString('utf8') - value = '' - } - - // Modify the event with the field name and value. The value is also - // decoded as UTF-8 - switch (field) { - case 'data': - if (event[field] === undefined) { - event[field] = value - } else { - event[field] += `\n${value}` - } - break - case 'retry': - if (isASCIINumber(value)) { - event[field] = value - } - break - case 'id': - if (isValidLastEventId(value)) { - event[field] = value - } - break - case 'event': - if (value.length > 0) { - event[field] = value - } - break + if (isFieldName(line, fieldLength, DATA)) { + const value = line.toString('utf8', valueStart) + + if (event.data === undefined) { + event.data = value + } else { + event.data += `\n${value}` + } + return + } + + if (isFieldName(line, fieldLength, RETRY)) { + if (isASCIINumberBytes(line, valueStart)) { + event.retry = line.toString('utf8', valueStart) + } + return + } + + if (isFieldName(line, fieldLength, ID)) { + if (isValidLastEventIdBytes(line, 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 + } } } @@ -29757,13 +29747,152 @@ class EventSourceStream extends Transform { } clearEvent () { - this.event = { - data: undefined, - event: undefined, - id: undefined, - retry: undefined + this.event.data = undefined + this.event.event = undefined + this.event.id = undefined + this.event.retry = undefined + } + + hasPendingEvent () { + return this.event.data !== undefined || + this.event.event !== undefined || + this.event.id !== undefined || + this.event.retry !== undefined + } + + hasCurrentByte () { + return this.chunkIndex < this.chunks.length && + this.pos < this.chunks[this.chunkIndex].length + } + + currentByte () { + return this.chunks[this.chunkIndex][this.pos] + } + + consumeCurrentByte () { + this.advanceCursor() + this.syncLineStartToCursor() + } + + advanceCursor () { + this.pos++ + + while (this.chunkIndex < this.chunks.length && this.pos >= this.chunks[this.chunkIndex].length) { + this.chunkIndex++ + this.pos = 0 } } + + syncLineStartToCursor () { + this.lineChunkIndex = this.chunkIndex + this.linePos = this.pos + this.dropConsumedChunks() + } + + dropConsumedChunks () { + while (this.lineChunkIndex > 0) { + this.chunks.shift() + this.lineChunkIndex-- + this.chunkIndex-- + } + + if (this.chunkIndex === this.chunks.length) { + this.chunks.length = 0 + this.chunkIndex = 0 + this.pos = 0 + this.lineChunkIndex = 0 + this.linePos = 0 + } + } + + readLine () { + if (this.lineChunkIndex === this.chunkIndex) { + return this.chunks[this.chunkIndex].subarray(this.linePos, this.pos) + } + + const chunks = [] + let length = 0 + + for (let i = this.lineChunkIndex; i <= this.chunkIndex; i++) { + const chunk = this.chunks[i] + const start = i === this.lineChunkIndex ? this.linePos : 0 + const end = i === this.chunkIndex ? this.pos : chunk.length + const slice = chunk.subarray(start, end) + length += slice.length + chunks.push(slice) + } + + return Buffer.concat(chunks, length) + } + + peekBufferedByte (offset) { + let chunkIndex = this.lineChunkIndex + let pos = this.linePos + + while (chunkIndex < this.chunks.length) { + const chunk = this.chunks[chunkIndex] + const remaining = chunk.length - pos + + if (offset < remaining) { + return chunk[pos + offset] + } + + offset -= remaining + chunkIndex++ + pos = 0 + } + } + + discardLeadingBytes (count) { + while (count > 0 && this.lineChunkIndex < this.chunks.length) { + const chunk = this.chunks[this.lineChunkIndex] + const remaining = chunk.length - this.linePos + + if (count < remaining) { + this.linePos += count + count = 0 + } else { + count -= remaining + this.lineChunkIndex++ + this.linePos = 0 + } + } + + this.chunkIndex = this.lineChunkIndex + this.pos = this.linePos + this.dropConsumedChunks() + } + + handleBOM () { + const first = this.peekBufferedByte(0) + const second = this.peekBufferedByte(1) + const third = this.peekBufferedByte(2) + + if (second === undefined) { + if (first === BOM[0]) { + return true + } + + this.checkBOM = false + return true + } + + if (third === undefined) { + if (first === BOM[0] && second === BOM[1]) { + return true + } + + this.checkBOM = false + return false + } + + if (first === BOM[0] && second === BOM[1] && third === BOM[2]) { + this.discardLeadingBytes(3) + } + + this.checkBOM = false + return !this.hasCurrentByte() + } } module.exports = { @@ -41031,7 +41160,7 @@ function establishWebSocketConnection (url, protocols, client, ws, onEstablish, // is specified, the server needs to include the same field and one of // the selected subprotocol values in its response for the connection to // be established. - if (!requestProtocols.includes(secProtocol)) { + if (requestProtocols === null || !requestProtocols.includes(secProtocol)) { failWebsocketConnection(ws, 'Protocol was not set in the opening handshake.') return } @@ -41792,7 +41921,12 @@ class PerMessageDeflate { if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) { callback(new MessageSizeExceededError()) + // The inflater may still hold buffered input that can emit a late + // zlib error. Remove the data listener, then deterministically stop + // the stream so a subsequent 'error' cannot fire without a listener + // (which would terminate the process as an unhandled error event). this.#inflate.removeAllListeners() + this.#inflate.destroy() this.#inflate = null return } @@ -64834,9 +64968,6 @@ class NodeHttpClient { body = uploadReportStream; } const res = await this.makeRequest(request, abortController, body); - if (timeoutId !== undefined) { - clearTimeout(timeoutId); - } const headers = getResponseHeaders(res); const status = res.statusCode ?? 0; const response = { @@ -64874,6 +65005,9 @@ class NodeHttpClient { return response; } finally { + if (timeoutId !== undefined) { + clearTimeout(timeoutId); + } // clean up event listener if (request.abortSignal && abortListener) { let uploadStreamDone = Promise.resolve(); @@ -65447,7 +65581,7 @@ function isSystemError(err) { ;// CONCATENATED MODULE: ./node_modules/@typespec/ts-http-runtime/dist/esm/constants.js // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -const constants_SDK_VERSION = "0.3.8"; +const constants_SDK_VERSION = "0.3.9"; const constants_DEFAULT_RETRY_POLICY_COUNT = 3; //# sourceMappingURL=constants.js.map ;// CONCATENATED MODULE: ./node_modules/@typespec/ts-http-runtime/dist/esm/policies/retryPolicy.js @@ -65476,7 +65610,6 @@ function retryPolicy_retryPolicy(strategies, options = { maxRetries: constants_D let retryCount = -1; retryRequest: while (true) { retryCount += 1; - response = undefined; responseError = undefined; try { logger.info(`Retry ${retryCount}: Attempting to send request`, request.requestId); @@ -70817,7 +70950,7 @@ function serializeRequestBody(request, operationArguments, operationSpec, string } } catch (error) { - throw new Error(`Error "${error.message}" occurred in serializing the payload - ${JSON.stringify(serializedName, undefined, " ")}.`); + throw new Error(`Error "${error.message}" occurred in serializing the payload - ${JSON.stringify(serializedName, undefined, " ")}.`, { cause: error }); } } else if (operationSpec.formDataParameters && operationSpec.formDataParameters.length > 0) { diff --git a/flake.lock b/flake.lock index 15f2fd5..c3e96b4 100644 --- a/flake.lock +++ b/flake.lock @@ -36,12 +36,12 @@ }, "nixpkgs": { "locked": { - "lastModified": 1787135253, - "narHash": "sha256-RD2kNWCG+Bjo6h+JVjWVNntZs2GtRoeY2xHjts/FNkA=", - "rev": "ffb3c9b700e759be2ef13237c9d8f953b32a1e46", - "revCount": 1058091, + "lastModified": 1788752844, + "narHash": "sha256-VaWGJ6+cIYN2erfSecbRV+4ljI185Ty2wUrXyvQbgOw=", + "rev": "dc5d91f840324650bac8c379428c7037a416959a", + "revCount": 1068949, "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.1058091%2Brev-ffb3c9b700e759be2ef13237c9d8f953b32a1e46/01a01da6-7d70-7f53-ba3a-88d54b0c71f1/source.tar.gz" + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.1068949%2Brev-dc5d91f840324650bac8c379428c7037a416959a/01a07ce0-1b55-7113-bd88-7c042925b3a1/source.tar.gz" }, "original": { "type": "tarball", diff --git a/package-lock.json b/package-lock.json index adaa5c5..9ec6693 100644 --- a/package-lock.json +++ b/package-lock.json @@ -147,9 +147,9 @@ } }, "node_modules/@azure/core-client": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.11.0.tgz", - "integrity": "sha512-JjQWO6akOck45PH/XBrxzsQGAiKrfFl4m5iggJ0ItMIz5omRufOXWpqCPpdjKN3vKDzlSUvFjaMb7Zwf0gvAdA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.11.1.tgz", + "integrity": "sha512-2QygG2F76ZpMP2eMztiJvAiFMu71M9rDeU7vO/QKg5Css7MgM4frUOslFjhVjRhbGaCNPtz/S8M6y46/fFKVuQ==", "license": "MIT", "dependencies": { "@azure/abort-controller": "^2.1.2", @@ -1149,9 +1149,9 @@ } }, "node_modules/@eslint/compat": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.1.0.tgz", - "integrity": "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.1.1.tgz", + "integrity": "sha512-rMcy8GSrwNzcISX/BlTDY/GLB4eCopEuy9woIls3To+15OLxykZrxxq+WUcylCPCQ6F4MujjBM1DX5V1aqI3Vw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1423,6 +1423,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1754,6 +1757,9 @@ "arm" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1768,6 +1774,9 @@ "arm" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1782,6 +1791,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1796,6 +1808,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1810,6 +1825,9 @@ "loong64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1824,6 +1842,9 @@ "loong64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1838,6 +1859,9 @@ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1852,6 +1876,9 @@ "ppc64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1866,6 +1893,9 @@ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1880,6 +1910,9 @@ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1894,6 +1927,9 @@ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1908,6 +1944,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1922,6 +1961,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2110,17 +2152,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.69.0.tgz", - "integrity": "sha512-t5jQTKPIgVW1PE6dR6H6Qz5gm8zjMlX5/2gRaOGd9eO6V7J+tQc6iWKukEe7dY8u9HyYasQ0yfF0/FSSTEO2gA==", + "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.69.0", - "@typescript-eslint/type-utils": "8.69.0", - "@typescript-eslint/utils": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.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" @@ -2133,7 +2175,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.69.0", + "@typescript-eslint/parser": "^8.70.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -2149,16 +2191,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.69.0.tgz", - "integrity": "sha512-l4b0DhWioGg6Gt2ebGlvfkFMOjRsauxtsnDRwUSRX1qHq3HdTfQHV8wW9zEXeciai6HfeaKOedQn2Zoofx3WBw==", + "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.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.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": { @@ -2174,14 +2216,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.69.0.tgz", - "integrity": "sha512-yi4obFrHMmnsesWehHbkg9zMA7Jt8cXT+mKM08G999pH1yT6nqgsHx7MYm0uY1wAj8CqiBXYRJ7WAT0QdQHQXg==", + "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.69.0", - "@typescript-eslint/types": "^8.69.0", + "@typescript-eslint/tsconfig-utils": "^8.70.0", + "@typescript-eslint/types": "^8.70.0", "debug": "^4.4.3" }, "engines": { @@ -2196,14 +2238,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.69.0.tgz", - "integrity": "sha512-ewfspqWvSxKSOaplqAUNbaSFO0eB6w1EtQ+esfYFRm3614Ty4uNtExkcbgd6nWsXphbqKyf9ZYdbZdv2xEoWEQ==", + "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.69.0", - "@typescript-eslint/visitor-keys": "8.69.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" @@ -2214,9 +2256,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.69.0.tgz", - "integrity": "sha512-xNqK7YTDZsLniQMV/4rpFR8Z5JlqeRvVjuG1YgF/mdPVH84HSD19L8CczMA0qg2RfwEV231GHH3VnToJDo4MfQ==", + "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": { @@ -2231,15 +2273,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.69.0.tgz", - "integrity": "sha512-ZfoJAVg3JZndQEpEl9petVlxau3lRuElc4HRMuAlLCf8to04/iHz692RUSNmXKDjEuJmIL+KZ2/BsOcBc16dsA==", + "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.69.0", - "@typescript-eslint/typescript-estree": "8.69.0", - "@typescript-eslint/utils": "8.69.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" }, @@ -2256,9 +2298,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.69.0.tgz", - "integrity": "sha512-K3VrubUPhlo9VDBS6QdI8YB5j7ClpqLRdefcz6PFrhnwicehBweqQ9Evhl4l+FYz0HdDmMqIiSX0aldGRYtDCA==", + "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": { @@ -2270,16 +2312,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.69.0.tgz", - "integrity": "sha512-AdFkgqck3Vudb/kWnxlyafU/4aBhHrbQ9locP2N4psXTy5mOBg0SHJumnLvx7r6g1gV4DKvUFwV2nJZBoqOD8w==", + "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.69.0", - "@typescript-eslint/tsconfig-utils": "8.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.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", @@ -2337,16 +2379,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.69.0.tgz", - "integrity": "sha512-tUbx60BBqQa31kXF5MCsOOLL5E/WzUuxIn7YpAvq+eaUlqvk8/NXnXMBNAdLCr0icjkzem7iUA5QqWHe/hJ1aw==", + "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.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.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" @@ -2361,13 +2403,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.69.0.tgz", - "integrity": "sha512-+rmdgPA+EXkNgKYvHvFfhrs35utXbwaC5PGpDquSXcoXQDKUA5UjV0LmTucG/4JXkM31BTu4TilHtrN8IVBe8w==", + "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.69.0", + "@typescript-eslint/types": "8.70.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2392,9 +2434,9 @@ } }, "node_modules/@typespec/ts-http-runtime": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.8.tgz", - "integrity": "sha512-bLMpVcWZNzq6lYOybwFwOAR1IXKcHnhUNqYeHjl1bET/qE3jFPFH+p8Wrh3rU4xwdnifPxmKNESBYnvnmc75aA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.9.tgz", + "integrity": "sha512-edSdeAqkdxBVzA1yL1LrLCml1YjyCVvPMtMqJpbF+6K609tHe8V6sQUzFQSGcYNhcuhOceZtjvN32+mpIth30A==", "license": "MIT", "dependencies": { "http-proxy-agent": "^7.0.0", @@ -2511,6 +2553,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2525,6 +2570,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2539,6 +2587,9 @@ "loong64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2553,6 +2604,9 @@ "loong64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2567,6 +2621,9 @@ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2581,6 +2638,9 @@ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2595,6 +2655,9 @@ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2609,6 +2672,9 @@ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2623,6 +2689,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2637,6 +2706,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -3011,9 +3083,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.11.20", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.20.tgz", - "integrity": "sha512-H0ulySigv6icDJ1F7SjtdCD6PrhTpdYCmP0CactWy1+ekh0AFd0o1Wn5T8b+hnTmdBx19u9yhL6wvCylXMY7zw==", + "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": { @@ -3040,9 +3112,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", - "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", + "version": "4.28.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.9.tgz", + "integrity": "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==", "dev": true, "funding": [ { @@ -3060,11 +3132,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.11.12", - "caniuse-lite": "^1.0.30001809", - "electron-to-chromium": "^1.5.402", - "node-releases": "^2.0.53", - "update-browserslist-db": "^1.3.0" + "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" @@ -3519,9 +3591,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.420", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.420.tgz", - "integrity": "sha512-2yD6XreGusOfNV+dUcvipJEXc3n/n7fgr7996aszTG+YY5E4mqM4tOq/3uhP129cazL9YHbVWSpc79ePotWtPA==", + "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" }, @@ -7141,16 +7213,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.69.0.tgz", - "integrity": "sha512-B3MltX0VqjUBNEe3b3sSuiRbfa6XrfHFtBiPamjT5AsW/dfq+y+bc0wyuS9DxAS1LyzCxRp2+rxzpLUvqM2BvA==", + "version": "8.70.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.70.0.tgz", + "integrity": "sha512-P/W5cz70/cQAuKfY3xwQMWWTV7BvJ0mAQmi+9mBcsVPaBUpd6Ohpa+fECv9rBFrQcig86jAiNBFNWUqnTjr4pw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.69.0", - "@typescript-eslint/parser": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.0", - "@typescript-eslint/utils": "8.69.0" + "@typescript-eslint/eslint-plugin": "8.70.0", + "@typescript-eslint/parser": "8.70.0", + "@typescript-eslint/typescript-estree": "8.70.0", + "@typescript-eslint/utils": "8.70.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7203,9 +7275,9 @@ } }, "node_modules/undici": { - "version": "6.28.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz", - "integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==", + "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"