diff options
24 files changed, 237 insertions, 84 deletions
diff --git a/.github/workflows/bun-landing.yml b/.github/workflows/bun-landing.yml index 86a5045fc..7fba02e51 100644 --- a/.github/workflows/bun-landing.yml +++ b/.github/workflows/bun-landing.yml @@ -26,9 +26,9 @@ jobs: node-version: ${{ matrix.node }} - name: Install bun - uses: xhyrom/setup-bun@v0.1.2 + uses: xhyrom/setup-bun@v0.1.8 with: - bun-version: latest + bun-version: canary - name: Install global dependencies run: bun install diff --git a/.github/workflows/bun-types-release.yml b/.github/workflows/bun-types-release.yml index ebbe08586..ca8058967 100644 --- a/.github/workflows/bun-types-release.yml +++ b/.github/workflows/bun-types-release.yml @@ -14,9 +14,9 @@ jobs: - uses: actions/checkout@v3 - name: Install bun - uses: xhyrom/setup-bun@v0.1.6 + uses: xhyrom/setup-bun@v0.1.8 with: - bun-version: latest + bun-version: canary github-token: ${{ secrets.GITHUB_TOKEN }} - name: Install node @@ -88,9 +88,9 @@ jobs: scope: '@oven-sh' - name: Install bun - uses: xhyrom/setup-bun@v0.1.6 + uses: xhyrom/setup-bun@v0.1.8 with: - bun-version: latest + bun-version: canary github-token: ${{ secrets.GITHUB_TOKEN }} - name: Download all artifacts diff --git a/.github/workflows/bun-types-tests.yml b/.github/workflows/bun-types-tests.yml index 207ef91c8..152a89197 100644 --- a/.github/workflows/bun-types-tests.yml +++ b/.github/workflows/bun-types-tests.yml @@ -20,9 +20,9 @@ jobs: uses: actions/checkout@v2 - name: Install bun - uses: xhyrom/setup-bun@v0.1.6 + uses: xhyrom/setup-bun@v0.1.8 with: - bun-version: latest + bun-version: canary github-token: ${{ secrets.GITHUB_TOKEN }} - name: Install node diff --git a/packages/bun-types/.eslintrc.cjs b/packages/bun-types/.eslintrc.cjs index d38b920f4..6fd18dcc9 100644 --- a/packages/bun-types/.eslintrc.cjs +++ b/packages/bun-types/.eslintrc.cjs @@ -19,5 +19,6 @@ module.exports = { "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-misused-new": "off", }, }; diff --git a/packages/bun-types/bun-test.d.ts b/packages/bun-types/bun-test.d.ts index c651b0a21..0d643ea56 100644 --- a/packages/bun-types/bun-test.d.ts +++ b/packages/bun-types/bun-test.d.ts @@ -37,6 +37,7 @@ declare module "bun:test" { toBe(value: any): void; toContain(value: any): void; toEqual(value: any): void; + toStrictEqual(value: any): void; toHaveLength(value: number): void; toHaveProperty(key: string, value?: any): void; toBeTruthy(): void; diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts index 265a8ed46..804d9c861 100644 --- a/packages/bun-types/bun.d.ts +++ b/packages/bun-types/bun.d.ts @@ -1,9 +1,13 @@ -import { SignalConstants } from "os"; - interface VoidFunction { (): void; } +declare namespace Bun { + interface Env extends Dict<string> { + NODE_ENV: string; + } +} + /** * * Bun.js runtime APIs @@ -30,7 +34,7 @@ declare module "bun" { * Changes to `process.env` at runtime won't automatically be reflected in the default value. For that, you can pass `process.env` explicitly. * */ - export const env: Record<string, string>; + export const env: Bun.Env; export const origin: string; /** @@ -2981,7 +2985,4 @@ interface BufferEncodingOption { encoding?: BufferEncoding; } -// declare var Bun: typeof import("bun"); -declare namespace Bun { - export * from "bun"; -} +declare var Bun: typeof import("bun"); diff --git a/packages/bun-types/bun.lockb b/packages/bun-types/bun.lockb Binary files differindex cf33f4cab..a0b9b6b1d 100755 --- a/packages/bun-types/bun.lockb +++ b/packages/bun-types/bun.lockb diff --git a/packages/bun-types/child_process.d.ts b/packages/bun-types/child_process.d.ts index 639dcaf62..c36a7dd0d 100644 --- a/packages/bun-types/child_process.d.ts +++ b/packages/bun-types/child_process.d.ts @@ -66,14 +66,15 @@ * @see [source](https://github.com/nodejs/node/blob/v18.0.0/lib/child_process.js) */ declare module "child_process" { - import { BunSpawnOptions } from "bun"; + import { SpawnOptions } from "bun"; import { ObjectEncodingOptions } from "node:fs"; import { EventEmitter, Abortable } from "node:events"; - import * as net from "node:net"; + import { Writable, Readable, Stream, Pipe } from "node:stream"; import { URL } from "node:url"; type Serializable = string | object | number | boolean | bigint; - type SendHandle = net.Socket | net.Server; + // import * as net from "node:net"; + // type SendHandle = net.Socket | net.Server; /** * Instances of the `ChildProcess` represent spawned child processes. * @@ -84,7 +85,7 @@ declare module "child_process" { */ class ChildProcess extends EventEmitter { spawn( - options: BunSpawnOptions & { cmd: string[] }, + options: SpawnOptions.OptionsObject & { args: string[]; file?: string }, ): ChildProcessWithoutNullStreams; /** @@ -464,17 +465,17 @@ declare module "child_process" { message: Serializable, callback?: (error: Error | null) => void, ): boolean; - send( - message: Serializable, - sendHandle?: SendHandle, - callback?: (error: Error | null) => void, - ): boolean; - send( - message: Serializable, - sendHandle?: SendHandle, - options?: MessageOptions, - callback?: (error: Error | null) => void, - ): boolean; + // send( + // message: Serializable, + // sendHandle?: SendHandle, + // callback?: (error: Error | null) => void, + // ): boolean; + // send( + // message: Serializable, + // sendHandle?: SendHandle, + // options?: MessageOptions, + // callback?: (error: Error | null) => void, + // ): boolean; /** * Closes the IPC channel between parent and child, allowing the child to exit * gracefully once there are no other connections keeping it alive. After calling @@ -550,10 +551,10 @@ declare module "child_process" { event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void, ): this; - addListener( - event: "message", - listener: (message: Serializable, sendHandle: SendHandle) => void, - ): this; + // addListener( + // event: "message", + // listener: (message: Serializable, sendHandle: SendHandle) => void, + // ): this; addListener(event: "spawn", listener: () => void): this; emit(event: string | symbol, ...args: any[]): boolean; emit( @@ -568,11 +569,11 @@ declare module "child_process" { code: number | null, signal: NodeJS.Signals | null, ): boolean; - emit( - event: "message", - message: Serializable, - sendHandle: SendHandle, - ): boolean; + // emit( + // event: "message", + // message: Serializable, + // sendHandle: SendHandle, + // ): boolean; emit(event: "spawn", listener: () => void): boolean; on(event: string, listener: (...args: any[]) => void): this; on( @@ -585,10 +586,10 @@ declare module "child_process" { event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void, ): this; - on( - event: "message", - listener: (message: Serializable, sendHandle: SendHandle) => void, - ): this; + // on( + // event: "message", + // listener: (message: Serializable, sendHandle: SendHandle) => void, + // ): this; on(event: "spawn", listener: () => void): this; once(event: string, listener: (...args: any[]) => void): this; once( @@ -601,10 +602,10 @@ declare module "child_process" { event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void, ): this; - once( - event: "message", - listener: (message: Serializable, sendHandle: SendHandle) => void, - ): this; + // once( + // event: "message", + // listener: (message: Serializable, sendHandle: SendHandle) => void, + // ): this; once(event: "spawn", listener: () => void): this; prependListener(event: string, listener: (...args: any[]) => void): this; prependListener( @@ -617,10 +618,10 @@ declare module "child_process" { event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void, ): this; - prependListener( - event: "message", - listener: (message: Serializable, sendHandle: SendHandle) => void, - ): this; + // prependListener( + // event: "message", + // listener: (message: Serializable, sendHandle: SendHandle) => void, + // ): this; prependListener(event: "spawn", listener: () => void): this; prependOnceListener( event: string, @@ -636,10 +637,10 @@ declare module "child_process" { event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void, ): this; - prependOnceListener( - event: "message", - listener: (message: Serializable, sendHandle: SendHandle) => void, - ): this; + // prependOnceListener( + // event: "message", + // listener: (message: Serializable, sendHandle: SendHandle) => void, + // ): this; prependOnceListener(event: "spawn", listener: () => void): this; } // return this object when stdio option is undefined or not specified @@ -703,7 +704,7 @@ declare module "child_process" { uid?: number | undefined; gid?: number | undefined; cwd?: string | URL | undefined; - env?: NodeJS.ProcessEnv | undefined; + env?: Partial<Bun.Env> | undefined; } interface CommonOptions extends ProcessEnvOptions { /** @@ -1172,7 +1173,7 @@ declare module "child_process" { interface ExecFileOptionsWithOtherEncoding extends ExecFileOptions { encoding: BufferEncoding; } - type ExecFileException = ExecException & NodeJS.ErrnoException; + type ExecFileException = ExecException & ErrnoException; /** * The `child_process.execFile()` function is similar to {@link exec} except that it does not spawn a shell by default. Rather, the specified * executable `file` is spawned directly as a new process making it slightly more @@ -1527,7 +1528,7 @@ declare module "child_process" { options?: ForkOptions, ): ChildProcess; interface SpawnSyncOptions extends CommonSpawnOptions { - input?: string | NodeJS.ArrayBufferView | undefined; + input?: string | ArrayBufferView | undefined; maxBuffer?: number | undefined; encoding?: BufferEncoding | "buffer" | null | undefined; } @@ -1594,7 +1595,7 @@ declare module "child_process" { options?: SpawnSyncOptions, ): SpawnSyncReturns<string | Buffer>; interface CommonExecOptions extends CommonOptions { - input?: string | NodeJS.ArrayBufferView | undefined; + input?: string | ArrayBufferView | undefined; stdio?: StdioOptions | undefined; killSignal?: NodeJS.Signals | number | undefined; maxBuffer?: number | undefined; diff --git a/packages/bun-types/globals.d.ts b/packages/bun-types/globals.d.ts index be58b8e02..c93265ecb 100644 --- a/packages/bun-types/globals.d.ts +++ b/packages/bun-types/globals.d.ts @@ -65,14 +65,14 @@ type Signals = | "SIGINFO"; interface ArrayConstructor { - fromAsync( - asyncItems: AsyncIterable | Iterable | ArrayLike, + fromAsync<T>( + asyncItems: AsyncIterable<T> | Iterable<T> | ArrayLike<T>, mapfn?: (value: any, index: number) => any, thisArg?: any, - ): Array; + ): Array<T>; } -interface console { +interface Console { /** * Asynchronously read lines from standard input (fd 0) * @@ -172,7 +172,7 @@ interface console { warn(...data: any[]): void; } -declare var console: console; +declare var console: Console; declare namespace NodeJS { interface RequireResolve { @@ -184,6 +184,44 @@ declare namespace NodeJS { (id: string): any; resolve: RequireResolve; } + type Signals = + | "SIGABRT" + | "SIGALRM" + | "SIGBUS" + | "SIGCHLD" + | "SIGCONT" + | "SIGFPE" + | "SIGHUP" + | "SIGILL" + | "SIGINT" + | "SIGIO" + | "SIGIOT" + | "SIGKILL" + | "SIGPIPE" + | "SIGPOLL" + | "SIGPROF" + | "SIGPWR" + | "SIGQUIT" + | "SIGSEGV" + | "SIGSTKFLT" + | "SIGSTOP" + | "SIGSYS" + | "SIGTERM" + | "SIGTRAP" + | "SIGTSTP" + | "SIGTTIN" + | "SIGTTOU" + | "SIGUNUSED" + | "SIGURG" + | "SIGUSR1" + | "SIGUSR2" + | "SIGVTALRM" + | "SIGWINCH" + | "SIGXCPU" + | "SIGXFSZ" + | "SIGBREAK" + | "SIGLOST" + | "SIGINFO"; } interface ImportMeta { @@ -297,9 +335,7 @@ interface Process { platform: Platform; argv: string[]; // execArgv: string[]; - env: Record<string, string> & { - NODE_ENV: string; - }; + env: Bun.Env; /** Whether you are using Bun */ isBun: 1; // FIXME: this should actually return a boolean @@ -315,6 +351,9 @@ interface Process { getuid(): number; setuid(id: number | string): void; dlopen(module: { exports: any }, filename: string, flags?: number): void; + stdin: import("stream").Duplex; + stdout: import("stream").Writable; + stderr: import("stream").Writable; } declare var process: Process; @@ -2637,3 +2676,30 @@ interface CallSite { */ isConstructor(): boolean; } + +interface ArrayBufferConstructor { + new (params: { byteLength: number; maxByteLength?: number }): ArrayBuffer; +} +interface ArrayBuffer { + /** + * Read-only. The length of the ArrayBuffer (in bytes). + */ + readonly byteLength: number; + /** + * Resize an ArrayBuffer in-place. + */ + resize(byteLength: number): ArrayBuffer; + + /** + * Returns a section of an ArrayBuffer. + */ + slice(begin: number, end?: number): ArrayBuffer; + readonly [Symbol.toStringTag]: string; +} + +interface SharedArrayBuffer { + /** + * Grow the SharedArrayBuffer in-place. + */ + grow(size: number): SharedArrayBuffer; +} diff --git a/packages/bun-types/package.json b/packages/bun-types/package.json index 85efdcd56..b8c8a2e2a 100644 --- a/packages/bun-types/package.json +++ b/packages/bun-types/package.json @@ -4,13 +4,16 @@ "private": true, "repository": "https://github.com/oven-sh/bun-types", "scripts": { - "build": "rm -rf ./dist && bun scripts/bundle.ts ./dist && bun run fmt", + "build": "rm -rf ./dist && bun run bundle && bun run fmt", + "bundle": "bun scripts/bundle.ts ./dist", "docs": "bun run build && typedoc", - "test": "tsd" + "test": "tsd", + "fmt": "prettier --write './**/*.{ts,tsx,js,jsx}'" }, "devDependencies": { "tsd": "^0.22.0", - "typedoc": "^0.23.9" + "typedoc": "^0.23.9", + "prettier": "^2.4.1" }, "tsd": { "directory": "tests" diff --git a/packages/bun-types/tests/array-buffer.test-d.ts b/packages/bun-types/tests/array-buffer.test-d.ts new file mode 100644 index 000000000..7d28e2097 --- /dev/null +++ b/packages/bun-types/tests/array-buffer.test-d.ts @@ -0,0 +1,12 @@ +const buffer = new ArrayBuffer({ + byteLength: 1024, + maxByteLength: 2048, +}); + +console.log(buffer.byteLength); // 1024 +buffer.resize(2048); +console.log(buffer.byteLength); // 2048 +TextDecoder; + +const buf = new SharedArrayBuffer(1024); +buf.grow(2048); diff --git a/packages/bun-types/tests/array.test-d.ts b/packages/bun-types/tests/array.test-d.ts new file mode 100644 index 000000000..ac04c6b34 --- /dev/null +++ b/packages/bun-types/tests/array.test-d.ts @@ -0,0 +1,19 @@ +import { expectType } from "tsd"; + +async function* listReleases() { + for (let page = 1; ; page++) { + const response = await fetch( + `https://api.github.com/repos/oven-sh/bun/releases?page=${page}`, + ); + const releases: { data: string }[] = await response.json(); + if (!releases.length) { + break; + } + for (const release of releases) { + yield release; + } + } +} + +const releases = await Array.fromAsync(listReleases()); +expectType<{ data: string }[]>(releases); diff --git a/packages/bun-types/tests/console.test-d.ts b/packages/bun-types/tests/console.test-d.ts new file mode 100644 index 000000000..5a4d6efa8 --- /dev/null +++ b/packages/bun-types/tests/console.test-d.ts @@ -0,0 +1,5 @@ +for await (const line of console) { + console.log("Received:", line); +} + +export {}; diff --git a/packages/bun-types/tests/env.test-d.ts b/packages/bun-types/tests/env.test-d.ts new file mode 100644 index 000000000..805aa4126 --- /dev/null +++ b/packages/bun-types/tests/env.test-d.ts @@ -0,0 +1,13 @@ +import { expectType } from "tsd"; + +declare global { + namespace Bun { + interface Env { + WHATEVER: "WHATEVER"; + } + } +} + +expectType<"WHATEVER">(process.env.WHATEVER); + +export {}; diff --git a/packages/bun-types/tests/index.d.ts b/packages/bun-types/tests/exports.d.ts index 45e52ec7d..45e52ec7d 100644 --- a/packages/bun-types/tests/index.d.ts +++ b/packages/bun-types/tests/exports.d.ts diff --git a/packages/bun-types/tests/fsrouter.test-d.ts b/packages/bun-types/tests/fsrouter.test-d.ts new file mode 100644 index 000000000..05556f60a --- /dev/null +++ b/packages/bun-types/tests/fsrouter.test-d.ts @@ -0,0 +1,13 @@ +import { FileSystemRouter } from "bun"; +import { expectType } from "tsd"; + +const router = new FileSystemRouter({ + dir: import.meta.dir + "/pages", + style: "nextjs", +}); + +const match = router.match("/"); +expectType<string>(match?.name!); +expectType<string>(match?.pathname!); +expectType<Record<string, string>>(match?.query!); +expectType<Record<string, string>>(match?.params!); diff --git a/packages/bun-types/tests/index.test-d.ts b/packages/bun-types/tests/globals.test-d.ts index 7a2390638..5faf9d834 100644 --- a/packages/bun-types/tests/index.test-d.ts +++ b/packages/bun-types/tests/globals.test-d.ts @@ -1,11 +1,6 @@ import { ZlibCompressionOptions } from "bun"; import { expectAssignable, expectType } from "tsd"; -import Bun, { fs, fsPromises } from "."; -// import Bun from "bun"; -// import fs from "fs"; -// import fsPromises from "fs/promises"; - -// Testing ../bun.d.ts +import Bun, { fs, fsPromises } from "./exports"; // FileBlob expectType<ReadableStream<Uint8Array>>(Bun.file("index.test-d.ts").stream()); diff --git a/packages/bun-types/tests/headers.test-d.ts b/packages/bun-types/tests/headers.test-d.ts new file mode 100644 index 000000000..711384ddc --- /dev/null +++ b/packages/bun-types/tests/headers.test-d.ts @@ -0,0 +1,6 @@ +const headers = new Headers(); +headers.append("Set-Cookie", "a=1"); +headers.append("Set-Cookie", "b=1; Secure"); + +console.log(headers.getAll("Set-Cookie")); // ["a=1", "b=1; Secure"] +console.log(headers.toJSON()); // { "set-cookie": "a=1, b=1; Secure" } diff --git a/packages/bun-types/tests/stdio.test-d.ts b/packages/bun-types/tests/stdio.test-d.ts new file mode 100644 index 000000000..d42f3b718 --- /dev/null +++ b/packages/bun-types/tests/stdio.test-d.ts @@ -0,0 +1,3 @@ +process.stdin; +process.stdout; +process.stderr; diff --git a/packages/bun-types/tests/tcp.test-d.ts b/packages/bun-types/tests/tcp.test-d.ts index 9cfcbebda..2d5f66f52 100644 --- a/packages/bun-types/tests/tcp.test-d.ts +++ b/packages/bun-types/tests/tcp.test-d.ts @@ -116,7 +116,7 @@ const listener = Bun.listen({ unix: "asdf", }); -listener.data.arg = "asdf"; +listener.data!.arg = "asdf"; // @ts-expect-error arg is string listener.data.arg = 234; diff --git a/packages/bun-types/tests/test.test-d.ts b/packages/bun-types/tests/test.test-d.ts new file mode 100644 index 000000000..653a41c4d --- /dev/null +++ b/packages/bun-types/tests/test.test-d.ts @@ -0,0 +1,13 @@ +import { test, expect } from "bun:test"; + +test("new expect() matchers", () => { + expect(1).not.toBe(2); + expect({ a: 1 }).toEqual({ a: 1, b: undefined }); + expect({ a: 1 }).toStrictEqual({ a: 1 }); + expect(new Set()).toHaveProperty("size"); + expect([]).toHaveLength(0); + expect(["bun"]).toContain("bun"); + expect(true).toBeTruthy(); + expect(Math.PI).toBeGreaterThan(3.14); + expect(null).toBeNull(); +}); diff --git a/packages/bun-types/tsconfig.json b/packages/bun-types/tsconfig.json index f88d23096..709470196 100644 --- a/packages/bun-types/tsconfig.json +++ b/packages/bun-types/tsconfig.json @@ -3,13 +3,13 @@ "lib": [ "ESNext" ], - "skipLibCheck": true, + "skipLibCheck": false, "strict": true, "target": "esnext", "module": "esnext", "moduleResolution": "node", "allowSyntheticDefaultImports": true, - "disableSolutionSearching": true + "disableSolutionSearching": true, }, "exclude": [ "dist", diff --git a/test/bun.js/child_process.test.ts b/test/bun.js/child_process.test.ts index bdb197180..6fe5bf996 100644 --- a/test/bun.js/child_process.test.ts +++ b/test/bun.js/child_process.test.ts @@ -36,13 +36,13 @@ const it: typeof it_ = (label, fn) => { } else if (fn.constructor.name === "AsyncFunction") { return it_(label, async () => { gcTick(); - await fn(); + await fn(() => {}); gcTick(); }); } else { return it_(label, () => { gcTick(); - fn(); + fn(() => {}); gcTick(); }); } @@ -204,7 +204,7 @@ describe("spawn()", () => { it("should allow explicit setting of argv0", async () => { var resolve; - const promise = new Promise((resolve1) => { + const promise = new Promise<string>((resolve1) => { resolve = resolve1; }); process.env.NO_COLOR = "1"; diff --git a/tsconfig.json b/tsconfig.json index 38b67ef1d..97bf40258 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,11 +4,12 @@ "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "noEmit": true, - "skipLibCheck": true, + // "skipLibCheck": true, "allowJs": true }, "include": [ - "." + ".", + "**/*.d.ts" ], "exclude": [ "src/test", |