From 188a479a2699ab1a509ebbe94321522297dece1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Mon, 24 Aug 2026 20:16:06 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#75433=20node:=20v2?= =?UTF-8?q?6.3=20by=20@Renegade334?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Corbin Crutchley --- types/node/buffer.buffer.d.ts | 10 +- types/node/crypto.d.ts | 4 +- types/node/http.d.ts | 16 +++ types/node/http2.d.ts | 12 +- types/node/node-tests/http.ts | 1 + types/node/node-tests/http2.ts | 1 + types/node/node-tests/process.ts | 2 + types/node/package.json | 2 +- types/node/process.d.ts | 52 +++++++ types/node/quic.d.ts | 238 +++++++++++++++++++++++++++---- types/node/sqlite.d.ts | 8 +- types/node/test.d.ts | 36 +++++ 12 files changed, 342 insertions(+), 40 deletions(-) diff --git a/types/node/buffer.buffer.d.ts b/types/node/buffer.buffer.d.ts index a6c4b256c987aa..7dd947b4c7ac34 100644 --- a/types/node/buffer.buffer.d.ts +++ b/types/node/buffer.buffer.d.ts @@ -316,11 +316,11 @@ declare module "node:buffer" { * such `Buffer` instances with zeroes. * * When using `Buffer.allocUnsafe()` to allocate new `Buffer` instances, - * allocations under 4 KiB are sliced from a single pre-allocated `Buffer`. This - * allows applications to avoid the garbage collection overhead of creating many - * individually allocated `Buffer` instances. This approach improves both - * performance and memory usage by eliminating the need to track and clean up as - * many individual `ArrayBuffer` objects. + * allocations less than `Buffer.poolSize >>> 1` (32KiB when default poolSize is used) are sliced + * from a single pre-allocated `Buffer`. This allows applications to avoid the + * garbage collection overhead of creating many individually allocated `Buffer` + * instances. This approach improves both performance and memory usage by + * eliminating the need to track and clean up as many individual `ArrayBuffer` objects. * * However, in the case where a developer may need to retain a small chunk of * memory from a pool for an indeterminate amount of time, it may be appropriate diff --git a/types/node/crypto.d.ts b/types/node/crypto.d.ts index 55db7ab9f20c64..fd03cb5dcf35d8 100644 --- a/types/node/crypto.d.ts +++ b/types/node/crypto.d.ts @@ -3742,7 +3742,7 @@ declare module "node:crypto" { ciphertext: NodeJS.BufferSource, sharedKeyAlgorithm: AlgorithmIdentifier | HmacImportParams | AesDerivedKeyParams | KmacImportParams, extractable: boolean, - usages: KeyUsage[], + keyUsages: KeyUsage[], ): Promise; decrypt( algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AeadParams, @@ -3774,7 +3774,7 @@ declare module "node:crypto" { encapsulationKey: CryptoKey, sharedKeyAlgorithm: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | KmacImportParams, extractable: boolean, - usages: KeyUsage[], + keyUsages: KeyUsage[], ): Promise; encrypt( algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AeadParams, diff --git a/types/node/http.d.ts b/types/node/http.d.ts index efd6e90a5ade62..a9ca191b158018 100644 --- a/types/node/http.d.ts +++ b/types/node/http.d.ts @@ -175,6 +175,7 @@ declare module "node:http" { headers?: OutgoingHttpHeaders | readonly string[] | undefined; host?: string | null | undefined; hostname?: string | null | undefined; + httpValidation?: "strict" | "relaxed" | "insecure" | undefined; insecureHTTPParser?: boolean | undefined; localAddress?: string | undefined; localPort?: number | undefined; @@ -254,6 +255,21 @@ declare module "node:http" { * @since v20.1.0 */ highWaterMark?: number | undefined; + /** + * Controls HTTP header value validation strictness + * for incoming requests. Accepted values are: + * * `'strict'`: Strictest validation; rejects any non-ASCII or control + * characters in header values. + * * `'relaxed'`: Allows a limited set of non-ASCII characters in header + * values, aligning with the + * [Fetch specification](https://fetch.spec.whatwg.org/). + * * `'insecure'`: Disables all header value validation (equivalent to + * `insecureHTTPParser: true`). + * + * Cannot be used together with `insecureHTTPParser`. **Default:** `'strict'`. + * @since v26.3.0 + */ + httpValidation?: "strict" | "relaxed" | "insecure" | undefined; /** * Use an insecure HTTP parser that accepts invalid HTTP headers when `true`. * Using the insecure parser should be avoided. diff --git a/types/node/http2.d.ts b/types/node/http2.d.ts index 0d15e743534a79..e1b698e59667d5 100644 --- a/types/node/http2.d.ts +++ b/types/node/http2.d.ts @@ -840,9 +840,12 @@ declare module "node:http2" { * HTTP/2 request to the connected server. * * When a `ClientHttp2Session` is first created, the socket may not yet be - * connected. if `clienthttp2session.request()` is called during this time, the + * connected. If `clienthttp2session.request()` is called during this time, the * actual request will be deferred until the socket is ready to go. - * If the `session` is closed before the actual request be executed, an `ERR_HTTP2_GOAWAY_SESSION` is thrown. + * + * If the session becomes unavailable before the request can be created, the + * returned stream will emit `ERR_HTTP2_GOAWAY_SESSION` or + * `ERR_HTTP2_INVALID_SESSION` asynchronously. * * This method is only available if `http2session.type` is equal to `http2.constants.NGHTTP2_SESSION_CLIENT`. * @@ -1166,6 +1169,11 @@ declare module "node:http2" { * @default 128 */ maxHeaderListPairs?: number | undefined; + /** + * Sets the maximum number of uniq origin the sever + * can send via ORIGIN frames. **Default:** `128`. + */ + maxOriginSetSize?: number | undefined; /** * Sets the maximum number of outstanding, unacknowledged pings. * @default 10 diff --git a/types/node/node-tests/http.ts b/types/node/node-tests/http.ts index 47f797c6d7d1d6..0ebf51df49b4f9 100644 --- a/types/node/node-tests/http.ts +++ b/types/node/node-tests/http.ts @@ -33,6 +33,7 @@ import * as url from "node:url"; server = http.createServer({ ServerResponse: MyServerResponse }, reqListener); // TODO: add test for all remaining options server = http.createServer({ + httpValidation: "insecure", insecureHTTPParser: true, keepAlive: true, keepAliveInitialDelay: 1000, diff --git a/types/node/node-tests/http2.ts b/types/node/node-tests/http2.ts index 38455c0ae30aef..9e2b249ec96188 100644 --- a/types/node/node-tests/http2.ts +++ b/types/node/node-tests/http2.ts @@ -270,6 +270,7 @@ import { URL } from "node:url"; maxDeflateDynamicTableSize: 0, maxSettings: 32, maxSessionMemory: 10, + maxOriginSetSize: 128, maxHeaderListPairs: 128, maxOutstandingPings: 10, maxSendHeaderBlockLength: 0, diff --git a/types/node/node-tests/process.ts b/types/node/node-tests/process.ts index 723d749fa4b528..676556170df84e 100644 --- a/types/node/node-tests/process.ts +++ b/types/node/node-tests/process.ts @@ -177,6 +177,8 @@ process.env.TZ = "test"; { process.permission.has("fs.read"); // $ExpectType boolean process.permission.has("fs.read", "./README.md"); // $ExpectType boolean + process.permission.drop("fs.read"); + process.permission.drop("fs.read", "./README.md"); } { diff --git a/types/node/package.json b/types/node/package.json index 38be82d33c988c..d0ecdb27d28465 100644 --- a/types/node/package.json +++ b/types/node/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@types/node", - "version": "26.2.9999", + "version": "26.3.9999", "nonNpm": "conflict", "nonNpmDescription": "Node.js", "projects": [ diff --git a/types/node/process.d.ts b/types/node/process.d.ts index 209ec2854d1e0f..4bbb9d4f647741 100644 --- a/types/node/process.d.ts +++ b/types/node/process.d.ts @@ -549,6 +549,58 @@ declare module "node:process" { * @since v20.0.0 */ has(scope: string, reference?: string): boolean; + /** + * Drops the specified permission from the current process. This operation is + * **irreversible** — once a permission is dropped, it cannot be restored through + * any Node.js API. + * + * If no reference is provided, the entire scope is dropped. For example, + * `process.permission.drop('fs.read')` will revoke ALL file system read + * permissions. + * + * When a reference is provided, only the permission for that specific resource + * is dropped. For example, `process.permission.drop('fs.read', '/etc/myapp')` + * will revoke read access to that directory while keeping other read + * permissions intact. + * + * **Important:** You can only drop the exact resource that was explicitly + * granted. The reference passed to `drop()` must match the original grant: + * + * * If a permission was granted using a wildcard (`*`), such as + * `--allow-fs-read=*`, individual paths cannot be dropped - only the entire + * scope can be dropped (by calling `drop()` without a reference). + * * If a directory was granted (e.g. `--allow-fs-read=/my/folder`), you cannot + * drop access to individual files inside it. You must drop the same directory + * that was granted. Any remaining grants continue to apply. + * + * The available scopes are the same as [`process.permission.has()`][]: + * + * `fs` - All File System (drops both read and write) + * * `fs.read` - File System read operations + * * `fs.write` - File System write operations + * * `child` - Child process spawning operations + * * `worker` - Worker thread spawning operation + * * `net` - Network operations + * * `inspector` - Inspector operations + * * `wasi` - WASI operations + * * `addon` - Native addon operations + * + * ```js + * const fs = require('node:fs'); + * + * // Read configuration during startup + * const config = fs.readFileSync('/etc/myapp/config.json', 'utf8'); + * + * // Drop read access to the config directory after initialization + * process.permission.drop('fs.read', '/etc/myapp'); + * + * // This will now throw ERR_ACCESS_DENIED + * fs.readFileSync('/etc/myapp/config.json'); + * ``` + * @since v26.3.0 + * @experimental + */ + drop(scope: string, reference?: string): void; } interface ProcessReport { /** diff --git a/types/node/quic.d.ts b/types/node/quic.d.ts index 2be0790f99e1b2..e3072e91501e5e 100644 --- a/types/node/quic.d.ts +++ b/types/node/quic.d.ts @@ -2,7 +2,7 @@ declare module "node:quic" { import { NonSharedBuffer } from "node:buffer"; import { KeyObject } from "node:crypto"; import { FileHandle } from "node:fs/promises"; - import { SocketAddress } from "node:net"; + import { BlockList, SocketAddress } from "node:net"; import { Writer } from "node:stream/iter"; import { EphemeralKeyInfo, PeerCertificate } from "node:tls"; /** @@ -192,34 +192,40 @@ declare module "node:quic" { */ authoritative?: boolean | undefined; } + /** + * @since v26.3.0 + */ interface ApplicationOptions { /** - * Maximum number of header name-value pairs accepted per header block. Headers beyond this limit are silently - * dropped. **Default:** `128` + * Maximum number of header name-value pairs accepted per header block. + * Headers beyond this limit are silently dropped. **Default:** `128` */ - maxHeaderPairs?: number | undefined; + maxHeaderPairs?: bigint | number | undefined; /** - * Maximum total byte length of all header names and values combined per header block. Headers that would push - * the total over this limit are silently dropped. **Default:** `8192` + * Maximum total byte length of all header names and values combined per header + * block. Headers that would push the total over this limit are silently + * dropped. **Default:** `8192` */ - maxHeaderLength?: number | undefined; + maxHeaderLength?: bigint | number | undefined; /** - * Maximum size of a compressed header field section (QPACK). `0` means unlimited. **Default:** `0` + * Maximum size of a compressed header field section (QPACK). `0` means + * unlimited. **Default:** `0` */ - maxFieldSectionSize?: number | undefined; + maxFieldSectionSize?: bigint | number | undefined; /** - * QPACK dynamic table capacity in bytes. Set to `0` to disable the dynamic table. **Default:** `4096` + * QPACK dynamic table capacity in bytes. Set to `0` to disable the dynamic + * table. **Default:** `4096` */ - qpackMaxDTableCapacity?: number | undefined; + qpackMaxDTableCapacity?: bigint | number | undefined; /** * QPACK encoder maximum dynamic table capacity. **Default:** `4096` */ - qpackEncoderMaxDTableCapacity?: number | undefined; + qpackEncoderMaxDTableCapacity?: bigint | number | undefined; /** - * Maximum number of streams that can be blocked waiting for QPACK dynamic table updates. - * **Default:** `100` + * Maximum number of streams that can e blocked waiting for QPACK dynamic table + * updates. **Default:** `100` */ - qpackBlockedStreams?: number | undefined; + qpackBlockedStreams?: bigint | number | undefined; /** * Enable the extended CONNECT protocol (RFC 9220). **Default:** `false` */ @@ -256,8 +262,7 @@ declare module "node:quic" { */ alpn?: string | readonly string[] | undefined; /** - * HTTP/3 application-specific options. These only apply when the negotiated - * ALPN selects the HTTP/3 application (`'h3'`). + * Application-specific options. * @since v26.2.0 */ application?: ApplicationOptions | undefined; @@ -342,7 +347,12 @@ declare module "node:quic" { minVersion?: number | undefined; /** * When the remote peer advertises a preferred address, this option specifies whether - * to use it or ignore it. + * to use it or ignore it. The default is `'ignore'` because honoring a server's + * preferred address causes the client to migrate its connection to a different IP + * address, which can be exploited for data exfiltration attacks that are + * indistinguishable from legitimate QUIC connection migration at the network level. + * Set to `'use'` only when connecting to trusted servers that require preferred + * address migration. * @since v23.8.0 */ preferredAddressPolicy?: "use" | "ignore" | "default" | undefined; @@ -370,6 +380,21 @@ declare module "node:quic" { * @since v26.2.0 */ datagramDropPolicy?: "drop-oldest" | "drop-newest" | undefined; + /** + * The maximum time in milliseconds that a peer-initiated stream can be idle + * (no data received) before it is automatically destroyed. This protects + * against slowloris-style attacks where a remote peer opens streams but never + * sends data, holding server resources indefinitely. Only peer-initiated + * streams are checked — locally-initiated streams are the application's + * responsibility. Set to `0` to disable. + * + * The idle check runs as part of the normal send processing loop, so it adds + * no additional timers or event loop overhead. The + * `session.stats.streamsIdleTimedOut` counter tracks how many streams have been + * destroyed by this mechanism. + * @since v26.3.0 + */ + streamIdleTimeout?: bigint | number | undefined; /** * The maximum number of `SendPendingData` cycles a datagram can survive * without being sent before it is abandoned. When a datagram cannot be @@ -397,6 +422,30 @@ declare module "node:quic" { * @since v23.8.0 */ handshakeTimeout?: bigint | number | undefined; + /** + * Controls how the client handles server certificate validation: + * + * * `'strict'` — OpenSSL aborts the TLS handshake immediately if the server's + * certificate fails validation. The `session.opened` promise rejects with a + * TLS error. The application cannot inspect the certificate or the error + * details. This is the most secure mode. + * + * * `'auto'` — The TLS handshake completes regardless of validation result. + * If validation fails, the `session.opened` promise is rejected with an error + * containing the validation reason, and the session is destroyed. The + * `onhandshake` callback (if set) fires before rejection, allowing diagnostic + * logging. This is the default and matches the behavior of `tls.connect()` + * with `rejectUnauthorized: true`. + * + * * `'manual'` — The TLS handshake completes regardless of validation result. + * The `session.opened` promise resolves with the handshake info, which includes + * `validationErrorReason` and `validationErrorCode` if validation failed. The + * application is responsible for checking these values and deciding whether to + * continue. Use this mode for custom validation logic, certificate pinning, or + * intentionally accepting self-signed certificates. + * @since v26.3.0 + */ + verifyPeer?: "strict" | "auto" | "manual" | undefined; /** * The peer server name to target (SNI). Defaults to `'localhost'`. * @since v26.1.0 @@ -569,6 +618,31 @@ declare module "node:quic" { * @since v23.8.0 */ address?: SocketAddress | string | undefined; + /** + * An optional `net.BlockList` instance for filtering incoming packets by + * source address. When configured, every received UDP packet is checked against + * the block list before any QUIC processing occurs, minimizing resource + * expenditure on blocked sources. The block list is evaluated live — rules + * added to the `BlockList` object after the endpoint is created take effect + * immediately. + * + * See `endpointOptions.blockListPolicy` for how matches are interpreted. + * @since v26.3.0 + */ + blockList?: BlockList | undefined; + /** + * Controls how the `endpointOptions.blockList` is interpreted: + * + * * `'deny'` — Packets from addresses matching the block list are dropped. + * All other addresses are accepted. This is the typical blocklist mode. + * * `'allow'` — Only packets from addresses matching the block list are + * accepted. All other addresses are dropped. This is an allowlist mode + * for restricting access to known clients. + * + * If no block list is configured, this option has no effect. + * @since v26.3.0 + */ + blockListPolicy?: "deny" | "allow" | undefined; /** * The endpoint maintains an internal cache of validated socket addresses as a * performance optimization. This option sets the maximum number of addresses @@ -625,15 +699,69 @@ declare module "node:quic" { */ maxConnectionsTotal?: number | undefined; /** - * Specifies the maximum number of QUIC retry attempts allowed per remote peer address. - * @since v23.8.0 + * The maximum number of QUIC retry packets the endpoint will send per second. + * This is a global rate limit (not per-host) that caps the total server-wide + * retry response rate, preventing spoofed-source floods from consuming unbounded + * resources. + * @since v26.3.0 */ - maxRetries?: bigint | number | undefined; + retryRate?: number | undefined; /** - * Specifies the maximum number of stateless resets that are allowed per remote peer address. - * @since v23.8.0 + * The maximum burst of retry packets allowed before rate limiting takes effect. + * @since v26.3.0 */ - maxStatelessResetsPerHost?: bigint | number | undefined; + retryBurst?: number | undefined; + /** + * The maximum number of stateless reset packets the endpoint will send per second. + * @since v26.3.0 + */ + statelessResetRate?: number | undefined; + /** + * The maximum burst of stateless reset packets allowed before rate limiting + * takes effect. + * @since v26.3.0 + */ + statelessResetBurst?: number | undefined; + /** + * The maximum number of version negotiation packets the endpoint will send per + * second. + * @since v26.3.0 + */ + versionNegotiationRate?: number | undefined; + /** + * The maximum number of immediate connection close packets the endpoint will + * send per second. + * @since v26.3.0 + */ + versionNegotiationBurst?: number | undefined; + /** + * The maximum number of immediate connection close packets the endpoint will + * send per second. + * @since v26.3.0 + */ + immediateCloseRate?: number | undefined; + /** + * The maximum burst of immediate connection close packets allowed before rate + * limiting takes effect. + * @since v26.3.0 + */ + immediateCloseBurst?: number | undefined; + /** + * The maximum number of new sessions that a single remote address can create per + * second. This is a per-host rate limit tracked in the address validation LRU + * cache. It prevents a validated remote address from churning through sessions + * (rapidly opening and abandoning connections) faster than the server can handle. + * For benchmarking where traffic comes from a single source, set this to a high + * value. + * @since v26.3.0 + */ + sessionCreationRate?: number | undefined; + /** + * The maximum burst of new session creations allowed from a single remote address + * before rate limiting takes effect. + * @since v26.3.0 + */ + sessionCreationBurst?: number | undefined; /** * Specifies the length of time a QUIC retry token is considered valid. * @since v23.8.0 @@ -846,25 +974,66 @@ declare module "node:quic" { */ readonly serverBusyCount: bigint; /** - * The total number of QUIC retry attempts on this endpoint. Read only. + * The total number of retry packets sent by this endpoint. Read only. * @since v23.8.0 */ readonly retryCount: bigint; /** - * The total number of sessions rejected due to QUIC version mismatch. Read only. + * The total number of retry packets dropped by the global rate + * limiter. Read only. A non-zero value indicates the endpoint is under retry + * flood pressure. + * @since v26.3.0 + */ + readonly retryRateLimited: bigint; + /** + * The total number of version negotiation packets sent by this + * endpoint. Read only. * @since v23.8.0 */ readonly versionNegotiationCount: bigint; /** - * The total number of stateless resets handled by this endpoint. Read only. + * The total number of version negotiation packets dropped by + * the global rate limiter. Read only. + * @since v26.3.0 + */ + readonly versionNegotiationRateLimited: bigint; + /** + * The total number of stateless reset packets sent by this + * endpoint. Read only. * @since v23.8.0 */ readonly statelessResetCount: bigint; /** - * The total number of sessions that were closed before handshake completed. Read only. + * The total number of stateless reset packets dropped by the + * global rate limiter. Read only. + * @since v26.3.0 + */ + readonly statelessResetRateLimited: bigint; + /** + * The total number of immediate connection close packets sent + * by this endpoint. Read only. * @since v23.8.0 */ readonly immediateCloseCount: bigint; + /** + * The total number of immediate connection close packets + * dropped by the global rate limiter. Read only. + * @since v26.3.0 + */ + readonly immediateCloseRateLimited: bigint; + /** + * The total number of session creation attempts dropped by the + * per-host rate limiter. Read only. A non-zero value indicates one or more + * remote addresses are creating sessions faster than the configured rate allows. + * @since v26.3.0 + */ + readonly sessionCreationRateLimited: bigint; + /** + * The total number of incoming packets dropped by the + * block list filter. Read only. + * @since v26.3.0 + */ + readonly packetsBlocked: bigint; } } interface CreateStreamOptions { @@ -997,6 +1166,13 @@ declare module "node:quic" { */ class QuicSession implements AsyncDisposable { private constructor(); + /** + * The current application-level options for this session. These include settings + * that are specific to the negotiated application protocol (e.g. HTTP/3) and may + * be negotiated separately from the transport parameters. Read only. + * @since v26.3.0 + */ + readonly applicationOptions: { [K in keyof ApplicationOptions]-?: ApplicationOptions[K] & (bigint | boolean) }; /** * Initiate a graceful close of the session. Existing streams will be allowed * to complete but no new streams will be opened. Once all streams have closed, @@ -1395,6 +1571,12 @@ declare module "node:quic" { * @since v23.8.0 */ readonly datagramsLost: bigint; + /** + * The total number of peer-initiated streams destroyed by the + * stream idle timeout. Read only. + * @since v26.3.0 + */ + readonly streamsIdleTimedOut: bigint; } } interface QuicErrorOptions { diff --git a/types/node/sqlite.d.ts b/types/node/sqlite.d.ts index bbe335da31c16c..70493f065c5175 100644 --- a/types/node/sqlite.d.ts +++ b/types/node/sqlite.d.ts @@ -127,8 +127,12 @@ declare module "node:sqlite" { } interface ApplyChangesetOptions { /** - * Skip changes that, when targeted table name is supplied to this function, return a truthy value. - * By default, all changes are attempted. + * for each table affected by at least + * one change in the changeset, the `filter` callback is invoked with the + * table name as the first argument. If the return value is falsy, then no + * attempt is made to apply any changes to the table. + * Otherwise, if the return value is truthy or no `filter` callback is provided, + * all changes related to the table are attempted. * @since v22.12.0 */ filter?: ((tableName: string) => boolean) | undefined; diff --git a/types/node/test.d.ts b/types/node/test.d.ts index 809e00be8a2bd3..585cca25780aa5 100644 --- a/types/node/test.d.ts +++ b/types/node/test.d.ts @@ -677,6 +677,12 @@ declare module "node:test" { * The nesting level of the test. */ nesting: number; + /** + * The `testId` of the enclosing test, or + * `undefined` for top-level tests. Lets custom reporters track lineage + * when concurrent siblings at the same nesting level interleave. + */ + parentId: number | undefined; /** * The flattened lowercased tags declared on the test * and its ancestor suites, in declaration order. Empty for untagged tests. @@ -711,6 +717,12 @@ declare module "node:test" { * The nesting level of the test. */ nesting: number; + /** + * The `testId` of the enclosing test, or + * `undefined` for top-level tests. Lets custom reporters track lineage + * when concurrent siblings at the same nesting level interleave. + */ + parentId: number | undefined; /** * The flattened lowercased tags declared on the test * and its ancestor suites, in declaration order. Empty for untagged tests. @@ -738,6 +750,12 @@ declare module "node:test" { * The nesting level of the test. */ nesting: number; + /** + * The `testId` of the enclosing test, or + * `undefined` for top-level tests. Lets custom reporters track lineage + * when concurrent siblings at the same nesting level interleave. + */ + parentId: number | undefined; /** * The flattened lowercased tags declared on the test * and its ancestor suites, in declaration order. Empty for untagged tests. @@ -789,6 +807,12 @@ declare module "node:test" { * The nesting level of the test. */ nesting: number; + /** + * The `testId` of the enclosing test, or + * `undefined` for top-level tests. Lets custom reporters track lineage + * when concurrent siblings at the same nesting level interleave. + */ + parentId: number | undefined; /** * The flattened lowercased tags declared on the test * and its ancestor suites, in declaration order. Empty for untagged tests. @@ -856,6 +880,12 @@ declare module "node:test" { * The nesting level of the test. */ nesting: number; + /** + * The `testId` of the enclosing test, or + * `undefined` for top-level tests. Lets custom reporters track lineage + * when concurrent siblings at the same nesting level interleave. + */ + parentId: number | undefined; /** * The flattened lowercased tags declared on the test * and its ancestor suites, in declaration order. Empty for untagged tests. @@ -900,6 +930,12 @@ declare module "node:test" { * The nesting level of the test. */ nesting: number; + /** + * The `testId` of the enclosing test, or + * `undefined` for top-level tests. Lets custom reporters track lineage + * when concurrent siblings at the same nesting level interleave. + */ + parentId: number | undefined; /** * The flattened lowercased tags declared on the test * and its ancestor suites, in declaration order. Empty for untagged tests.