Repository: DefinitelyTyped/DefinitelyTyped
Pull request #71922: [node] Update typings to v22.14.0
Author: login: Renegade334
Labels: name: Self Merge
description: This PR can now be self-merged by the PR author or an owner
name: Maintainer Approved
name: Critical package
Created: 2025-02-13T01:16:06Z | Merged: 2025-04-02T18:23:06Z

- deps: update undici to 6.21.1
- doc: add note for features using `InternalWorker` with permission model
- doc: expand description of `parseArg`'s `default`
- fs: allow `exclude` option in globs to accept glob patterns
- module: add `findPackageJSON` util
- process: add process.ref() and process.unref() methods
- sqlite: pass conflict type to conflict resolution handler
- sqlite: support TypedArray and DataView in `StatementSync`
- src,worker: add isInternalWorker
- test_runner: add assert.register() API
- test_runner: add TestContext.prototype.waitFor()
- test_runner: add t.assert.fileSnapshot()
- util: expose CallSite.scriptId
- util: rename CallSite.column to columnNumber

----

- [x] Use a meaningful title for the pull request. Include the name of the package modified.
- [x] Test the change in your own code. (Compile and run.)
- [x] [Add or edit tests](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.md#my-package-teststs) to reflect the change.
- [x] Follow the advice from the [readme](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.md#make-a-pull-request).
- [x] Avoid [common mistakes](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.md#common-mistakes).
- [x] [Run `pnpm test <package to test>`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.md#running-tests).

If changing an existing definition:

- [x] Provide a URL to documentation or source code which provides context for the suggested changes: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V22.md#22.14.0
- [x] If this PR brings the type definitions up to date with a new version of the JS library, update the version number in the `package.json`.



Diff:
diff --git a/types/node/fs.d.ts b/types/node/fs.d.ts
index aba529b50791a7..45b991a12207cb 100644
--- a/types/node/fs.d.ts
+++ b/types/node/fs.d.ts
@@ -4261,7 +4261,7 @@ declare module "fs" {
      */
     export function cpSync(source: string | URL, destination: string | URL, opts?: CopySyncOptions): void;
 
-    interface GlobOptionsBase {
+    interface _GlobOptions<T extends Dirent | string> {
         /**
          * Current working directory.
          * @default process.cwd()
@@ -4274,21 +4274,20 @@ declare module "fs" {
          */
         withFileTypes?: boolean | undefined;
         /**
-         * Function to filter out files/directories. Return true to exclude the item, false to include it.
+         * Function to filter out files/directories or a
+         * list of glob patterns to be excluded. If a function is provided, return
+         * `true` to exclude the item, `false` to include it.
+         * @default undefined
          */
-        exclude?: ((fileName: any) => boolean) | undefined;
+        exclude?: ((fileName: T) => boolean) | readonly string[] | undefined;
     }
-    export interface GlobOptionsWithFileTypes extends GlobOptionsBase {
-        exclude?: ((fileName: Dirent) => boolean) | undefined;
+    export interface GlobOptions extends _GlobOptions<Dirent | string> {}
+    export interface GlobOptionsWithFileTypes extends _GlobOptions<Dirent> {
         withFileTypes: true;
     }
-    export interface GlobOptionsWithoutFileTypes extends GlobOptionsBase {
-        exclude?: ((fileName: string) => boolean) | undefined;
+    export interface GlobOptionsWithoutFileTypes extends _GlobOptions<string> {
         withFileTypes?: false | undefined;
     }
-    export interface GlobOptions extends GlobOptionsBase {
-        exclude?: ((fileName: Dirent | string) => boolean) | undefined;
-    }
 
     /**
      * Retrieves the files matching the specified pattern.
diff --git a/types/node/module.d.ts b/types/node/module.d.ts
index 56309c78fbb1ea..545532adc4b033 100644
--- a/types/node/module.d.ts
+++ b/types/node/module.d.ts
@@ -128,12 +128,54 @@ declare module "module" {
          */
         function getCompileCacheDir(): string | undefined;
         /**
-         * @since v23.2.0, v22.14.0
+         * ```text
+         * /path/to/project
+         *   ├ packages/
+         *     ├ bar/
+         *       ├ bar.js
+         *       └ package.json // name = '@foo/bar'
+         *     └ qux/
+         *       ├ node_modules/
+         *         └ some-package/
+         *           └ package.json // name = 'some-package'
+         *       ├ qux.js
+         *       └ package.json // name = '@foo/qux'
+         *   ├ main.js
+         *   └ package.json // name = '@foo'
+         * ```
+         * ```js
+         * // /path/to/project/packages/bar/bar.js
+         * import { findPackageJSON } from 'node:module';
+         *
+         * findPackageJSON('..', import.meta.url);
+         * // '/path/to/project/package.json'
+         * // Same result when passing an absolute specifier instead:
+         * findPackageJSON(new URL('../', import.meta.url));
+         * findPackageJSON(import.meta.resolve('../'));
+         *
+         * findPackageJSON('some-package', import.meta.url);
+         * // '/path/to/project/packages/bar/node_modules/some-package/package.json'
+         * // When passing an absolute specifier, you might get a different result if the
+         * // resolved module is inside a subfolder that has nested `package.json`.
+         * findPackageJSON(import.meta.resolve('some-package'));
+         * // '/path/to/project/packages/bar/node_modules/some-package/some-subfolder/package.json'
+         *
+         * findPackageJSON('@foo/qux', import.meta.url);
+         * // '/path/to/project/packages/qux/package.json'
+         * ```
+         * @since v22.14.0
+         * @param specifier The specifier for the module whose `package.json` to
+         * retrieve. When passing a _bare specifier_, the `package.json` at the root of
+         * the package is returned. When passing a _relative specifier_ or an _absolute specifier_,
+         * the closest parent `package.json` is returned.
+         * @param base The absolute location (`file:` URL string or FS path) of the
+         * containing  module. For CJS, use `__filename` (not `__dirname`!); for ESM, use
+         * `import.meta.url`. You do not need to pass it if `specifier` is an _absolute specifier_.
+         * @returns A path if the `package.json` is found. When `startLocation`
+         * is a package, the package's root `package.json`; when a relative or unresolved, the closest
+         * `package.json` to the `startLocation`.
          */
-        function findPackageJSON(
-            specifier: string | URL,
-            base?: string | URL,
-        ): undefined | string;
+        function findPackageJSON(specifier: string | URL, base?: string | URL): string | undefined;
         /**
          * @since v18.6.0, v16.17.0
          */
@@ -162,6 +204,9 @@ declare module "module" {
          * Register a module that exports hooks that customize Node.js module
          * resolution and loading behavior. See
          * [Customization hooks](https://nodejs.org/docs/latest-v22.x/api/module.html#customization-hooks).
+         *
+         * This feature requires `--allow-worker` if used with the
+         * [Permission Model](https://nodejs.org/docs/latest-v22.x/api/permissions.html#permission-model).
          * @since v20.6.0, v18.19.0
          * @param specifier Customization hooks to be registered; this should be
          * the same string that would be passed to `import()`, except that if it is
diff --git a/types/node/package.json b/types/node/package.json
index fd2a5ab40f0112..be30ab0f4b5553 100644
--- a/types/node/package.json
+++ b/types/node/package.json
@@ -1,7 +1,7 @@
 {
     "private": true,
     "name": "@types/node",
-    "version": "22.13.9999",
+    "version": "22.14.9999",
     "nonNpm": "conflict",
     "nonNpmDescription": "Node.js",
     "projects": [
@@ -15,7 +15,7 @@
         }
     },
     "dependencies": {
-        "undici-types": "~6.20.0"
+        "undici-types": "~6.21.0"
     },
     "devDependencies": {
         "@types/node": "workspace:."
diff --git a/types/node/process.d.ts b/types/node/process.d.ts
index c7225eb66fad90..63b6525878620b 100644
--- a/types/node/process.d.ts
+++ b/types/node/process.d.ts
@@ -1910,6 +1910,34 @@ declare module "process" {
                  * @since v0.8.0
                  */
                 traceDeprecation: boolean;
+                /**
+                 * An object is "refable" if it implements the Node.js "Refable protocol".
+                 * Specifically, this means that the object implements the `Symbol.for('nodejs.ref')`
+                 * and `Symbol.for('nodejs.unref')` methods. "Ref'd" objects will keep the Node.js
+                 * event loop alive, while "unref'd" objects will not. Historically, this was
+                 * implemented by using `ref()` and `unref()` methods directly on the objects.
+                 * This pattern, however, is being deprecated in favor of the "Refable protocol"
+                 * in order to better support Web Platform API types whose APIs cannot be modified
+                 * to add `ref()` and `unref()` methods but still need to support that behavior.
+                 * @since v22.14.0
+                 * @experimental
+                 * @param maybeRefable An object that may be "refable".
+                 */
+                ref(maybeRefable: any): void;
+                /**
+                 * An object is "unrefable" if it implements the Node.js "Refable protocol".
+                 * Specifically, this means that the object implements the `Symbol.for('nodejs.ref')`
+                 * and `Symbol.for('nodejs.unref')` methods. "Ref'd" objects will keep the Node.js
+                 * event loop alive, while "unref'd" objects will not. Historically, this was
+                 * implemented by using `ref()` and `unref()` methods directly on the objects.
+                 * This pattern, however, is being deprecated in favor of the "Refable protocol"
+                 * in order to better support Web Platform API types whose APIs cannot be modified
+                 * to add `ref()` and `unref()` methods but still need to support that behavior.
+                 * @since v22.14.0
+                 * @experimental
+                 * @param maybeRefable An object that may be "unref'd".
+                 */
+                unref(maybeRefable: any): void;
                 /* EventEmitter */
                 addListener(event: "beforeExit", listener: BeforeExitListener): this;
                 addListener(event: "disconnect", listener: DisconnectListener): this;
diff --git a/types/node/sqlite.d.ts b/types/node/sqlite.d.ts
index e95a5411ddcaf0..bd0c4ebf4d321c 100644
--- a/types/node/sqlite.d.ts
+++ b/types/node/sqlite.d.ts
@@ -43,7 +43,10 @@
  * @see [source](https://github.com/nodejs/node/blob/v22.x/lib/sqlite.js)
  */
 declare module "node:sqlite" {
-    type SupportedValueType = null | number | bigint | string | Uint8Array;
+    type SQLInputValue = null | number | bigint | string | NodeJS.ArrayBufferView;
+    type SQLOutputValue = null | number | bigint | string | Uint8Array;
+    /** @deprecated Use `SQLInputValue` or `SQLOutputValue` instead. */
+    type SupportedValueType = SQLOutputValue;
     interface DatabaseSyncOptions {
         /**
          * If `true`, the database is opened by the constructor. When
@@ -109,10 +112,30 @@ declare module "node:sqlite" {
          */
         filter?: ((tableName: string) => boolean) | undefined;
         /**
-         * Determines how conflicts are handled. **Default**: `SQLITE_CHANGESET_ABORT`.
+         * A function that determines how to handle conflicts. The function receives one argument,
+         * which can be one of the following values:
+         *
+         * * `SQLITE_CHANGESET_DATA`: A `DELETE` or `UPDATE` change does not contain the expected "before" values.
+         * * `SQLITE_CHANGESET_NOTFOUND`: A row matching the primary key of the `DELETE` or `UPDATE` change does not exist.
+         * * `SQLITE_CHANGESET_CONFLICT`: An `INSERT` change results in a duplicate primary key.
+         * * `SQLITE_CHANGESET_FOREIGN_KEY`: Applying a change would result in a foreign key violation.
+         * * `SQLITE_CHANGESET_CONSTRAINT`: Applying a change results in a `UNIQUE`, `CHECK`, or `NOT NULL` constraint
+         * violation.
+         *
+         * The function should return one of the following values:
+         *
+         * * `SQLITE_CHANGESET_OMIT`: Omit conflicting changes.
+         * * `SQLITE_CHANGESET_REPLACE`: Replace existing values with conflicting changes (only valid with
+             `SQLITE_CHANGESET_DATA` or `SQLITE_CHANGESET_CONFLICT` conflicts).
+         * * `SQLITE_CHANGESET_ABORT`: Abort on conflict and roll back the database.
+         *
+         * When an error is thrown in the conflict handler or when any other value is returned from the handler,
+         * applying the changeset is aborted and the database is rolled back.
+         *
+         * **Default**: A function that returns `SQLITE_CHANGESET_ABORT`.
          * @since v22.12.0
          */
-        onConflict?: number | undefined;
+        onConflict?: ((conflictType: number) => number) | undefined;
     }
     interface FunctionOptions {
         /**
@@ -322,11 +345,11 @@ declare module "node:sqlite" {
          * @return An array of objects. Each object corresponds to a row returned by executing the prepared statement. The keys and values of each object correspond to the column names and values of
          * the row.
          */
-        all(...anonymousParameters: SupportedValueType[]): unknown[];
+        all(...anonymousParameters: SQLInputValue[]): Record<string, SQLOutputValue>[];
         all(
-            namedParameters: Record<string, SupportedValueType>,
-            ...anonymousParameters: SupportedValueType[]
-        ): unknown[];
+            namedParameters: Record<string, SQLInputValue>,
+            ...anonymousParameters: SQLInputValue[]
+        ): Record<string, SQLOutputValue>[];
         /**
          * The source SQL text of the prepared statement with parameter
          * placeholders replaced by the values that were used during the most recent
@@ -346,8 +369,11 @@ declare module "node:sqlite" {
          * @return An object corresponding to the first row returned by executing the prepared statement. The keys and values of the object correspond to the column names and values of the row. If no
          * rows were returned from the database then this method returns `undefined`.
          */
-        get(...anonymousParameters: SupportedValueType[]): unknown;
-        get(namedParameters: Record<string, SupportedValueType>, ...anonymousParameters: SupportedValueType[]): unknown;
+        get(...anonymousParameters: SQLInputValue[]): Record<string, SQLOutputValue> | undefined;
+        get(
+            namedParameters: Record<string, SQLInputValue>,
+            ...anonymousParameters: SQLInputValue[]
+        ): Record<string, SQLOutputValue> | undefined;
         /**
          * This method executes a prepared statement and returns an iterator of
          * objects. If the prepared statement does not return any results, this method
@@ -361,11 +387,11 @@ declare module "node:sqlite" {
          * returned by executing the prepared statement. The keys and values of each
          * object correspond to the column names and values of the row.
          */
-        iterate(...anonymousParameters: SupportedValueType[]): NodeJS.Iterator<unknown>;
+        iterate(...anonymousParameters: SQLInputValue[]): NodeJS.Iterator<Record<string, SQLOutputValue>>;
         iterate(
-            namedParameters: Record<string, SupportedValueType>,
-            ...anonymousParameters: SupportedValueType[]
-        ): NodeJS.Iterator<unknown>;
+            namedParameters: Record<string, SQLInputValue>,
+            ...anonymousParameters: SQLInputValue[]
+        ): NodeJS.Iterator<Record<string, SQLOutputValue>>;
         /**
          * This method executes a prepared statement and returns an object summarizing the
          * resulting changes. The prepared statement [parameters are bound](https://www.sqlite.org/c3ref/bind_blob.html) using the
@@ -374,10 +400,10 @@ declare module "node:sqlite" {
          * @param namedParameters An optional object used to bind named parameters. The keys of this object are used to configure the mapping.
          * @param anonymousParameters Zero or more values to bind to anonymous parameters.
          */
-        run(...anonymousParameters: SupportedValueType[]): StatementResultingChanges;
+        run(...anonymousParameters: SQLInputValue[]): StatementResultingChanges;
         run(
-            namedParameters: Record<string, SupportedValueType>,
-            ...anonymousParameters: SupportedValueType[]
+            namedParameters: Record<string, SQLInputValue>,
+            ...anonymousParameters: SQLInputValue[]
         ): StatementResultingChanges;
         /**
          * The names of SQLite parameters begin with a prefix character. By default,`node:sqlite` requires that this prefix character is present when binding
@@ -420,13 +446,33 @@ declare module "node:sqlite" {
      * @since v22.13.0
      */
     namespace constants {
+        /**
+         * The conflict handler is invoked with this constant when processing a DELETE or UPDATE change if a row with the required PRIMARY KEY fields is present in the database, but one or more other (non primary-key) fields modified by the update do not contain the expected "before" values.
+         * @since v22.14.0
+         */
+        const SQLITE_CHANGESET_DATA: number;
+        /**
+         * The conflict handler is invoked with this constant when processing a DELETE or UPDATE change if a row with the required PRIMARY KEY fields is not present in the database.
+         * @since v22.14.0
+         */
+        const SQLITE_CHANGESET_NOTFOUND: number;
+        /**
+         * This constant is passed to the conflict handler while processing an INSERT change if the operation would result in duplicate primary key values.
+         * @since v22.14.0
+         */
+        const SQLITE_CHANGESET_CONFLICT: number;
+        /**
+         * If foreign key handling is enabled, and applying a changeset leaves the database in a state containing foreign key violations, the conflict handler is invoked with this constant exactly once before the changeset is committed. If the conflict handler returns `SQLITE_CHANGESET_OMIT`, the changes, including those that caused the foreign key constraint violation, are committed. Or, if it returns `SQLITE_CHANGESET_ABORT`, the changeset is rolled back.
+         * @since v22.14.0
+         */
+        const SQLITE_CHANGESET_FOREIGN_KEY: number;
         /**
          * Conflicting changes are omitted.
          * @since v22.12.0
          */
         const SQLITE_CHANGESET_OMIT: number;
         /**
-         * Conflicting changes replace existing values.
+         * Conflicting changes replace existing values. Note that this value can only be returned when the type of conflict is either `SQLITE_CHANGESET_DATA` or `SQLITE_CHANGESET_CONFLICT`.
          * @since v22.12.0
          */
         const SQLITE_CHANGESET_REPLACE: number;
diff --git a/types/node/test.d.ts b/types/node/test.d.ts
index d7ca0168d4859d..fc8e72c9b9faf2 100644
--- a/types/node/test.d.ts
+++ b/types/node/test.d.ts
@@ -147,6 +147,7 @@ declare module "node:test" {
         export {
             after,
             afterEach,
+            assert,
             before,
             beforeEach,
             describe,
@@ -753,6 +754,18 @@ declare module "node:test" {
          * @returns A {@link Promise} resolved with `undefined` once the test completes.
          */
         test: typeof test;
+        /**
+         * This method polls a `condition` function until that function either returns
+         * successfully or the operation times out.
+         * @since v22.14.0
+         * @param condition An assertion function that is invoked
+         * periodically until it completes successfully or the defined polling timeout
+         * elapses. Successful completion is defined as not throwing or rejecting. This
+         * function does not accept any arguments, and is allowed to return any value.
+         * @param options An optional configuration object for the polling operation.
+         * @returns Fulfilled with the value returned by `condition`.
+         */
+        waitFor<T>(condition: () => T, options?: TestContextWaitForOptions): Promise<Awaited<T>>;
         /**
          * Each test provides its own MockTracker instance.
          */
@@ -781,6 +794,33 @@ declare module "node:test" {
             | "throws"
         >
     {
+        /**
+         * This function serializes `value` and writes it to the file specified by `path`.
+         *
+         * ```js
+         * test('snapshot test with default serialization', (t) => {
+         *   t.assert.fileSnapshot({ value1: 1, value2: 2 }, './snapshots/snapshot.json');
+         * });
+         * ```
+         *
+         * This function differs from `context.assert.snapshot()` in the following ways:
+         *
+         * * The snapshot file path is explicitly provided by the user.
+         * * Each snapshot file is limited to a single snapshot value.
+         * * No additional escaping is performed by the test runner.
+         *
+         * These differences allow snapshot files to better support features such as syntax
+         * highlighting.
+         * @since v22.14.0
+         * @param value A value to serialize to a string. If Node.js was started with
+         * the [`--test-update-snapshots`](https://nodejs.org/docs/latest-v22.x/api/cli.html#--test-update-snapshots)
+         * flag, the serialized value is written to
+         * `path`. Otherwise, the serialized value is compared to the contents of the
+         * existing snapshot file.
+         * @param path The file where the serialized `value` is written.
+         * @param options Optional configuration options.
+         */
+        fileSnapshot(value: any, path: string, options?: AssertSnapshotOptions): void;
         /**
          * This function implements assertions for snapshot testing.
          * ```js
@@ -795,8 +835,17 @@ declare module "node:test" {
          * });
          * ```
          * @since v22.3.0
+         * @param value A value to serialize to a string. If Node.js was started with
+         * the [`--test-update-snapshots`](https://nodejs.org/docs/latest-v22.x/api/cli.html#--test-update-snapshots)
+         * flag, the serialized value is written to
+         * the snapshot file. Otherwise, the serialized value is compared to the
+         * corresponding value in the existing snapshot file.
          */
         snapshot(value: any, options?: AssertSnapshotOptions): void;
+        /**
+         * A custom assertion function registered with `assert.register()`.
+         */
+        [name: string]: (...args: any[]) => void;
     }
     interface AssertSnapshotOptions {
         /**
@@ -809,6 +858,20 @@ declare module "node:test" {
          */
         serializers?: ReadonlyArray<(value: any) => any> | undefined;
     }
+    interface TestContextWaitForOptions {
+        /**
+         * The number of milliseconds to wait after an unsuccessful
+         * invocation of `condition` before trying again.
+         * @default 50
+         */
+        interval?: number | undefined;
+        /**
+         * The poll timeout in milliseconds. If `condition` has not
+         * succeeded by the time this elapses, an error occurs.
+         * @default 1000
+         */
+        timeout?: number | undefined;
+    }
 
     /**
      * An instance of `SuiteContext` is passed to each suite function in order to
@@ -1594,6 +1657,24 @@ declare module "node:test" {
          */
         [Symbol.dispose](): void;
     }
+    /**
+     * An object whose methods are used to configure available assertions on the
+     * `TestContext` objects in the current process. The methods from `node:assert`
+     * and snapshot testing functions are available by default.
+     *
+     * It is possible to apply the same configuration to all files by placing common
+     * configuration code in a module
+     * preloaded with `--require` or `--import`.
+     * @since v22.14.0
+     */
+    namespace assert {
+        /**
+         * Defines a new assertion function with the provided name and function. If an
+         * assertion already exists with the same name, it is overwritten.
+         * @since v22.14.0
+         */
+        function register(name: string, fn: (this: TestContext, ...args: any[]) => void): void;
+    }
     /**
      * @since v22.3.0
      */
@@ -1625,6 +1706,7 @@ declare module "node:test" {
     export {
         after,
         afterEach,
+        assert,
         before,
         beforeEach,
         describe,
diff --git a/types/node/test/fs.ts b/types/node/test/fs.ts
index 9d161dbac4f0fb..3ffd240a93a339 100644
--- a/types/node/test/fs.ts
+++ b/types/node/test/fs.ts
@@ -1008,52 +1008,40 @@ const anyStatFs: fs.StatsFs | fs.BigIntStatsFs = fs.statfsSync(".", { bigint: Ma
             matches; // $ExpectType Dirent[] | string[]
         },
     );
+    glob("**/*.js", { exclude: ["**/*.generated.js"] }, (err, matches) => {
+        matches; // $ExpectType string[]
+    });
 
-    for (const entry of globSync("**/*.js")) {
-        entry; // $ExpectType string
-    }
-    for (const entry of globSync("**/*.js", { cwd: "/" })) {
-        entry; // $ExpectType string
-    }
-    for (const entry of globSync("**/*.js", { withFileTypes: true })) {
-        entry; // $ExpectType Dirent
-    }
-    for (const entry of globSync("**/*.js", { withFileTypes: Math.random() > 0.5 })) {
-        entry; // $ExpectType Dirent | string
-    }
+    globSync("**/*.js"); // $ExpectType string[]
+    globSync("**/*.js", { cwd: "/" }); // $ExpectType string[]
+    globSync("**/*.js", { withFileTypes: true }); // $ExpectType Dirent[]
+    globSync("**/*.js", { withFileTypes: Math.random() > 0.5 }); // $ExpectType string[] | Dirent[]
 
-    for (
-        const entry of globSync("**/*.js", {
-            exclude: (fileName) => {
-                fileName; // $ExpectType string
-                return false;
-            },
-        })
-    ) {
-        entry; // $ExpectType string
-    }
-    for (
-        const entry of globSync("**/*.js", {
-            withFileTypes: true,
-            exclude: (fileName) => {
-                fileName; // $ExpectType Dirent
-                return false;
-            },
-        })
-    ) {
-        entry; // $ExpectType Dirent
-    }
-    for (
-        const entry of globSync("**/*.js", {
-            withFileTypes: Math.random() > 0.5,
-            exclude: (fileName) => {
-                fileName; // $ExpectType Dirent | string
-                return false;
-            },
-        })
-    ) {
-        entry; // $ExpectType Dirent | string
-    }
+    // $ExpectType string[]
+    globSync("**/*.js", {
+        exclude: (fileName) => {
+            fileName; // $ExpectType string
+            return false;
+        },
+    });
+    // ExpectType Dirent[]
+    globSync("**/*.js", {
+        withFileTypes: true,
+        exclude: (fileName) => {
+            fileName; // $ExpectType Dirent
+            return false;
+        },
+    });
+    // $ExpectType string[] | Dirent[]
+    globSync("**/*.js", {
+        withFileTypes: Math.random() > 0.5,
+        exclude: (fileName) => {
+            fileName; // $ExpectType Dirent | string
+            return false;
+        },
+    });
+    // $ExpectType string[]
+    globSync("**/*.js", { exclude: ["**/*.generated.js"] });
 });
 
 (async () => {
diff --git a/types/node/test/module.ts b/types/node/test/module.ts
index 24a30a5875f757..2822afde813548 100644
--- a/types/node/test/module.ts
+++ b/types/node/test/module.ts
@@ -47,6 +47,11 @@ Module.Module === Module;
     // $ExpectType Require
     Module.createRequire(new URL("file:///usr/lib/node"));
 
+    // $ExpectType string | undefined
+    Module.findPackageJSON("..", __filename);
+    // $ExpectType string | undefined
+    Module.findPackageJSON(new URL("../", "file:///path/to/module"));
+
     // $ExpectType boolean
     Module.isBuiltin("process");
 
diff --git a/types/node/test/process.ts b/types/node/test/process.ts
index f78b3882e0a8e1..d7bb969f692f02 100644
--- a/types/node/test/process.ts
+++ b/types/node/test/process.ts
@@ -244,3 +244,9 @@ process.env.TZ = "test";
     myDisposableObject.dispose();
     finalization.unregister(myDisposableObject);
 }
+
+{
+    const timeout = setTimeout(() => {}, 1000);
+    process.ref(timeout);
+    process.unref(timeout);
+}
diff --git a/types/node/test/sqlite.ts b/types/node/test/sqlite.ts
index 88296a362758f9..2bed5b6fa1463f 100644
--- a/types/node/test/sqlite.ts
+++ b/types/node/test/sqlite.ts
@@ -1,4 +1,4 @@
-import { DatabaseSync, StatementSync } from "node:sqlite";
+import { constants, DatabaseSync, StatementSync } from "node:sqlite";
 import { TextEncoder } from "node:util";
 
 {
@@ -27,11 +27,11 @@ import { TextEncoder } from "node:util";
     insert.run(2, null, null, null, null);
     insert.run(3, Number(8), Number(2.718), String("bar"), Buffer.from("x☃y☃"));
     insert.run(4, 99n, 0xf, "", new Uint8Array());
-    insert.get(); // $ExpectType unknown
+    insert.get(); // $ExpectType Record<string, SQLOutputValue> | undefined
 
     const query = database.prepare("SELECT * FROM data ORDER BY key");
-    query.all(); // $ExpectType unknown[]
-    query.iterate(); // $ExpectType Iterator<unknown, any, any>
+    query.all(); // $ExpectType Record<string, SQLOutputValue>[]
+    query.iterate(); // $ExpectType Iterator<Record<string, SQLOutputValue>, any, any>
 
     const sql = "INSERT INTO types (key, val) VALUES ($k, ?)";
     const stmt = database.prepare(sql);
@@ -71,3 +71,21 @@ import { TextEncoder } from "node:util";
     targetDb.applyChangeset(changeset);
     // Now that the changeset has been applied, targetDb contains the same data as sourceDb.
 }
+
+{
+    const db = new DatabaseSync(":memory:");
+    const session = db.createSession({
+        db: "main",
+        table: "my_table",
+    });
+    db.applyChangeset(session.changeset(), {
+        filter: (table) => {
+            table; // $ExpectType string
+            return true;
+        },
+        onConflict: (conflictType) => {
+            conflictType; // $ExpectType number
+            return constants.SQLITE_CHANGESET_ABORT;
+        },
+    });
+}
diff --git a/types/node/test/test.ts b/types/node/test/test.ts
index 1053e2a033e44a..f9ca3f998c6c3f 100644
--- a/types/node/test/test.ts
+++ b/types/node/test/test.ts
@@ -1,3 +1,4 @@
+import * as assert from "node:assert";
 import { Readable, Transform, TransformCallback, TransformOptions } from "node:stream";
 import {
     after,
@@ -992,6 +993,17 @@ test("test on the default export", (t) => {
     contextTest(t);
 });
 
+test("waitFor()", (t) => {
+    // $ExpectType Promise<void>
+    t.waitFor(() => {}, { interval: 100, timeout: 10_000 });
+    // $ExpectType Promise<void>
+    t.waitFor(async () => {}, { interval: 100, timeout: 10_000 });
+    // $ExpectType Promise<boolean>
+    t.waitFor(() => true);
+    // $ExpectType Promise<boolean>
+    t.waitFor(async () => true);
+});
+
 // @ts-expect-error Should not be able to instantiate a TestContext
 const invalidTestContext = new TestContext();
 
@@ -1026,8 +1038,32 @@ test("planning with streams", (t: TestContext, done) => {
     });
 });
 
+// Test custom assertion functions.
+{
+    test.assert.register("isOdd", (n: number) => {
+        assert.strictEqual(n % 2, 1);
+    });
+    test("invokes a custom assertion as part of the test plan", (t) => {
+        t.plan(2);
+        t.assert.isOdd(5);
+        assert.throws(() => {
+            t.assert.isOdd(4);
+        });
+    });
+    test.assert.register("context", function() {
+        // $ExpectType TestContext
+        this;
+    });
+}
+
 // Test snapshot assertion.
 test(t => {
+    // $ExpectType void
+    t.assert.fileSnapshot({ value1: true, value2: false }, "./snapshots/snapshot.json");
+    // $ExpectType void
+    t.assert.fileSnapshot({ value3: "foo", value4: "bar" }, "./snapshots/snapshot.json", {
+        serializers: [value => JSON.stringify(value)],
+    });
     // $ExpectType void
     t.assert.snapshot({ value1: true, value2: false });
     // $ExpectType void
diff --git a/types/node/test/util.ts b/types/node/test/util.ts
index 3d8f8401758786..2247cfc15778a1 100644
--- a/types/node/test/util.ts
+++ b/types/node/test/util.ts
@@ -458,7 +458,8 @@ const errorMap: Map<number, [string, string]> = util.getSystemErrorMap();
         console.log(`CallSite ${index + 1}:`);
         console.log(`Function Name: ${callSite.functionName}`);
         console.log(`Script Name: ${callSite.scriptName}`);
+        console.log(`Script ID: ${callSite.scriptId}`);
         console.log(`Line Number: ${callSite.lineNumber}`);
-        console.log(`Column Number: ${callSite.column}`);
+        console.log(`Column Number: ${callSite.columnNumber}`);
     });
 }
diff --git a/types/node/util.d.ts b/types/node/util.d.ts
index f618378fb257fe..d4da341f553c44 100644
--- a/types/node/util.d.ts
+++ b/types/node/util.d.ts
@@ -118,6 +118,12 @@ declare module "util" {
          * function for this call site.
          */
         scriptName: string;
+        /**
+         * Returns the unique id of the script, as in Chrome DevTools protocol
+         * [`Runtime.ScriptId`](https://chromedevtools.github.io/devtools-protocol/1-3/Runtime/#type-ScriptId).
+         * @since v22.14.0
+         */
+        scriptId: string;
         /**
          * Returns the number, 1-based, of the line for the associate function call.
          */
@@ -125,7 +131,7 @@ declare module "util" {
         /**
          * Returns the 1-based column offset on the line for the associated function call.
          */
-        column: number;
+        columnNumber: number;
     }
     /**
      * The `util.format()` method returns a formatted string using the first argument
@@ -1572,9 +1578,10 @@ declare module "util" {
          */
         short?: string | undefined;
         /**
-         * The default option value when it is not set by args.
-         * It must be of the same type as the the `type` property.
-         * When `multiple` is `true`, it must be an array.
+         * The default value to
+         * be used if (and only if) the option does not appear in the arguments to be
+         * parsed. It must be of the same type as the `type` property. When `multiple`
+         * is `true`, it must be an array.
          * @since v18.11.0
          */
         default?: string | boolean | string[] | boolean[] | undefined;
diff --git a/types/node/worker_threads.d.ts b/types/node/worker_threads.d.ts
index a1f75be0b3dff1..ee370b440e95ff 100644
--- a/types/node/worker_threads.d.ts
+++ b/types/node/worker_threads.d.ts
@@ -60,6 +60,7 @@ declare module "worker_threads" {
     import { Readable, Writable } from "node:stream";
     import { URL } from "node:url";
     import { X509Certificate } from "node:crypto";
+    const isInternalThread: boolean;
     const isMainThread: boolean;
     const parentPort: null | MessagePort;
     const resourceLimits: ResourceLimits;


Reviews:
user: login: diavrank
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-02-20T21:20:03Z
user: login: jakebailey
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-01T00:51:57Z
user: login: Renegade334
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-01T05:18:56Z
user: login: jakebailey
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-01T05:31:21Z
user: login: jakebailey
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-02T17:35:56Z
user: login: jakebailey
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-02T17:36:18Z
user: login: jasonslagter
body: Thanks
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-10T02:45:19Z
user: login: jasonslagter
body: Thanks 
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-10T02:46:19Z

Review comments:
diff_hunk: @@ -4261,7 +4261,7 @@ declare module "fs" {
      */
     export function cpSync(source: string | URL, destination: string | URL, opts?: CopySyncOptions): void;
 
-    interface GlobOptionsBase {
+    export interface GlobOptions<T extends Dirent | string = Dirent | string> {
path: types/node/fs.d.ts
user: login: jakebailey
body: Why do the type parameter instead of the old way with the duplicated def?
created_at: 2025-04-01T00:51:56Z
author_association: MEMBER
diff_hunk: @@ -4261,7 +4261,7 @@ declare module "fs" {
      */
     export function cpSync(source: string | URL, destination: string | URL, opts?: CopySyncOptions): void;
 
-    interface GlobOptionsBase {
+    export interface GlobOptions<T extends Dirent | string = Dirent | string> {
path: types/node/fs.d.ts
user: login: Renegade334
body: Arbitrary choice – one less symbol. I have no strong feelings either way.
created_at: 2025-04-01T05:18:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -4261,7 +4261,7 @@ declare module "fs" {
      */
     export function cpSync(source: string | URL, destination: string | URL, opts?: CopySyncOptions): void;
 
-    interface GlobOptionsBase {
+    export interface GlobOptions<T extends Dirent | string = Dirent | string> {
path: types/node/fs.d.ts
user: login: jakebailey
body: When it comes to type parameters, I'm wary of adding them just because they can never be removed as someone could instantiate this type and then we're stuck with it. The previous method seemed fine enough if it still works (but if it doesn't that's another story).
created_at: 2025-04-01T05:31:21Z
author_association: MEMBER
diff_hunk: @@ -4261,7 +4261,7 @@ declare module "fs" {
      */
     export function cpSync(source: string | URL, destination: string | URL, opts?: CopySyncOptions): void;
 
-    interface GlobOptionsBase {
+    export interface GlobOptions<T extends Dirent | string = Dirent | string> {
path: types/node/fs.d.ts
user: login: jakebailey
body: I guess an unexported interface works too.
created_at: 2025-04-02T17:35:56Z
author_association: MEMBER

PR comments:
user: login: typescript-bot
created_at: 2025-02-19T07:08:14Z
body: @Renegade334 Thank you for submitting this PR!

***This is a live comment that I will keep updated.***

## 1 package in this PR

* `node` — [on npm](https://www.npmjs.com/package/node), [on unpkg](https://unpkg.com/browse/node@latest/)

## Code Reviews

Because this is a widely-used package, a DT maintainer will need to review it before it can be merged.

You can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=71922&install-plugin=playground-dt-review).

## Status

 * ✅ No merge conflicts
 * ✅ Continuous integration tests have passed
 * ✅ Most recent commit is approved by a DT maintainer

All of the items on the list are green. **To merge, you need to post a comment including the string "Ready to merge"** to bring in your changes.

----------------------
<details><summary>Diagnostic Information: What the bot saw about this PR</summary>

```json
{
  "type": "info",
  "now": "-",
  "pr_number": 71922,
  "author": "Renegade334",
  "headCommitOid": "78687dcbd8941af90542dc783e6f8ac633817152",
  "mergeBaseOid": "0b32fa9afac119291faf6ca0dc1ccdcb1b120a6e",
  "lastPushDate": "2025-02-13T01:16:06.000Z",
  "lastActivityDate": "2025-04-02T18:22:29.000Z",
  "mergeOfferDate": "2025-04-02T17:36:57.000Z",
  "mergeRequestDate": "2025-04-02T18:22:29.000Z",
  "mergeRequestUser": "Renegade334",
  "hasMergeConflict": false,
  "isFirstContribution": false,
  "tooManyFiles": false,
  "hugeChange": false,
  "popularityLevel": "Critical",
  "pkgInfo": [
    {
      "name": "node",
      "kind": "edit",
      "files": [
        {
          "path": "types/node/fs.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/module.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/package.json",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/node/process.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/sqlite.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/test.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/test/fs.ts",
          "kind": "test"
        },
        {
          "path": "types/node/test/module.ts",
          "kind": "test"
        },
        {
          "path": "types/node/test/process.ts",
          "kind": "test"
        },
        {
          "path": "types/node/test/sqlite.ts",
          "kind": "test"
        },
        {
          "path": "types/node/test/test.ts",
          "kind": "test"
        },
        {
          "path": "types/node/test/util.ts",
          "kind": "test"
        },
        {
          "path": "types/node/util.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/worker_threads.d.ts",
          "kind": "definition"
        }
      ],
      "owners": [
        "Microsoft",
        "jkomyno",
        "alvis",
        "r3nya",
        "btoueg",
        "smac89",
        "touffy",
        "DeividasBakanas",
        "eyqs",
        "Hannes-Magnusson-CK",
        "hoo29",
        "kjin",
        "ajafff",
        "islishude",
        "mwiktorczyk",
        "mohsen1",
        "galkin",
        "parambirs",
        "eps1lon",
        "ThomasdenH",
        "WilcoBakker",
        "wwwy3y3",
        "samuela",
        "kuehlein",
        "bhongy",
        "chyzwar",
        "trivikr",
        "yoursunny",
        "qwelias",
        "ExE-Boss",
        "peterblazejewicz",
        "addaleax",
        "victorperin",
        "NodeJS",
        "LinusU",
        "wafuwafu13",
        "mcollina",
        "Semigradsky"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Critical"
    }
  ],
  "reviews": [
    {
      "type": "approved",
      "reviewer": "jakebailey",
      "date": "2025-04-02T17:36:18.000Z",
      "isMaintainer": true
    },
    {
      "type": "stale",
      "reviewer": "diavrank",
      "date": "2025-02-20T21:20:03.000Z",
      "abbrOid": "ceb5391"
    }
  ],
  "mainBotCommentID": 2667690112,
  "ciResult": "pass"
}
```

</details>
<!--typescript_bot_welcome-->
author_association: CONTRIBUTOR
user: login: typescript-bot
created_at: 2025-02-19T07:08:15Z
body: 🔔 @Microsoft @jkomyno @alvis @r3nya @btoueg @smac89 @touffy @DeividasBakanas @eyqs @Hannes-Magnusson-CK @hoo29 @kjin @ajafff @islishude @mwiktorczyk @mohsen1 @galkin @parambirs @eps1lon @ThomasdenH @WilcoBakker @wwwy3y3 @samuela @kuehlein @bhongy @chyzwar @trivikr @yoursunny @qwelias @ExE-Boss @peterblazejewicz @addaleax @victorperin @NodeJS @LinusU @wafuwafu13 @mcollina @Semigradsky — please [review this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/71922/files) in the next few days. Be sure to explicitly select **`Approve`** or **`Request Changes`** in the GitHub UI so I know what's going on.
<!--typescript_bot_pinging-reviewers-->
author_association: CONTRIBUTOR
user: login: typescript-bot
created_at: 2025-02-24T06:48:58Z
body: Re-ping @Microsoft, @jkomyno, @alvis, @r3nya, @btoueg, @smac89, @touffy, @DeividasBakanas, @eyqs, @Hannes-Magnusson-CK, @hoo29, @kjin, @ajafff, @islishude, @mwiktorczyk, @mohsen1, @galkin, @parambirs, @eps1lon, @ThomasdenH, @WilcoBakker, @wwwy3y3, @samuela, @kuehlein, @bhongy, @chyzwar, @trivikr, @yoursunny, @qwelias, @ExE-Boss, @peterblazejewicz, @addaleax, @victorperin, @NodeJS, @LinusU, @wafuwafu13, @mcollina, @Semigradsky:

This PR has been out for over a week, yet I haven't seen any reviews.

Could someone please give it some attention? Thanks!
<!--typescript_bot_Unreviewed:nearly:2025-02-13-->
author_association: CONTRIBUTOR
user: login: typescript-bot
created_at: 2025-03-03T06:49:22Z
body: It has been more than two weeks and this PR still has no reviews.

I'll bump it to the DT maintainer queue. Thank you for your patience, @Renegade334.

(Ping @Microsoft, @jkomyno, @alvis, @r3nya, @btoueg, @smac89, @touffy, @DeividasBakanas, @eyqs, @Hannes-Magnusson-CK, @hoo29, @kjin, @ajafff, @islishude, @mwiktorczyk, @mohsen1, @galkin, @parambirs, @eps1lon, @ThomasdenH, @WilcoBakker, @wwwy3y3, @samuela, @kuehlein, @bhongy, @chyzwar, @trivikr, @yoursunny, @qwelias, @ExE-Boss, @peterblazejewicz, @addaleax, @victorperin, @NodeJS, @LinusU, @wafuwafu13, @mcollina, @Semigradsky.)
<!--typescript_bot_Unreviewed:done-->
author_association: CONTRIBUTOR
user: login: typescript-bot
created_at: 2025-04-02T17:23:44Z
body: @jakebailey, @diavrank Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review?
<!--typescript_bot_stale-ping-ec6d20-ceb5391-->
author_association: CONTRIBUTOR
user: login: typescript-bot
created_at: 2025-04-02T17:36:57Z
body: @diavrank Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review?
<!--typescript_bot_stale-ping-84d14a-ceb5391-->
author_association: CONTRIBUTOR
user: login: Renegade334
created_at: 2025-04-02T18:22:29Z
body: Ready to merge.
author_association: CONTRIBUTOR