Fix some issues in Bun types (#17424)

Co-authored-by: Michael H <git@riskymh.dev>
This commit is contained in:
Alistair Smith
2025-03-04 00:04:12 +00:00
committed by GitHub
parent 70dbf582a6
commit 9141337c7d
25 changed files with 860 additions and 516 deletions

View File

@@ -141,9 +141,11 @@
"packages/bun-uws/fuzzing": true,
},
"files.associations": {
"*.css": "tailwindcss",
"*.idl": "cpp",
"*.mdc": "markdown",
"array": "cpp",
"ios": "cpp",
},
"C_Cpp.files.exclude": {
"**/.vscode": true,

View File

@@ -151,13 +151,13 @@
"@qiwi/npm-registry-client": ["@qiwi/npm-registry-client@8.9.1", "", { "dependencies": { "concat-stream": "^2.0.0", "graceful-fs": "^4.2.4", "normalize-package-data": "~1.0.1 || ^2.0.0 || ^3.0.0", "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^8.0.0", "once": "^1.4.0", "request": "^2.88.2", "retry": "^0.12.0", "safe-buffer": "^5.2.1", "semver": "2 >=2.2.1 || 3.x || 4 || 5 || 7", "slide": "^1.1.6", "ssri": "^8.0.0" }, "optionalDependencies": { "npmlog": "2 || ^3.1.0 || ^4.0.0" } }, "sha512-rZF+mG+NfijR0SHphhTLHRr4aM4gtfdwoAMY6we2VGQam8vkN1cxGG1Lg/Llrj8Dd0Mu6VjdFQRyMMRZxtZR2A=="],
"@types/bun": ["@types/bun@1.1.17", "", { "dependencies": { "bun-types": "1.1.44" } }, "sha512-zZt0Kao/8hAwNOXh4bmt8nKbMEd4QD8n7PeTGF+NZTVY5ouXhU/TX7jUj4He1p7mgY+WdplnU1B6MB1j17vdzg=="],
"@types/bun": ["@types/bun@1.2.2", "", { "dependencies": { "bun-types": "1.2.2" } }, "sha512-tr74gdku+AEDN5ergNiBnplr7hpDp3V1h7fqI2GcR/rsUaM39jpSeKH0TFibRvU0KwniRx5POgaYnaXbk0hU+w=="],
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
"@types/node": ["@types/node@22.10.7", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg=="],
"@types/node": ["@types/node@22.13.5", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg=="],
"@types/prop-types": ["@types/prop-types@15.7.12", "", {}, "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="],

View File

@@ -204,7 +204,7 @@ To customize the TLS validation, use the `checkServerIdentity` option in `tls`
await fetch("https://example.com", {
tls: {
checkServerIdentity: (hostname, peerCertificate) => {
// Return an error if the certificate is invalid
// Return an Error if the certificate is invalid
},
},
});

View File

@@ -23,3 +23,9 @@ declare module "*.html" {
var contents: any;
export = contents;
}
declare module "*.svg" {
// Bun 1.2.3 added support for frontend dev server
var contents: `${string}.svg`;
export = contents;
}

View File

@@ -1,3 +1,74 @@
declare class _ShellError extends Error implements ShellOutput {
readonly stdout: Buffer;
readonly stderr: Buffer;
readonly exitCode: number;
/**
* Read from stdout as a string
*
* @param encoding - The encoding to use when decoding the output
* @returns Stdout as a string with the given encoding
* @example
*
* ## Read as UTF-8 string
*
* ```ts
* const output = await $`echo hello`;
* console.log(output.text()); // "hello\n"
* ```
*
* ## Read as base64 string
*
* ```ts
* const output = await $`echo ${atob("hello")}`;
* console.log(output.text("base64")); // "hello\n"
* ```
*
*/
text(encoding?: BufferEncoding): string;
/**
* Read from stdout as a JSON object
*
* @returns Stdout as a JSON object
* @example
*
* ```ts
* const output = await $`echo '{"hello": 123}'`;
* console.log(output.json()); // { hello: 123 }
* ```
*
*/
json(): any;
/**
* Read from stdout as an ArrayBuffer
*
* @returns Stdout as an ArrayBuffer
* @example
*
* ```ts
* const output = await $`echo hello`;
* console.log(output.arrayBuffer()); // ArrayBuffer { byteLength: 6 }
* ```
*/
arrayBuffer(): ArrayBuffer;
/**
* Read from stdout as a Blob
*
* @returns Stdout as a blob
* @example
* ```ts
* const output = await $`echo hello`;
* console.log(output.blob()); // Blob { size: 6, type: "" }
* ```
*/
blob(): Blob;
bytes(): Uint8Array;
}
/**
* Bun.js runtime APIs
*
@@ -16,9 +87,13 @@
declare module "bun" {
import type { FFIFunctionCallableSymbol } from "bun:ffi";
import type { Encoding as CryptoEncoding } from "crypto";
import type { CipherNameAndProtocol, EphemeralKeyInfo, PeerCertificate } from "tls";
import type { Stats } from "node:fs";
import type { X509Certificate } from "node:crypto";
import type { Stats } from "node:fs";
import type { CipherNameAndProtocol, EphemeralKeyInfo, PeerCertificate } from "tls";
type DistributedOmit<T, K extends keyof T> = T extends T ? Omit<T, K> : never;
type PathLike = string | NodeJS.TypedArray | ArrayBufferLike | URL;
interface Env {
NODE_ENV?: string;
/**
@@ -110,77 +185,6 @@ declare module "bun" {
| SpawnOptions.Writable
| ReadableStream;
class ShellError extends Error implements ShellOutput {
readonly stdout: Buffer;
readonly stderr: Buffer;
readonly exitCode: number;
/**
* Read from stdout as a string
*
* @param encoding - The encoding to use when decoding the output
* @returns Stdout as a string with the given encoding
* @example
*
* ## Read as UTF-8 string
*
* ```ts
* const output = await $`echo hello`;
* console.log(output.text()); // "hello\n"
* ```
*
* ## Read as base64 string
*
* ```ts
* const output = await $`echo ${atob("hello")}`;
* console.log(output.text("base64")); // "hello\n"
* ```
*
*/
text(encoding?: BufferEncoding): string;
/**
* Read from stdout as a JSON object
*
* @returns Stdout as a JSON object
* @example
*
* ```ts
* const output = await $`echo '{"hello": 123}'`;
* console.log(output.json()); // { hello: 123 }
* ```
*
*/
json(): any;
/**
* Read from stdout as an ArrayBuffer
*
* @returns Stdout as an ArrayBuffer
* @example
*
* ```ts
* const output = await $`echo hello`;
* console.log(output.arrayBuffer()); // ArrayBuffer { byteLength: 6 }
* ```
*/
arrayBuffer(): ArrayBuffer;
/**
* Read from stdout as a Blob
*
* @returns Stdout as a blob
* @example
* ```ts
* const output = await $`echo hello`;
* console.log(output.blob()); // Blob { size: 6, type: "" }
* ```
*/
blob(): Blob;
bytes(): Uint8Array;
}
class ShellPromise extends Promise<ShellOutput> {
get stdin(): WritableStream;
/**
@@ -300,9 +304,13 @@ declare module "bun" {
new (): Shell;
}
type ShellError = _ShellError;
export interface Shell {
(strings: TemplateStringsArray, ...expressions: ShellExpression[]): ShellPromise;
readonly ShellError: typeof _ShellError;
/**
* Perform bash-like brace expansion on the given pattern.
* @param pattern - Brace pattern to expand
@@ -3940,13 +3948,14 @@ declare module "bun" {
interface TLSWebSocketServeOptions<WebSocketDataType = undefined>
extends WebSocketServeOptions<WebSocketDataType>,
TLSOptions {
TLSOptionsAsDeprecated {
unix?: never;
tls?: TLSOptions | TLSOptions[];
}
interface UnixTLSWebSocketServeOptions<WebSocketDataType = undefined>
extends UnixWebSocketServeOptions<WebSocketDataType>,
TLSOptions {
TLSOptionsAsDeprecated {
/**
* If set, the HTTP server will listen on a unix socket instead of a port.
* (Cannot be used with hostname+port)
@@ -3954,6 +3963,7 @@ declare module "bun" {
unix: string;
tls?: TLSOptions | TLSOptions[];
}
interface ErrorLike extends Error {
code?: string;
errno?: number;
@@ -4033,11 +4043,129 @@ declare module "bun" {
secureOptions?: number | undefined; // Value is a numeric bitmask of the `SSL_OP_*` options
}
interface TLSServeOptions extends ServeOptions, TLSOptions {
// Note for contributors: TLSOptionsAsDeprecated should be considered immutable
// and new TLS option keys should only be supported on the `.tls` property (which comes
// from the TLSOptions interface above).
/**
* This exists because Bun.serve() extends the TLSOptions object, but
* they're now considered deprecated. You should be passing the
* options on `.tls` instead.
*
* @example
* ```ts
* //// OLD ////
* Bun.serve({
* fetch: () => new Response("Hello World"),
* passphrase: "secret",
* });
*
* //// NEW ////
* Bun.serve({
* fetch: () => new Response("Hello World"),
* tls: {
* passphrase: "secret",
* },
* });
* ```
*/
interface TLSOptionsAsDeprecated {
/**
* Passphrase for the TLS key
*
* @deprecated Use `.tls.passphrase` instead
*/
passphrase?: string;
/**
* File path to a .pem file custom Diffie Helman parameters
*
* @deprecated Use `.tls.dhParamsFile` instead
*/
dhParamsFile?: string;
/**
* Explicitly set a server name
*
* @deprecated Use `.tls.serverName` instead
*/
serverName?: string;
/**
* This sets `OPENSSL_RELEASE_BUFFERS` to 1.
* It reduces overall performance but saves some memory.
* @default false
*
* @deprecated Use `.tls.lowMemoryMode` instead
*/
lowMemoryMode?: boolean;
/**
* If set to `false`, any certificate is accepted.
* Default is `$NODE_TLS_REJECT_UNAUTHORIZED` environment variable, or `true` if it is not set.
*
* @deprecated Use `.tls.rejectUnauthorized` instead
*/
rejectUnauthorized?: boolean;
/**
* If set to `true`, the server will request a client certificate.
*
* Default is `false`.
*
* @deprecated Use `.tls.requestCert` instead
*/
requestCert?: boolean;
/**
* Optionally override the trusted CA certificates. Default is to trust
* the well-known CAs curated by Mozilla. Mozilla's CAs are completely
* replaced when CAs are explicitly specified using this option.
*
* @deprecated Use `.tls.ca` instead
*/
ca?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
/**
* Cert chains in PEM format. One cert chain should be provided per
* private key. Each cert chain should consist of the PEM formatted
* certificate for a provided private key, followed by the PEM
* formatted intermediate certificates (if any), in order, and not
* including the root CA (the root CA must be pre-known to the peer,
* see ca). When providing multiple cert chains, they do not have to
* be in the same order as their private keys in key. If the
* intermediate certificates are not provided, the peer will not be
* able to validate the certificate, and the handshake will fail.
*
* @deprecated Use `.tls.cert` instead
*/
cert?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
/**
* Private keys in PEM format. PEM allows the option of private keys
* being encrypted. Encrypted keys will be decrypted with
* options.passphrase. Multiple keys using different algorithms can be
* provided either as an array of unencrypted key strings or buffers,
* or an array of objects in the form {pem: <string|buffer>[,
* passphrase: <string>]}. The object form can only occur in an array.
* object.passphrase is optional. Encrypted keys will be decrypted with
* object.passphrase if provided, or options.passphrase if it is not.
*
* @deprecated Use `.tls.key` instead
*/
key?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
/**
* Optionally affect the OpenSSL protocol behavior, which is not
* usually necessary. This should be used carefully if at all! Value is
* a numeric bitmask of the SSL_OP_* options from OpenSSL Options
*
* @deprecated `Use .tls.secureOptions` instead
*/
secureOptions?: number | undefined; // Value is a numeric bitmask of the `SSL_OP_*` options
}
interface TLSServeOptions extends ServeOptions, TLSOptionsAsDeprecated {
tls?: TLSOptions | TLSOptions[];
}
interface UnixTLSServeOptions extends UnixServeOptions, TLSOptions {
interface UnixTLSServeOptions extends UnixServeOptions, TLSOptionsAsDeprecated {
tls?: TLSOptions | TLSOptions[];
}
@@ -4494,18 +4622,18 @@ declare module "bun" {
*/
function serve<T, R extends { [K in keyof R]: RouterTypes.RouteValue<K & string> }>(
options: (
| (Omit<ServeOptions, "fetch"> & {
| (DistributedOmit<Serve, "fetch"> & {
routes: R;
fetch?: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
})
| (Omit<ServeOptions, "routes"> & {
| (DistributedOmit<Serve, "routes"> & {
routes?: never;
fetch: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
})
| WebSocketServeOptions<T>
) & {
/**
* @deprecated Use `routes` instead in new code. This will continue to work for awhile though.
* @deprecated Use `routes` instead in new code. This will continue to work for a while though.
*/
static?: R;
},
@@ -4918,7 +5046,7 @@ declare module "bun" {
*/
function openInEditor(path: string, options?: EditorOptions): void;
const fetch: typeof globalThis.fetch & {
var fetch: typeof globalThis.fetch & {
preconnect(url: string): void;
};
@@ -5542,7 +5670,11 @@ declare module "bun" {
onStart(callback: OnStartCallback): this;
onBeforeParse(
constraints: PluginConstraints,
callback: { napiModule: unknown; symbol: string; external?: unknown | undefined },
callback: {
napiModule: unknown;
symbol: string;
external?: unknown | undefined;
},
): this;
/**
* Register a callback to load imports with a specific import specifier

24
packages/bun-types/devserver.d.ts vendored Normal file
View File

@@ -0,0 +1,24 @@
export {};
declare global {
interface ImportMeta {
/**
* Hot module replacement
*
* https://bun.sh/docs/bundler/fullstack
*/
hot: {
/**
* import.meta.hot.data maintains state between module instances during hot replacement, enabling data transfer from previous to new versions.
*
* @example
* ```ts
* import.meta.hot.data = {
* bun: 'is cool',
* };
* ```
*/
data: any;
};
}
}

View File

@@ -1,9 +1,56 @@
type _Response = typeof globalThis extends { onmessage: any } ? {} : import("undici-types").Response;
interface Headers {
/**
* Convert {@link Headers} to a plain JavaScript object.
*
* About 10x faster than `Object.fromEntries(headers.entries())`
*
* Called when you run `JSON.stringify(headers)`
*
* Does not preserve insertion order. Well-known header names are lowercased. Other header names are left as-is.
*/
toJSON(): Record<string, string>;
/**
* Get the total number of headers
*/
readonly count: number;
/**
* Get all headers matching the name
*
* Only supports `"Set-Cookie"`. All other headers are empty arrays.
*
* @param name - The header name to get
*
* @returns An array of header values
*
* @example
* ```ts
* const headers = new Headers();
* headers.append("Set-Cookie", "foo=bar");
* headers.append("Set-Cookie", "baz=qux");
* headers.getAll("Set-Cookie"); // ["foo=bar", "baz=qux"]
* ```
*/
getAll(name: "set-cookie" | "Set-Cookie"): string[];
}
export interface Response extends _Response {}
export declare class Response {
constructor(body?: Bun.BodyInit | null | undefined, init?: Bun.ResponseInit | undefined);
var Headers: {
prototype: Headers;
new (init?: Bun.HeadersInit): Headers;
};
interface Request {
headers: Headers;
}
var Request: {
prototype: Request;
new (requestInfo: string, requestInit?: RequestInit): Request;
new (requestInfo: RequestInit & { url: string }): Request;
new (requestInfo: Request, requestInit?: RequestInit): Request;
};
var Response: {
new (body?: Bun.BodyInit | null | undefined, init?: Bun.ResponseInit | undefined): Response;
/**
* Create a new {@link Response} with a JSON body
*
@@ -27,7 +74,8 @@ export declare class Response {
* ```
* @link https://github.com/whatwg/fetch/issues/1389
*/
static json(body?: any, options?: Bun.ResponseInit | number): Response;
json(body?: any, options?: Bun.ResponseInit | number): Response;
/**
* Create a new {@link Response} that redirects to url
*
@@ -35,7 +83,7 @@ export declare class Response {
* @param status - the HTTP status code to use for the redirect
*/
// tslint:disable-next-line:unified-signatures
static redirect(url: string, status?: number): Response;
redirect(url: string, status?: number): Response;
/**
* Create a new {@link Response} that redirects to url
@@ -44,10 +92,70 @@ export declare class Response {
* @param options - options to pass to the response
*/
// tslint:disable-next-line:unified-signatures
static redirect(url: string, options?: Bun.ResponseInit): Response;
redirect(url: string, options?: Bun.ResponseInit): Response;
/**
* Create a new {@link Response} that has a network error
*/
static error(): Response;
error(): Response;
};
type _BunTLSOptions = import("bun").TLSOptions;
interface BunFetchRequestInitTLS extends _BunTLSOptions {
/**
* Custom function to check the server identity
* @param hostname - The hostname of the server
* @param cert - The certificate of the server
* @returns An error if the server is unauthorized, otherwise undefined
*/
checkServerIdentity?: NonNullable<import("node:tls").ConnectionOptions["checkServerIdentity"]>;
}
/**
* BunFetchRequestInit represents additional options that Bun supports in `fetch()` only.
*
* Bun extends the `fetch` API with some additional options, except
* this interface is not quite a `RequestInit`, because they won't work
* if passed to `new Request()`. This is why it's a separate type.
*/
interface BunFetchRequestInit extends RequestInit {
/**
* Override the default TLS options
*/
tls?: BunFetchRequestInitTLS;
}
var fetch: {
/**
* Send a HTTP(s) request
*
* @param request Request object
* @param init A structured value that contains settings for the fetch() request.
*
* @returns A promise that resolves to {@link Response} object.
*/
(request: Request, init?: BunFetchRequestInit): Promise<Response>;
/**
* Send a HTTP(s) request
*
* @param url URL string
* @param init A structured value that contains settings for the fetch() request.
*
* @returns A promise that resolves to {@link Response} object.
*/
(url: string | URL | Request, init?: BunFetchRequestInit): Promise<Response>;
(input: string | URL | globalThis.Request, init?: BunFetchRequestInit): Promise<Response>;
/**
* Start the DNS resolution, TCP connection, and TLS handshake for a request
* before the request is actually sent.
*
* This can reduce the latency of a request when you know there's some
* long-running task that will delay the request starting.
*
* This is a bun-specific API and is not part of the Fetch API specification.
*/
preconnect(url: string | URL): void;
};

View File

@@ -1,144 +1,66 @@
type _ReadableStream<T> = typeof globalThis extends {
onerror: any;
ReadableStream: infer T;
}
? T
: import("stream/web").ReadableStream<T>;
type _WritableStream<T> = typeof globalThis extends {
onerror: any;
WritableStream: infer T;
}
? T
: import("stream/web").WritableStream<T>;
export {};
type _TextEncoder = typeof globalThis extends {
onerror: any;
TextEncoder: infer T;
}
? T
: Bun.TextEncoder;
type _Event = {
/** This is not used in Node.js and is provided purely for completeness. */
readonly bubbles: boolean;
/** Alias for event.stopPropagation(). This is not used in Node.js and is provided purely for completeness. */
cancelBubble: () => void;
/** True if the event was created with the cancelable option */
readonly cancelable: boolean;
/** This is not used in Node.js and is provided purely for completeness. */
readonly composed: boolean;
/** Returns an array containing the current EventTarget as the only entry or empty if the event is not being dispatched. This is not used in Node.js and is provided purely for completeness. */
composedPath(): [EventTarget?];
/** Alias for event.target. */
readonly currentTarget: EventTarget | null;
/** Is true if cancelable is true and event.preventDefault() has been called. */
readonly defaultPrevented: boolean;
/** This is not used in Node.js and is provided purely for completeness. */
readonly eventPhase: 0 | 2;
/** The `AbortSignal` "abort" event is emitted with `isTrusted` set to `true`. The value is `false` in all other cases. */
readonly isTrusted: boolean;
/** Sets the `defaultPrevented` property to `true` if `cancelable` is `true`. */
preventDefault(): void;
/** This is not used in Node.js and is provided purely for completeness. */
returnValue: boolean;
/** Alias for event.target. */
readonly srcElement: EventTarget | null;
/** Stops the invocation of event listeners after the current one completes. */
stopImmediatePropagation(): void;
/** This is not used in Node.js and is provided purely for completeness. */
stopPropagation(): void;
/** The `EventTarget` dispatching the event */
readonly target: EventTarget | null;
/** The millisecond timestamp when the Event object was created. */
readonly timeStamp: number;
/** Returns the type of event, e.g. "click", "hashchange", or "submit". */
readonly type: string;
};
type _TextDecoder = typeof globalThis extends {
onerror: any;
TextDecoder: infer T;
}
? T
: Bun.TextDecoder;
type _Performance = typeof globalThis extends {
onerror: any;
}
? {}
: import("perf_hooks").Performance;
type _Worker = typeof globalThis extends { onerror: any; Worker: infer T } ? T : Bun.Worker;
type _Event = typeof globalThis extends { onerror: any; Event: any }
? {}
: {
/** This is not used in Node.js and is provided purely for completeness. */
readonly bubbles: boolean;
/** Alias for event.stopPropagation(). This is not used in Node.js and is provided purely for completeness. */
cancelBubble: () => void;
/** True if the event was created with the cancelable option */
readonly cancelable: boolean;
/** This is not used in Node.js and is provided purely for completeness. */
readonly composed: boolean;
/** Returns an array containing the current EventTarget as the only entry or empty if the event is not being dispatched. This is not used in Node.js and is provided purely for completeness. */
composedPath(): [EventTarget?];
/** Alias for event.target. */
readonly currentTarget: EventTarget | null;
/** Is true if cancelable is true and event.preventDefault() has been called. */
readonly defaultPrevented: boolean;
/** This is not used in Node.js and is provided purely for completeness. */
readonly eventPhase: 0 | 2;
/** The `AbortSignal` "abort" event is emitted with `isTrusted` set to `true`. The value is `false` in all other cases. */
readonly isTrusted: boolean;
/** Sets the `defaultPrevented` property to `true` if `cancelable` is `true`. */
preventDefault(): void;
/** This is not used in Node.js and is provided purely for completeness. */
returnValue: boolean;
/** Alias for event.target. */
readonly srcElement: EventTarget | null;
/** Stops the invocation of event listeners after the current one completes. */
stopImmediatePropagation(): void;
/** This is not used in Node.js and is provided purely for completeness. */
stopPropagation(): void;
/** The `EventTarget` dispatching the event */
readonly target: EventTarget | null;
/** The millisecond timestamp when the Event object was created. */
readonly timeStamp: number;
/** Returns the type of event, e.g. "click", "hashchange", or "submit". */
readonly type: string;
};
type _EventTarget = typeof globalThis extends {
onerror: any;
EventTarget: any;
}
? {}
: {
/**
* Adds a new handler for the `type` event. Any given `listener` is added only once per `type` and per `capture` option value.
*
* If the `once` option is true, the `listener` is removed after the next time a `type` event is dispatched.
*
* The `capture` option is not used by Node.js in any functional way other than tracking registered event listeners per the `EventTarget` specification.
* Specifically, the `capture` option is used as part of the key when registering a `listener`.
* Any individual `listener` may be added once with `capture = false`, and once with `capture = true`.
*/
addEventListener(
type: string,
listener: EventListener | EventListenerObject,
options?: AddEventListenerOptions | boolean,
): void;
/** Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. */
dispatchEvent(event: Event): boolean;
/** Removes the event listener in target's event listener list with the same type, callback, and options. */
removeEventListener(
type: string,
listener: EventListener | EventListenerObject,
options?: Bun.EventListenerOptions | boolean,
): void;
};
type _Crypto = typeof globalThis extends {
onerror: any;
Crypto: infer T;
}
? T
: import("crypto").webcrypto.Crypto;
type _SubtleCrypto = typeof globalThis extends {
onerror: any;
SubtleCrypto: infer T;
}
? T
: import("crypto").webcrypto.SubtleCrypto;
type _CryptoKey = typeof globalThis extends {
onerror: any;
CryptoKey: infer T;
}
? T
: import("crypto").webcrypto.CryptoKey;
type _Body = typeof globalThis extends { onerror: any }
? {}
: {
readonly body: ReadableStream | null;
readonly bodyUsed: boolean;
readonly arrayBuffer: () => Promise<ArrayBuffer>;
readonly blob: () => Promise<Blob>;
readonly formData: () => Promise<FormData>;
readonly json: () => Promise<unknown>;
readonly text: () => Promise<string>;
};
import { S3FileOptions } from "bun";
import type { TextDecoder as NodeTextDecoder, TextEncoder as NodeTextEncoder } from "util";
import type { MessagePort } from "worker_threads";
import type { WebSocket as _WebSocket } from "ws";
type _EventTarget = {
/**
* Adds a new handler for the `type` event. Any given `listener` is added only once per `type` and per `capture` option value.
*
* If the `once` option is true, the `listener` is removed after the next time a `type` event is dispatched.
*
* The `capture` option is not used by Node.js in any functional way other than tracking registered event listeners per the `EventTarget` specification.
* Specifically, the `capture` option is used as part of the key when registering a `listener`.
* Any individual `listener` may be added once with `capture = false`, and once with `capture = true`.
*/
addEventListener(
type: string,
listener: EventListener | EventListenerObject,
options?: AddEventListenerOptions | boolean,
): void;
/** Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. */
dispatchEvent(event: Event): boolean;
/** Removes the event listener in target's event listener list with the same type, callback, and options. */
removeEventListener(
type: string,
listener: EventListener | EventListenerObject,
options?: Bun.EventListenerOptions | boolean,
): void;
};
declare global {
var Bun: typeof import("bun");
@@ -149,7 +71,7 @@ declare global {
browser: boolean;
/** Whether you are using Bun */
isBun: 1; // FIXME: this should actually return a boolean
isBun: true;
/** The current git sha of Bun **/
revision: string;
reallyExit(code?: number): never;
@@ -160,7 +82,7 @@ declare global {
namespace Bun {
type ArrayBufferView = NodeJS.TypedArray | DataView;
type StringOrBuffer = string | NodeJS.TypedArray | ArrayBufferLike;
type PathLike = string | NodeJS.TypedArray | ArrayBufferLike | URL;
type PathLike = import("bun").PathLike;
type BodyInit = ReadableStream | XMLHttpRequestBodyInit | URLSearchParams;
type XMLHttpRequestBodyInit = Blob | BufferSource | string | FormData;
type ReadableStreamController<T> = ReadableStreamDefaultController<T>;
@@ -168,7 +90,7 @@ declare global {
| ReadableStreamDefaultReadValueResult<T>
| ReadableStreamDefaultReadDoneResult;
type ReadableStreamReader<T> = ReadableStreamDefaultReader<T>;
type Transferable = ArrayBuffer | MessagePort;
type Transferable = ArrayBuffer | import("worker_threads").MessagePort;
type MessageEventSource = undefined;
type Encoding = "utf-8" | "windows-1252" | "utf-16";
type UncaughtExceptionOrigin = "uncaughtException" | "unhandledRejection";
@@ -216,7 +138,8 @@ declare global {
type ResponseType = "basic" | "cors" | "default" | "error" | "opaque" | "opaqueredirect";
interface TextEncoder extends NodeTextEncoder {
type _TextEncoder = import("util").TextEncoder;
interface TextEncoder extends _TextEncoder {
new (encoding?: Bun.Encoding, options?: { fatal?: boolean; ignoreBOM?: boolean }): TextEncoder;
/**
* UTF-8 encodes the `src` string to the `dest` Uint8Array and returns an object
@@ -234,7 +157,8 @@ declare global {
encodeInto(src?: string, dest?: Bun.BufferSource): import("util").EncodeIntoResult;
}
interface TextDecoder extends NodeTextDecoder {
type _TextDecoder = import("util").TextDecoder;
interface TextDecoder extends _TextDecoder {
new (encoding?: Bun.Encoding, options?: { fatal?: boolean; ignoreBOM?: boolean }): TextDecoder;
}
@@ -282,7 +206,7 @@ declare global {
/** Returns the origin of the message, for server-sent events and cross-document messaging. */
readonly origin: string;
/** Returns the MessagePort array sent with the message, for cross-document messaging and channel messaging. */
readonly ports: readonly MessagePort[]; // ReadonlyArray<typeof import("worker_threads").MessagePort["prototype"]>;
readonly ports: readonly (typeof MessagePort)[]; // ReadonlyArray<typeof import("worker_threads").MessagePort["prototype"]>;
readonly source: Bun.MessageEventSource | null;
}
@@ -470,7 +394,6 @@ declare global {
type?: undefined;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface DirectUnderlyingSource<R = any> {
cancel?: UnderlyingSourceCancelCallback;
pull: (controller: ReadableStreamDirectController) => void | PromiseLike<void>;
@@ -642,6 +565,7 @@ declare global {
* @since v10.5.0
*/
ref(): void;
/**
* Calling `unref()` on a worker allows the thread to exit if this is the only
* active handle in the event system. If the worker is already `unref()`ed calling`unref()` again has no effect.
@@ -659,74 +583,44 @@ declare global {
}
}
interface ReadableStream<R = any> extends _ReadableStream<R> {}
var ReadableStream: typeof globalThis extends {
onerror: any;
ReadableStream: infer T;
}
? T
: {
prototype: ReadableStream;
new <R = any>(underlyingSource?: Bun.UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;
new <R = any>(
underlyingSource?: Bun.DirectUnderlyingSource<R>,
strategy?: QueuingStrategy<R>,
): ReadableStream<R>;
};
type _ReadableStream = import("stream/web").ReadableStream;
interface ReadableStream<R = any> extends _ReadableStream {}
var ReadableStream: {
prototype: ReadableStream;
new <R = any>(underlyingSource?: Bun.UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;
new <R = any>(underlyingSource?: Bun.DirectUnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;
};
interface WritableStream<W = any> extends _WritableStream<W> {}
var WritableStream: typeof globalThis extends {
onerror: any;
WritableStream: infer T;
}
? T
: {
prototype: WritableStream;
new <W = any>(underlyingSink?: Bun.UnderlyingSink<W>, strategy?: QueuingStrategy<W>): WritableStream<W>;
};
type _WritableStream = import("stream/web").WritableStream;
interface WritableStream<W = any> extends _WritableStream {}
var WritableStream: {
prototype: WritableStream;
new <W = any>(underlyingSink?: Bun.UnderlyingSink<W>, strategy?: QueuingStrategy<W>): WritableStream<W>;
};
type _Worker = import("worker_threads").Worker;
interface Worker extends _Worker {}
var Worker: typeof globalThis extends {
onerror: any;
Worker: infer T;
}
? T
: {
prototype: Worker;
new (scriptURL: string | URL, options?: Bun.WorkerOptions | undefined): Worker;
/**
* This is the cloned value of the `data` property passed to `new Worker()`
*
* This is Bun's equivalent of `workerData` in Node.js.
*/
data: any;
};
var Worker: {
prototype: Worker;
new (scriptURL: string | URL, options?: Bun.WorkerOptions | undefined): Worker;
/**
* This is the cloned value of the `data` property passed to `new Worker()`
*
* This is Bun's equivalent of `workerData` in Node.js.
*/
data: any;
};
interface WebSocket extends _WebSocket {}
var WebSocket: typeof globalThis extends {
onerror: any;
WebSocket: infer T;
}
? T
: typeof _WebSocket;
var WebSocket: typeof import("ws").WebSocket;
type _Crypto = import("crypto").webcrypto.Crypto;
interface Crypto extends _Crypto {}
var Crypto: typeof globalThis extends {
onerror: any;
Crypto: infer T;
}
? T
: {
prototype: Crypto;
new (): Crypto;
};
var Crypto: {
prototype: Crypto;
new (): Crypto;
};
var crypto: typeof globalThis extends {
onerror: any;
crypto: infer T;
}
? T
: Crypto;
var crypto: Crypto;
/**
* An implementation of the [WHATWG Encoding Standard](https://encoding.spec.whatwg.org/) `TextEncoder` API. All
@@ -737,49 +631,27 @@ declare global {
* const uint8array = encoder.encode('this is some data');
* ```
*/
interface TextEncoder extends _TextEncoder {}
var TextEncoder: typeof globalThis extends {
onerror: any;
TextEncoder: infer T;
}
? T
: typeof TextEncoder;
interface TextEncoder extends Bun.TextEncoder {}
var TextEncoder: typeof TextEncoder;
interface TextDecoder extends _TextDecoder {}
var TextDecoder: typeof globalThis extends {
onerror: any;
TextDecoder: infer T;
}
? T
: typeof TextDecoder;
interface TextDecoder extends Bun.TextDecoder {}
var TextDecoder: typeof TextDecoder;
type _Performance = import("perf_hooks").Performance;
interface Performance extends _Performance {}
var performance: typeof globalThis extends {
onerror: any;
performance: infer T;
}
? T
: Performance;
var performance: Performance;
interface Event extends _Event {}
var Event: typeof globalThis extends { onerror: any; Event: infer T }
? T
: {
prototype: Event;
new (type: string, eventInitDict?: Bun.EventInit): Event;
};
interface EventTarget extends _EventTarget {}
var EventTarget: typeof globalThis extends {
onerror: any;
EventTarget: infer T;
}
? T
: {
prototype: EventTarget;
new (): EventTarget;
};
var Event: {
prototype: Event;
new (type: string, eventInitDict?: Bun.EventInit): Event;
};
interface Body extends _Body {}
interface EventTarget extends _EventTarget {}
var EventTarget: {
prototype: EventTarget;
new (): EventTarget;
};
interface File extends Blob {
/**
@@ -793,9 +665,11 @@ declare global {
readonly lastModified: number;
readonly name: string;
}
var File: typeof globalThis extends { onerror: any; File: infer T } ? T : typeof File;
interface FetchRequestInit extends RequestInit {
var File: typeof File;
type _RequestInit = import("undici-types").RequestInit;
interface RequestInit extends _RequestInit {
/**
* Log the raw HTTP request & response to stdout. This API may be
* removed in a future version of Bun without notice.
@@ -809,18 +683,10 @@ declare global {
*/
proxy?: string;
/**
* Override the default TLS options
*/
tls?: {
rejectUnauthorized?: boolean | undefined; // Defaults to true
checkServerIdentity?: any; // TODO: change `any` to `checkServerIdentity`
};
/**
* Override the default S3 options
*/
s3?: S3FileOptions;
s3?: import("bun").S3Options;
}
/**
@@ -909,43 +775,6 @@ declare global {
new (): ShadowRealm;
};
interface Fetch {
/**
* Send a HTTP(s) request
*
* @param request Request object
* @param init A structured value that contains settings for the fetch() request.
*
* @returns A promise that resolves to {@link Response} object.
*/
(request: Request, init?: RequestInit): Promise<Response>;
/**
* Send a HTTP(s) request
*
* @param url URL string
* @param init A structured value that contains settings for the fetch() request.
*
* @returns A promise that resolves to {@link Response} object.
*/
(url: string | URL | Request, init?: FetchRequestInit): Promise<Response>;
(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
/**
* Start the DNS resolution, TCP connection, and TLS handshake for a request
* before the request is actually sent.
*
* This can reduce the latency of a request when you know there's some
* long-running task that will delay the request starting.
*
* This is a bun-specific API and is not part of the Fetch API specification.
*/
preconnect(url: string | URL): void;
}
var fetch: Fetch;
function queueMicrotask(callback: (...args: any[]) => void): void;
/**
* Log an error using the default exception handler
@@ -1048,15 +877,10 @@ declare global {
};
interface MessageEvent<T = any> extends Bun.MessageEvent<T> {}
var MessageEvent: typeof globalThis extends {
onerror: any;
MessageEvent: infer T;
}
? T
: {
prototype: MessageEvent;
new <T>(type: string, eventInitDict?: Bun.MessageEventInit<T>): MessageEvent<T>;
};
var MessageEvent: {
prototype: MessageEvent;
new <T>(type: string, eventInitDict?: Bun.MessageEventInit<T>): MessageEvent<T>;
};
interface CustomEvent<T = any> extends Event {
/** Returns any custom data event was created with. Typically used for synthetic events. */
@@ -1068,25 +892,25 @@ declare global {
new <T>(type: string, eventInitDict?: Bun.CustomEventInit<T>): CustomEvent<T>;
};
/**
* The URL interface represents an object providing static methods used for
* creating object URLs.
*/
interface URL {
new (url: string | URL, base?: string | URL): URL;
/** Not implemented yet */
createObjectURL(obj: Blob): string;
/** Not implemented yet */
revokeObjectURL(url: string): void;
// /**
// * The URL interface represents an object providing static methods used for
// * creating object URLs.
// */
// interface URL extends _URL {
// new (url: string | URL, base?: string | URL): URL;
// /** Not implemented yet */
// createObjectURL(obj: Blob): string;
// /** Not implemented yet */
// revokeObjectURL(url: string): void;
/**
* Check if `url` is a valid URL string
*
* @param url URL string to parse
* @param base URL to resolve against
*/
canParse(url: string, base?: string): boolean;
}
// /**
// * Check if `url` is a valid URL string
// *
// * @param url URL string to parse
// * @param base URL to resolve against
// */
// canParse(url: string, base?: string): boolean;
// }
interface EventListener {
(evt: Event): void;
@@ -1450,30 +1274,22 @@ declare global {
readonly DATA_CLONE_ERR: 25;
}
var DOMException: typeof globalThis extends {
onerror: any;
DOMException: infer T;
}
? T
: {
prototype: DOMException;
new (message?: string, name?: string): DOMException;
};
var DOMException: {
prototype: DOMException;
new (message?: string, name?: string): DOMException;
};
function alert(message?: string): void;
function confirm(message?: string): boolean;
function prompt(message?: string, _default?: string): string | null;
var SubtleCrypto: typeof globalThis extends {
onerror: any;
SubtleCrypto: infer T;
}
? T
: {
prototype: _SubtleCrypto;
new (): _SubtleCrypto;
};
type _SubtleCrypto = import("crypto").webcrypto.SubtleCrypto;
var SubtleCrypto: {
prototype: _SubtleCrypto;
new (): _SubtleCrypto;
};
type _CryptoKey = import("crypto").webcrypto.CryptoKey;
interface CryptoKey extends _CryptoKey {}
var CryptoKey: {
prototype: CryptoKey;
@@ -1949,64 +1765,6 @@ declare global {
*/
bytes(): Promise<Uint8Array>;
}
var Blob: typeof globalThis extends {
onerror: any;
Blob: infer T;
}
? T
: typeof Blob;
var Response: typeof globalThis extends {
onerror: any;
Response: infer T;
}
? T
: typeof import("./fetch").Response;
var Request: typeof globalThis extends {
onerror: any;
Request: infer T;
}
? T
: {
prototype: Request;
new (requestInfo: string, requestInit?: RequestInit): Request;
new (requestInfo: RequestInit & { url: string }): Request;
new (requestInfo: Request, requestInit?: RequestInit): Request;
};
interface Headers {
/**
* Convert {@link Headers} to a plain JavaScript object.
*
* About 10x faster than `Object.fromEntries(headers.entries())`
*
* Called when you run `JSON.stringify(headers)`
*
* Does not preserve insertion order. Well-known header names are lowercased. Other header names are left as-is.
*/
toJSON(): Record<string, string>;
/**
* Get the total number of headers
*/
readonly count: number;
/**
* Get all headers matching the name
*
* Only supports `"Set-Cookie"`. All other headers are empty arrays.
*
* @param name - The header name to get
*
* @returns An array of header values
*
* @example
* ```ts
* const headers = new Headers();
* headers.append("Set-Cookie", "foo=bar");
* headers.append("Set-Cookie", "baz=qux");
* headers.getAll("Set-Cookie"); // ["foo=bar", "baz=qux"]
* ```
*/
getAll(name: "set-cookie" | "Set-Cookie"): string[];
}
var Blob: typeof Blob;
}

View File

@@ -3,16 +3,16 @@
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference lib="esnext" />
/// <reference types="node" />
/// <reference types="ws" />
/// <reference types="node" />
// contributors: uncomment this to detect conflicts with lib.dom.d.ts
//// <reference lib="dom" />
// /// <reference lib="dom" />
/// <reference path="./globals.d.ts" />
/// <reference path="./bun.d.ts" />
/// <reference path="./overrides.d.ts" />
/// <reference path="./globals.d.ts" />
/// <reference path="./fetch.d.ts" />
/// <reference path="./overrides.d.ts" />
/// <reference path="./ffi.d.ts" />
/// <reference path="./test.d.ts" />
/// <reference path="./html-rewriter.d.ts" />
@@ -21,3 +21,4 @@
/// <reference path="./wasm.d.ts" />
/// <reference path="./deprecated.d.ts" />
/// <reference path="./ambient.d.ts" />
/// <reference path="./devserver.d.ts" />

View File

@@ -1,8 +1,7 @@
{
"name": "bun-types",
"license": "MIT",
"main": "",
"types": "index.d.ts",
"types": "./index.d.ts",
"description": "Type definitions and documentation for Bun, an incredibly fast JavaScript runtime",
"repository": {
"type": "git",
@@ -27,7 +26,7 @@
},
"scripts": {
"prebuild": "echo $(pwd)",
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && find ./docs -type f -name '*.md' -exec sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION#bun-v:-1.0.0}\"'/g' {} +",
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && find ./docs -type f -name '*.md' -exec sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION#bun-v}\"'/g' {} +",
"build": "bun run copy-docs && bun scripts/build.ts && bun run fmt",
"test": "tsc",
"fmt": "echo $(which biome) && biome format --write ."

View File

@@ -2,6 +2,13 @@ import { join } from "node:path";
import pkg from "../package.json";
const BUN_VERSION = (process.env.BUN_VERSION || Bun.version || process.versions.bun).replace(/^.*v/, "");
const BUN_VERSION = (
process.env.BUN_VERSION ||
Bun.version ||
process.versions.bun
).replace(/^.*v/, "");
Bun.write(join(import.meta.dir, "..", "package.json"), JSON.stringify({ version: BUN_VERSION, ...pkg }, null, 2));
Bun.write(
join(import.meta.dir, "..", "package.json"),
JSON.stringify({ version: BUN_VERSION, ...pkg }, null, 2),
);

View File

@@ -1,14 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"skipLibCheck": false,
"declaration": true,
"emitDeclarationOnly": true,
"noEmit": false,
"declarationDir": "out"
},
"files": ["ambient.d.ts"], // ambient defines .txt and .toml loaders
"include": ["**/*.ts"],
"exclude": ["dist", "node_modules"]
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"skipLibCheck": true,
"declaration": true,
"emitDeclarationOnly": true,
"noEmit": false,
"declarationDir": "out"
},
"include": ["**/*.ts"],
"exclude": ["dist", "node_modules"]
}

View File

@@ -350,10 +350,18 @@ static JSValue constructBunShell(VM& vm, JSObject* bunObject)
throwTypeError(globalObject, scope, "Internal error: BunShell constructor did not return an object"_s);
return {};
}
auto* bunShell = shell.getObject();
auto ShellError = bunShell->get(globalObject, JSC::Identifier::fromString(vm, "ShellError"_s));
if (UNLIKELY(!ShellError.isObject())) {
throwTypeError(globalObject, scope, "Internal error: BunShell.ShellError is not an object"_s);
return {};
}
bunShell->putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "braces"_s), 1, Generated::BunObject::jsBraces, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
bunShell->putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "escape"_s), 1, BunObject_callback_shellEscape, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
bunShell->putDirect(vm, JSC::Identifier::fromString(vm, "ShellError"_s), ShellError.getObject(), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0);
return bunShell;
}
@@ -684,7 +692,7 @@ JSC_DEFINE_HOST_FUNCTION(functionFileURLToPath, (JSC::JSGlobalObject * globalObj
/* Source for BunObject.lut.h
@begin bunObjectTable
$ constructBunShell ReadOnly|DontDelete|PropertyCallback
$ constructBunShell DontDelete|PropertyCallback
ArrayBufferSink BunObject_getter_wrap_ArrayBufferSink DontDelete|PropertyCallback
CryptoHasher BunObject_getter_wrap_CryptoHasher DontDelete|PropertyCallback
FFI BunObject_getter_wrap_FFI DontDelete|PropertyCallback

View File

@@ -15,4 +15,7 @@ JSC_DECLARE_HOST_FUNCTION(functionFileURLToPath);
JSC::JSValue constructBunFetchObject(VM& vm, JSObject* bunObject);
JSC::JSObject* createBunObject(VM& vm, JSObject* globalObject);
JSC::JSObject* BunShell(JSGlobalObject* globalObject);
JSC::JSValue ShellError(JSGlobalObject* globalObject);
}

View File

@@ -478,6 +478,7 @@ public:
LazyProperty<JSGlobalObject, Structure> m_JSS3FileStructure;
LazyProperty<JSGlobalObject, Structure> m_S3ErrorStructure;
JSC::LazyClassStructure m_JSStatsClassStructure;
JSC::LazyClassStructure m_JSStatsBigIntClassStructure;
JSC::LazyClassStructure m_JSDirentClassStructure;

View File

@@ -1,7 +1,7 @@
{
"compilerOptions": {
// Enable latest features
"lib": ["ESNext", "DOM"],
// Environment setup & latest features
"lib": ["esnext"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
@@ -18,6 +18,7 @@
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,

View File

@@ -357,6 +357,10 @@ export function createBunShellTemplateFunction(createShellInterpreter, createPar
value: ShellPromise,
enumerable: true,
},
ShellError: {
value: ShellError,
enumerable: true,
},
});
return BunShell;

View File

@@ -0,0 +1,66 @@
import { fileURLToPath, $ as Shell, ShellError } from "bun";
import { beforeAll, describe, expect, setDefaultTimeout, test } from "bun:test";
import { join } from "node:path";
const BUN_REPO_ROOT = fileURLToPath(import.meta.resolve("../../../"));
const BUN_TYPES_PACKAGE_ROOT = join(BUN_REPO_ROOT, "packages", "bun-types");
const FIXTURE_DIR = fileURLToPath(import.meta.resolve("./fixture"));
const TSCONFIG_SOURCE_PATH = join(BUN_REPO_ROOT, "src/cli/init/tsconfig.default.json");
const BUN_TYPES_PACKAGE_JSON_PATH = join(BUN_TYPES_PACKAGE_ROOT, "package.json");
const BUN_VERSION = (process.env.BUN_VERSION || Bun.version || process.versions.bun).replace(/^.*v/, "");
const BUN_TYPES_TARBALL_NAME = `types-bun-${BUN_VERSION}.tgz`;
const $ = Shell.cwd(BUN_REPO_ROOT);
beforeAll(async () => {
try {
await $`
cd ${BUN_TYPES_PACKAGE_ROOT}
bun install
# temp package.json with @types/bun name and version
cp package.json package.json.backup
`;
const pkg = await Bun.file(BUN_TYPES_PACKAGE_JSON_PATH).json();
await Bun.write(
BUN_TYPES_PACKAGE_JSON_PATH,
JSON.stringify({ ...pkg, name: "@types/bun", version: BUN_VERSION }, null, 2),
);
await $`
cd ${BUN_TYPES_PACKAGE_ROOT}
bun run build
bun pm pack --destination ${FIXTURE_DIR}
exit 0
mv package.json.backup package.json
cd ${FIXTURE_DIR}
cp ${TSCONFIG_SOURCE_PATH} tsconfig.json
bun uninstall @types/bun
bun add @types/bun@${BUN_TYPES_TARBALL_NAME}
rm ${BUN_TYPES_TARBALL_NAME}
`;
} catch (e) {
if (e instanceof ShellError) {
console.log(e.stderr.toString());
}
throw e;
}
});
beforeAll(() => {
setDefaultTimeout(1000 * 60 * 5);
});
describe("@types/bun integration test", () => {
test("it typechecks successfully", async () => {
const p = await $`
cd ${FIXTURE_DIR}
bun run check
`;
expect(p.exitCode).toBe(0);
});
});

View File

@@ -0,0 +1,3 @@
node_modules
# generated by test
tsconfig.json

View File

@@ -0,0 +1,25 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "fixture",
"dependencies": {
"@types/bun": "types-bun-1.2.3.tgz",
},
"peerDependencies": {
"typescript": "^5.0.0",
},
},
},
"packages": {
"@types/bun": ["@types/bun@types-bun-1.2.3.tgz", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }],
"@types/node": ["@types/node@22.13.5", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg=="],
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
"typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
"undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
}
}

View File

@@ -0,0 +1,183 @@
import svgpath from "cool.svg";
svgpath satisfies `${string}.svg`;
// just some APIs
new Request("url");
new Response();
new Headers();
new URL("");
new URLSearchParams();
new File([], "filename", { type: "text/plain" });
new Blob([], { type: "text/plain" });
new ReadableStream();
new WritableStream();
new TransformStream();
new AbortSignal();
new AbortController();
fetch("url");
new Bun.$.ShellError();
new Promise(resolve => {
resolve(1);
});
new Map();
new Set();
new WeakMap();
new WeakSet();
new Map();
new Set();
new WeakMap();
const statuses = [200, 400, 401, 403, 404, 500, 501, 502, 503, 504];
const r = new Request("", {
body: "",
});
await fetch(r);
await fetch("", {
tls: {
rejectUnauthorized: false,
},
});
r.method;
r.body;
r.headers.get("content-type");
await r.json();
await r.text();
declare const headers: Headers;
headers.toJSON();
const req1 = new Request("", {
body: "",
});
fetch("", {
tls: {
rejectUnauthorized: false,
checkServerIdentity: () => {
return undefined;
},
},
});
req1.body;
req1.json();
req1.formData();
req1.arrayBuffer();
req1.blob();
req1.text();
req1.arrayBuffer();
req1.blob();
req1.headers;
req1.headers.toJSON();
new ReadableStream({});
const body = await fetch(req1);
await body.text();
fetch.preconnect(new URL(""));
Bun.serve({
port: 3000,
fetch: () => new Response("ok"),
key: Bun.file(""),
cert: Bun.file(""),
tls: {
key: Bun.file(""),
cert: Bun.file(""),
},
});
URL.canParse;
URL.createObjectURL;
URL.revokeObjectURL;
Response.json();
Response.redirect("bun.sh", 300);
Response.error();
Response.redirect("bun.sh", {
status: 200,
headers: new Headers(
(() => {
const h = new Headers();
h.set("key", "value");
h.toJSON();
return h;
})(),
),
});
Bun.fetch.preconnect;
Bun.fetch("", {
proxy: "",
s3: {},
});
Bun.serve({
fetch(req) {
req.headers;
const headers = req.headers.toJSON();
const body = req.method === "GET" || req.method === "HEAD" ? undefined : req.body;
return new Response(body, {
headers,
status: statuses[Math.floor(Math.random() * statuses.length)],
});
},
});
import.meta.hot.data;
import { serve } from "bun";
new Worker("").on("message", (e: MessageEvent<string>) => {
e;
e.data satisfies string;
});
new Worker("", {
type: "module",
preload: ["preload.ts"],
});
serve({
fetch(req) {
const headers = req.headers.toJSON();
const body = req.method === "GET" || req.method === "HEAD" ? undefined : req.body;
return new Response(body, {
headers,
status: statuses[Math.floor(Math.random() * statuses.length)],
});
},
});
import { s3 } from "bun";
s3.file("");
declare const key: string;
declare const cert: string;
Bun.serve({
fetch: () => new Response("ok"),
tls: {
key,
cert,
},
});

View File

@@ -0,0 +1,14 @@
{
"name": "fixture",
"module": "index.ts",
"peerDependencies": {
"typescript": "^5.0.0"
},
"scripts": {
"check": "tsc --noEmit"
},
"type": "module",
"dependencies": {
"@types/bun": "types-bun-1.2.3.tgz"
}
}

View File

@@ -1,5 +1,5 @@
import { describe, it, expect } from "bun:test";
import { s3, S3Client, type S3Options } from "bun";
import { describe, expect, it } from "bun:test";
import { randomUUID } from "node:crypto";
describe("s3 - Storage class", () => {

View File

@@ -343,7 +343,7 @@ describe("FormData", () => {
expect(await (body.get("foo") as Blob).text()).toBe("baz");
});
type FetchReqArgs = [request: Request, init?: RequestInit];
type FetchURLArgs = [url: string | URL | Request, init?: FetchRequestInit];
type FetchURLArgs = [url: string | URL | Request, init?: RequestInit];
for (let useRequestConstructor of [true, false]) {
describe(useRequestConstructor ? "Request constructor" : "fetch()", () => {
function send(args: FetchReqArgs | FetchURLArgs) {

View File

@@ -14,7 +14,8 @@
"@faasjs/larger/*": ["js/bun/resolve/*/larger-index.js"]
},
"experimentalDecorators": true,
"emitDecoratorMetadata": true
"emitDecoratorMetadata": true,
"types": ["../packages/bun-types"]
},
"include": [
//