,
+ ]
+ ? Promise
+ : T extends [
+ ...unknown[],
+ (...args: any[]) => Promise,
+ { signal?: AbortSignal; end?: boolean },
+ ]
+ ? Promise
+ : Promise;
+ namespace promises {
+ function pipeline(...streams: T): PipelinePromise;
+ function finished(
+ stream: unknown,
+ options?: FinishedOptions & { cleanup?: boolean },
+ ): Promise;
+ }
+ class Stream extends EventEmitter {}
+
+ export {
+ Readable,
+ Writable,
+ Duplex,
+ Transform,
+ PassThrough,
+ Stream,
+ addAbortSignal,
+ pipeline,
+ compose,
+ finished,
+ getDefaultHighWaterMark,
+ promises,
+ };
+ export type {
+ ReadableOptions,
+ WritableOptions,
+ DuplexOptions,
+ TransformOptions,
+ FinishedOptions,
+ PipelinePromise,
+ };
+}
+
+declare module "node:stream" {
+ import stream = require("stream");
+ export = stream;
+}
diff --git a/packages/compiler/ambient/node-fallback/string_decoder.d.ts b/packages/compiler/ambient/node-fallback/string_decoder.d.ts
new file mode 100644
index 000000000..617a7871c
--- /dev/null
+++ b/packages/compiler/ambient/node-fallback/string_decoder.d.ts
@@ -0,0 +1,20 @@
+/* node:string_decoder — StringDecoder over Node's whole encoding set:
+ * write() decodes complete sequences and buffers a trailing partial one
+ * across chunk boundaries (utf8's truncated sequence, base64's mod-3
+ * remainder, utf16le's odd byte / trailing lead surrogate; latin1, ascii
+ * and hex are stateless); end() flushes the buffered partial. `encoding`
+ * answers the normalized name. Node's exact algorithms (SEMANTICS.md);
+ * the encoding must be a literal, and end(buffer) fences — write the
+ * buffer, then end(). */
+declare module "string_decoder" {
+ export class StringDecoder {
+ constructor(encoding?: BufferEncoding);
+ readonly encoding: string;
+ write(buffer: Uint8Array): string;
+ end(buffer?: Uint8Array): string;
+ }
+}
+
+declare module "node:string_decoder" {
+ export * from "string_decoder";
+}
diff --git a/packages/compiler/ambient/node-fallback/test.d.ts b/packages/compiler/ambient/node-fallback/test.d.ts
new file mode 100644
index 000000000..2ca1c0fe7
--- /dev/null
+++ b/packages/compiler/ambient/node-fallback/test.d.ts
@@ -0,0 +1,236 @@
+///
+
+/* node:assert — the static assertion surface. The module object IS a
+ * callable function (`assert(x)` is `assert.ok(x)`), so the declaration
+ * is the callable-namespace `export =` shape and BOTH `import assert
+ * from "node:assert"` and `const assert = require("assert")` bind the
+ * callable; named imports take the members. Failures throw
+ * AssertionError (name "AssertionError", code "ERR_ASSERTION" — catch and
+ * read .name/.message/.code). strictEqual/deepStrictEqual compare with
+ * Object.is over scalars; deepStrictEqual compares composites
+ * structurally per their static types. The messages here are plain
+ * strings (Node accepts Errors — that form fences per site), and the
+ * shallow legacy pair (equal/notEqual) follows Node's == coercions for
+ * primitive and primitive-union operands, including Node v24's NaN
+ * exception. deepEqual/notDeepEqual remain declared-but-fenced;
+ * assert/strict's loose names alias the strict forms and lower. */
+/* node:test — the in-process test runner (prefix-only in Node too:
+ * require("test") is MODULE_NOT_FOUND). test/it register tests (sync and
+ * async bodies, skip/todo/only options and method twins), describe/suite
+ * group them (bodies run at registration, Node's collection phase),
+ * before/after/beforeEach/afterEach hook the enclosing suite, and the
+ * TestContext argument carries subtests (t.test), t.skip/t.todo,
+ * t.diagnostic, and t.assert. mock/run/snapshot are DECLARED so real
+ * suites typecheck but fence at their use sites (no lowering). */
+declare module "node:test" {
+ type TestFn = (t: TestContext) => void | Promise;
+ type SuiteFn = (s: SuiteContext) => void;
+ type HookFn = (c: TestContext | SuiteContext) => void | Promise;
+ /* The describe/suite callback's context, and the before/after hook
+ * context of a suite. */
+ interface SuiteContext {
+ readonly name: string;
+ readonly fullName: string;
+ readonly filePath: string | undefined;
+ readonly attempt: number;
+ readonly passed: boolean;
+ diagnostic(message: string): void;
+ }
+ interface TestOptions {
+ skip?: boolean | string;
+ todo?: boolean | string;
+ only?: boolean;
+ concurrency?: number | boolean;
+ timeout?: number;
+ plan?: number;
+ }
+ interface TestContext {
+ readonly name: string;
+ readonly fullName: string;
+ readonly filePath: string | undefined;
+ readonly attempt: number;
+ readonly passed: boolean;
+ readonly workerId: number | undefined;
+ readonly tags: readonly string[];
+ readonly assert: TestContextAssert;
+ readonly mock: MockTracker;
+ test(name?: string, fn?: TestFn): Promise;
+ test(name?: string, options?: TestOptions, fn?: TestFn): Promise;
+ test(options?: TestOptions, fn?: TestFn): Promise;
+ test(fn?: TestFn): Promise;
+ skip(message?: string): void;
+ todo(message?: string): void;
+ diagnostic(message: string): void;
+ plan(count: number): void;
+ after(fn: HookFn): void;
+ before(fn: HookFn): void;
+ beforeEach(fn: HookFn): void;
+ afterEach(fn: HookFn): void;
+ }
+ interface AssertSnapshotOptions {
+ readonly serializers?: ReadonlyArray<(value: any) => any> | undefined;
+ }
+ interface TestContextAssert {
+ snapshot(value: any, options?: AssertSnapshotOptions): void;
+ fileSnapshot(value: any, path: string, options?: AssertSnapshotOptions): void;
+ ok(value: unknown, message?: string): void;
+ strictEqual(actual: unknown, expected: unknown, message?: string): void;
+ notStrictEqual(actual: unknown, expected: unknown, message?: string): void;
+ deepStrictEqual(actual: unknown, expected: unknown, message?: string): void;
+ notDeepStrictEqual(actual: unknown, expected: unknown, message?: string): void;
+ equal(actual: unknown, expected: unknown, message?: string): void;
+ notEqual(actual: unknown, expected: unknown, message?: string): void;
+ deepEqual(actual: unknown, expected: unknown, message?: string): void;
+ notDeepEqual(actual: unknown, expected: unknown, message?: string): void;
+ fail(message?: string): never;
+ throws(fn: () => unknown, expected?: unknown, message?: string): void;
+ match(value: string, regExp: RegExp, message?: string): void;
+ doesNotMatch(value: string, regExp: RegExp, message?: string): void;
+ }
+ /* The name, options and function are each optional, as in Node: a test
+ * without a name takes the function's name, or "". */
+ function test(name?: string, fn?: TestFn): Promise;
+ function test(name?: string, options?: TestOptions, fn?: TestFn): Promise;
+ function test(options?: TestOptions, fn?: TestFn): Promise;
+ function test(fn?: TestFn): Promise;
+ namespace test {
+ function skip(name?: string, fn?: TestFn): Promise;
+ function skip(name?: string, options?: TestOptions, fn?: TestFn): Promise;
+ function skip(options?: TestOptions, fn?: TestFn): Promise