diff --git a/types/node/assert.d.ts b/types/node/assert.d.ts index eb9238c24b5518..cd6d6df9ff33d4 100644 --- a/types/node/assert.d.ts +++ b/types/node/assert.d.ts @@ -44,6 +44,13 @@ declare module "assert" { * @default true */ strict?: boolean | undefined; + /** + * If set to `true`, skips prototype and constructor + * comparison in deep equality checks. + * @since v24.9.0 + * @default false + */ + skipPrototype?: boolean | undefined; } interface Assert extends Pick { readonly [kOptions]: AssertOptions & { strict: false }; @@ -67,7 +74,8 @@ declare module "assert" { * ``` * * **Important**: When destructuring assertion methods from an `Assert` instance, - * the methods lose their connection to the instance's configuration options (such as `diff` and `strict` settings). + * the methods lose their connection to the instance's configuration options (such + * as `diff`, `strict`, and `skipPrototype` settings). * The destructured methods will fall back to default behavior instead. * * ```js @@ -81,6 +89,33 @@ declare module "assert" { * strictEqual({ a: 1 }, { b: { c: 1 } }); * ``` * + * The `skipPrototype` option affects all deep equality methods: + * + * ```js + * class Foo { + * constructor(a) { + * this.a = a; + * } + * } + * + * class Bar { + * constructor(a) { + * this.a = a; + * } + * } + * + * const foo = new Foo(1); + * const bar = new Bar(1); + * + * // Default behavior - fails due to different constructors + * const assert1 = new Assert(); + * assert1.deepStrictEqual(foo, bar); // AssertionError + * + * // Skip prototype comparison - passes if properties are equal + * const assert2 = new Assert({ skipPrototype: true }); + * assert2.deepStrictEqual(foo, bar); // OK + * ``` + * * When destructured, methods lose access to the instance's `this` context and revert to default assertion behavior * (diff: 'simple', non-strict mode). * To maintain custom options when using destructured methods, avoid diff --git a/types/node/crypto.d.ts b/types/node/crypto.d.ts index d7c605b98c0f16..e429849b2fce42 100644 --- a/types/node/crypto.d.ts +++ b/types/node/crypto.d.ts @@ -4254,6 +4254,16 @@ declare module "crypto" { * @since v15.6.0 */ readonly serialNumber: string; + /** + * The algorithm used to sign the certificate or `undefined` if the signature algorithm is unknown by OpenSSL. + * @since v24.9.0 + */ + readonly signatureAlgorithm: string | undefined; + /** + * The OID of the algorithm used to sign the certificate. + * @since v24.9.0 + */ + readonly signatureAlgorithmOid: string; /** * The date/time from which this certificate is considered valid. * @since v15.6.0 @@ -5138,9 +5148,9 @@ declare module "crypto" { exportKey(format: "jwk", key: CryptoKey): Promise; exportKey(format: Exclude, key: CryptoKey): Promise; /** - * Using the method and parameters provided in `algorithm`, `subtle.generateKey()` - * attempts to generate new keying material. Depending the method used, the method - * may generate either a single `CryptoKey` or a `CryptoKeyPair`. + * Using the parameters provided in `algorithm`, this method + * attempts to generate new keying material. Depending on the algorithm used + * either a single `CryptoKey` or a `CryptoKeyPair` is generated. * * The `CryptoKeyPair` (public and private key) generating algorithms supported * include: @@ -5198,9 +5208,11 @@ declare module "crypto" { */ getPublicKey(key: CryptoKey, keyUsages: KeyUsage[]): Promise; /** - * The `subtle.importKey()` method attempts to interpret the provided `keyData` as the given `format` - * to create a `` instance using the provided `algorithm`, `extractable`, and `keyUsages` arguments. - * If the import is successful, the returned promise will be resolved with the created ``. + * This method attempts to interpret the provided `keyData` + * as the given `format` to create a `CryptoKey` instance using the provided + * `algorithm`, `extractable`, and `keyUsages` arguments. If the import is + * successful, the returned promise will be resolved with a {CryptoKey} + * representation of the key material. * * If importing KDF algorithm keys, `extractable` must be `false`. * @param format Must be one of `'raw'`, `'pkcs8'`, `'spki'`, `'jwk'`, `'raw-secret'`, diff --git a/types/node/http.d.ts b/types/node/http.d.ts index f4ea91b3fe4df5..df46bc28e5a43f 100644 --- a/types/node/http.d.ts +++ b/types/node/http.d.ts @@ -339,6 +339,17 @@ declare module "http" { * If the header's value is an array, the items will be joined using `; `. */ uniqueHeaders?: Array | undefined; + /** + * A callback which receives an + * incoming request and returns a boolean, to control which upgrade attempts + * should be accepted. Accepted upgrades will fire an `'upgrade'` event (or + * their sockets will be destroyed, if no listener is registered) while + * rejected upgrades will fire a `'request'` event like any non-upgrade + * request. + * @since v24.9.0 + * @default () => server.listenerCount('upgrade') > 0 + */ + shouldUpgradeCallback?: ((request: InstanceType) => boolean) | undefined; /** * If set to `true`, an error is thrown when writing to an HTTP response which does not have a body. * @default false diff --git a/types/node/package.json b/types/node/package.json index 10a75314bcdd5d..686f9ed1dc7d35 100644 --- a/types/node/package.json +++ b/types/node/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@types/node", - "version": "24.8.9999", + "version": "24.9.9999", "nonNpm": "conflict", "nonNpmDescription": "Node.js", "projects": [ @@ -18,7 +18,7 @@ } }, "dependencies": { - "undici-types": "~7.14.0" + "undici-types": "~7.16.0" }, "devDependencies": { "@types/node": "workspace:." diff --git a/types/node/sqlite.d.ts b/types/node/sqlite.d.ts index 50be8b539bb5b8..4a533758bbca53 100644 --- a/types/node/sqlite.d.ts +++ b/types/node/sqlite.d.ts @@ -355,6 +355,47 @@ declare module "node:sqlite" { * @return The prepared statement. */ prepare(sql: string): StatementSync; + /** + * Creates a new `SQLTagStore`, which is an LRU (Least Recently Used) cache for + * storing prepared statements. This allows for the efficient reuse of prepared + * statements by tagging them with a unique identifier. + * + * When a tagged SQL literal is executed, the `SQLTagStore` checks if a prepared + * statement for that specific SQL string already exists in the cache. If it does, + * the cached statement is used. If not, a new prepared statement is created, + * executed, and then stored in the cache for future use. This mechanism helps to + * avoid the overhead of repeatedly parsing and preparing the same SQL statements. + * + * ```js + * import { DatabaseSync } from 'node:sqlite'; + * + * const db = new DatabaseSync(':memory:'); + * const sql = db.createSQLTagStore(); + * + * db.exec('CREATE TABLE users (id INT, name TEXT)'); + * + * // Using the 'run' method to insert data. + * // The tagged literal is used to identify the prepared statement. + * sql.run`INSERT INTO users VALUES (1, 'Alice')`; + * sql.run`INSERT INTO users VALUES (2, 'Bob')`; + * + * // Using the 'get' method to retrieve a single row. + * const id = 1; + * const user = sql.get`SELECT * FROM users WHERE id = ${id}`; + * console.log(user); // { id: 1, name: 'Alice' } + * + * // Using the 'all' method to retrieve all rows. + * const allUsers = sql.all`SELECT * FROM users ORDER BY id`; + * console.log(allUsers); + * // [ + * // { id: 1, name: 'Alice' }, + * // { id: 2, name: 'Bob' } + * // ] + * ``` + * @since v24.9.0 + * @returns A new SQL tag store for caching prepared statements. + */ + createTagStore(maxSize?: number): SQLTagStore; /** * Creates and attaches a session to the database. This method is a wrapper around * [`sqlite3session_create()`](https://www.sqlite.org/session/sqlite3session_create.html) and @@ -428,6 +469,73 @@ declare module "node:sqlite" { */ close(): void; } + /** + * This class represents a single LRU (Least Recently Used) cache for storing + * prepared statements. + * + * Instances of this class are created via the database.createSQLTagStore() method, + * not by using a constructor. The store caches prepared statements based on the + * provided SQL query string. When the same query is seen again, the store + * retrieves the cached statement and safely applies the new values through + * parameter binding, thereby preventing attacks like SQL injection. + * + * The cache has a maxSize that defaults to 1000 statements, but a custom size can + * be provided (e.g., database.createSQLTagStore(100)). All APIs exposed by this + * class execute synchronously. + * @since v24.9.0 + */ + interface SQLTagStore { + /** + * Executes the given SQL query and returns all resulting rows as an array of objects. + * @since v24.9.0 + */ + all( + stringElements: TemplateStringsArray, + ...boundParameters: SQLInputValue[] + ): Record[]; + /** + * Executes the given SQL query and returns the first resulting row as an object. + * @since v24.9.0 + */ + get( + stringElements: TemplateStringsArray, + ...boundParameters: SQLInputValue[] + ): Record | undefined; + /** + * Executes the given SQL query and returns an iterator over the resulting rows. + * @since v24.9.0 + */ + iterate( + stringElements: TemplateStringsArray, + ...boundParameters: SQLInputValue[] + ): NodeJS.Iterator>; + /** + * Executes the given SQL query, which is expected to not return any rows (e.g., INSERT, UPDATE, DELETE). + * @since v24.9.0 + */ + run(stringElements: TemplateStringsArray, ...boundParameters: SQLInputValue[]): StatementResultingChanges; + /** + * A read-only property that returns the number of prepared statements currently in the cache. + * @since v24.9.0 + * @returns The maximum number of prepared statements the cache can hold. + */ + size(): number; + /** + * A read-only property that returns the maximum number of prepared statements the cache can hold. + * @since v24.9.0 + */ + readonly capacity: number; + /** + * A read-only property that returns the `DatabaseSync` object associated with this `SQLTagStore`. + * @since v24.9.0 + */ + readonly db: DatabaseSync; + /** + * Resets the LRU cache, clearing all stored prepared statements. + * @since v24.9.0 + */ + clear(): void; + } interface StatementColumnMetadata { /** * The unaliased name of the column in the origin diff --git a/types/node/test/assert.ts b/types/node/test/assert.ts index 62ea05f33ef152..7594522fc8f6ce 100644 --- a/types/node/test/assert.ts +++ b/types/node/test/assert.ts @@ -225,6 +225,7 @@ assert.partialDeepStrictEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 }); // The type annotation is mandatory here to avoid TS2775 const strictCustomAssert: assert.AssertStrict = new assert.Assert({ diff: "full", + skipPrototype: true, }); strictCustomAssert.equal(n, 1); _1 = n; diff --git a/types/node/test/crypto.ts b/types/node/test/crypto.ts index d0cb7be8ff4b39..bef5920ae5fa66 100644 --- a/types/node/test/crypto.ts +++ b/types/node/test/crypto.ts @@ -1573,6 +1573,8 @@ import { promisify } from "node:util"; cert.publicKey; // $ExpectType KeyObject cert.raw; // $ExpectType Buffer || Buffer cert.serialNumber; // $ExpectType string + cert.signatureAlgorithm; // $ExpectType string | undefined + cert.signatureAlgorithmOid; // $ExpectType string cert.subject; // $ExpectType string cert.subjectAltName; // $ExpectType string | undefined cert.validFrom; // $ExpectType string diff --git a/types/node/test/http.ts b/types/node/test/http.ts index 67bba86b57ffa4..102ba8e6eb408e 100644 --- a/types/node/test/http.ts +++ b/types/node/test/http.ts @@ -40,6 +40,10 @@ import * as url from "node:url"; headersTimeout: 50000, requireHostHeader: false, rejectNonStandardBodyWrites: false, + shouldUpgradeCallback(request) { + request; // $ExpectType IncomingMessage + return true; + }, }, reqListener); server.close(); diff --git a/types/node/test/sqlite.ts b/types/node/test/sqlite.ts index bd2ff1e27bc58b..7b64d962492d63 100644 --- a/types/node/test/sqlite.ts +++ b/types/node/test/sqlite.ts @@ -7,6 +7,9 @@ import { TextEncoder } from "node:util"; database.isOpen; // $ExpectType boolean database.isTransaction; // $ExpectType boolean + database.createTagStore(); // $ExpectType SQLTagStore + database.createTagStore(100); // $ExpectType SQLTagStore + database.exec(` CREATE TABLE data( key INTEGER PRIMARY KEY, @@ -142,3 +145,21 @@ import { TextEncoder } from "node:util"; }, ); } + +{ + const db = new DatabaseSync(":memory:"); + const tagStore = db.createTagStore(); + + const id = 12345; + const name = "Alice"; + + tagStore.all`SELECT * FROM users ORDER BY id`; // $ExpectType Record[] + tagStore.get`SELECT * FROM users WHERE id = ${id}`; // $ExpectType Record | undefined + tagStore.iterate`SELECT * FROM users WHERE id = ${id}`; // $ExpectType Iterator, undefined, any> + tagStore.run`INSERT INTO users VALUES (${id}, ${name})`; // $ExpectType StatementResultingChanges + + tagStore.size(); // $ExpectType number + tagStore.capacity; // $ExpectType number + tagStore.db; // $ExpectType DatabaseSync + tagStore.clear(); +} diff --git a/types/node/test/util.ts b/types/node/test/util.ts index dc29db5be59d55..41bf62bedb74ba 100644 --- a/types/node/test/util.ts +++ b/types/node/test/util.ts @@ -213,7 +213,8 @@ util.deprecate(util.deprecate, "deprecate() is deprecated, use bar() instead"); util.deprecate(util.deprecate, "deprecate() is deprecated, use bar() instead", "DEP0001"); // util.isDeepStrictEqual -util.isDeepStrictEqual({ foo: "bar" }, { foo: "bar" }); +util.isDeepStrictEqual({ foo: "bar" }, { foo: "bar" }); // $ExpectType boolean +util.isDeepStrictEqual({ foo: "bar" }, { foo: "bar" }, { skipPrototype: true }); // $ExpectType boolean // util.TextDecoder() const td = new util.TextDecoder(); diff --git a/types/node/test/vm.ts b/types/node/test/vm.ts index 199604adb1b0a2..e84b58b6ae9316 100644 --- a/types/node/test/vm.ts +++ b/types/node/test/vm.ts @@ -216,6 +216,9 @@ import { resolveAndLinkDependencies(rootModule); rootModule.instantiate(); + rootModule.hasAsyncGraph(); // $ExpectType boolean + rootModule.hasTopLevelAwait(); // $ExpectType boolean + await rootModule.evaluate(); }); diff --git a/types/node/test/worker_threads.ts b/types/node/test/worker_threads.ts index afba6c5a3312e8..5891fddb9839ca 100644 --- a/types/node/test/worker_threads.ts +++ b/types/node/test/worker_threads.ts @@ -79,6 +79,9 @@ import { createContext } from "node:vm"; w.startCpuProfile().then(handle => { handle.stop().then(JSON.parse); }); + w.startHeapProfile().then(handle => { + handle.stop().then(JSON.parse); + }); w.terminate().then(() => { // woot }); diff --git a/types/node/util.d.ts b/types/node/util.d.ts index 9a01b35b0fc066..9a3f5ad8e093bb 100644 --- a/types/node/util.d.ts +++ b/types/node/util.d.ts @@ -853,6 +853,15 @@ declare module "util" { * @return The deprecated function wrapped to emit a warning. */ export function deprecate(fn: T, msg: string, code?: string): T; + export interface IsDeepStrictEqualOptions { + /** + * If `true`, prototype and constructor + * comparison is skipped during deep strict equality check. + * @since v24.9.0 + * @default false + */ + skipPrototype?: boolean | undefined; + } /** * Returns `true` if there is deep strict equality between `val1` and `val2`. * Otherwise, returns `false`. @@ -861,7 +870,7 @@ declare module "util" { * equality. * @since v9.0.0 */ - export function isDeepStrictEqual(val1: unknown, val2: unknown): boolean; + export function isDeepStrictEqual(val1: unknown, val2: unknown, options?: IsDeepStrictEqualOptions): boolean; /** * Returns `str` with any ANSI escape codes removed. * diff --git a/types/node/v8.d.ts b/types/node/v8.d.ts index 038fcda4eca611..e4d668d2d25982 100644 --- a/types/node/v8.d.ts +++ b/types/node/v8.d.ts @@ -416,6 +416,22 @@ declare module "v8" { */ [Symbol.asyncDispose](): Promise; } + /** + * @since v24.9.0 + */ + interface HeapProfileHandle { + /** + * Stopping collecting the profile, then return a Promise that fulfills with an error or the + * profile data. + * @since v24.9.0 + */ + stop(): Promise; + /** + * Stopping collecting the profile and the profile will be discarded. + * @since v24.9.0 + */ + [Symbol.asyncDispose](): Promise; + } /** * V8 only supports `Latin-1/ISO-8859-1` and `UTF16` as the underlying representation of a string. * If the `content` uses `Latin-1/ISO-8859-1` as the underlying representation, this function will return true; diff --git a/types/node/vm.d.ts b/types/node/vm.d.ts index bf36187a6a77cc..e51721e9068791 100644 --- a/types/node/vm.d.ts +++ b/types/node/vm.d.ts @@ -962,6 +962,26 @@ declare module "vm" { * @deprecated Use `sourceTextModule.moduleRequests` instead. */ readonly dependencySpecifiers: readonly string[]; + /** + * Iterates over the dependency graph and returns `true` if any module in its + * dependencies or this module itself contains top-level `await` expressions, + * otherwise returns `false`. + * + * The search may be slow if the graph is big enough. + * + * This requires the module to be instantiated first. If the module is not + * instantiated yet, an error will be thrown. + * @since v24.9.0 + */ + hasAsyncGraph(): boolean; + /** + * Returns whether the module itself contains any top-level `await` expressions. + * + * This corresponds to the field `[[HasTLA]]` in [Cyclic Module Record](https://tc39.es/ecma262/#sec-cyclic-module-records) in the + * ECMAScript specification. + * @since v24.9.0 + */ + hasTopLevelAwait(): boolean; /** * Instantiate the module with the linked requested modules. * diff --git a/types/node/worker_threads.d.ts b/types/node/worker_threads.d.ts index e6b45159decd67..cc947c044e8f75 100644 --- a/types/node/worker_threads.d.ts +++ b/types/node/worker_threads.d.ts @@ -62,7 +62,7 @@ declare module "worker_threads" { import { Readable, Writable } from "node:stream"; import { ReadableStream, TransformStream, WritableStream } from "node:stream/web"; import { URL } from "node:url"; - import { CPUProfileHandle, HeapInfo } from "node:v8"; + import { CPUProfileHandle, HeapInfo, HeapProfileHandle } from "node:v8"; import { MessageEvent } from "undici-types"; const isInternalThread: boolean; const isMainThread: boolean; @@ -492,10 +492,10 @@ declare module "worker_threads" { * `await using` example. * * ```js - * const { Worker } = require('node::worker_threads'); + * const { Worker } = require('node:worker_threads'); * * const w = new Worker(` - * const { parentPort } = require('worker_threads'); + * const { parentPort } = require('node:worker_threads'); * parentPort.on('message', () => {}); * `, { eval: true }); * @@ -507,6 +507,43 @@ declare module "worker_threads" { * @since v24.8.0 */ startCpuProfile(): Promise; + /** + * Starting a Heap profile then return a Promise that fulfills with an error + * or an `HeapProfileHandle` object. This API supports `await using` syntax. + * + * ```js + * const { Worker } = require('node:worker_threads'); + * + * const worker = new Worker(` + * const { parentPort } = require('worker_threads'); + * parentPort.on('message', () => {}); + * `, { eval: true }); + * + * worker.on('online', async () => { + * const handle = await worker.startHeapProfile(); + * const profile = await handle.stop(); + * console.log(profile); + * worker.terminate(); + * }); + * ``` + * + * `await using` example. + * + * ```js + * const { Worker } = require('node:worker_threads'); + * + * const w = new Worker(` + * const { parentPort } = require('node:worker_threads'); + * parentPort.on('message', () => {}); + * `, { eval: true }); + * + * w.on('online', async () => { + * // Stop profile automatically when return and profile will be discarded + * await using handle = await w.startHeapProfile(); + * }); + * ``` + */ + startHeapProfile(): Promise; /** * Calls `worker.terminate()` when the dispose scope is exited. *