aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Colin McDonnell <colinmcd94@gmail.com> 2023-02-22 17:45:22 -0800
committerGravatar GitHub <noreply@github.com> 2023-02-22 17:45:22 -0800
commit9f53a2210cac920c34c858d1fb408dbf9b8d8f94 (patch)
treebaabceb3cb4db1d261746ecdba80cb040640fc05
parent575291a301eb14f8452958d49b74148b97b89106 (diff)
downloadbun-9f53a2210cac920c34c858d1fb408dbf9b8d8f94.tar.gz
bun-9f53a2210cac920c34c858d1fb408dbf9b8d8f94.tar.zst
bun-9f53a2210cac920c34c858d1fb408dbf9b8d8f94.zip
Various type fixes (#2135)
* Simplify serve() types * Remove baseURI * Add Bun.serve type tests * Number env vars * Make loader optional * FSRouter doesn't support URL * Update sqlite types * Bench --------- Co-authored-by: Colin McDonnell <colinmcd@alum.mit.edu>
-rw-r--r--bench/ffi/bun.js3
-rw-r--r--packages/bun-types/bun.d.ts106
-rw-r--r--packages/bun-types/sqlite.d.ts37
-rw-r--r--packages/bun-types/tests/serve.test-d.ts81
-rw-r--r--packages/bun-types/tests/spawn.test-d.ts70
-rw-r--r--packages/bun-types/tests/sqlite.test-d.ts28
-rw-r--r--packages/bun-types/tests/tcp.test-d.ts4
7 files changed, 272 insertions, 57 deletions
diff --git a/bench/ffi/bun.js b/bench/ffi/bun.js
index 593473929..6e83702ee 100644
--- a/bench/ffi/bun.js
+++ b/bench/ffi/bun.js
@@ -1,8 +1,7 @@
import { ptr, dlopen, CString, toBuffer } from "bun:ffi";
import { run, bench, group } from "mitata";
-const { napiNoop, napiHash, napiString } = require(import.meta.dir +
- "/src/ffi_napi_bench.node");
+const { napiNoop, napiHash, napiString } = require(import.meta.dir + "/src/ffi_napi_bench.node");
const {
symbols: {
diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts
index a04ec91a0..8f020dcfc 100644
--- a/packages/bun-types/bun.d.ts
+++ b/packages/bun-types/bun.d.ts
@@ -52,6 +52,12 @@ declare module "bun" {
options?: { PATH?: string; cwd?: string },
): string;
+ export type Serve<WebSocketDataType = undefined> =
+ | ServeOptions
+ | TLSServeOptions
+ | WebSocketServeOptions<WebSocketDataType>
+ | TLSWebSocketServeOptions<WebSocketDataType>;
+
/**
* Start a fast HTTP server.
*
@@ -88,8 +94,12 @@ declare module "bun" {
* });
* ```
*/
- export function serve<WebSocketDataType>(
- options: Serve<WebSocketDataType>,
+ export function serve<T>(
+ options:
+ | ServeOptions
+ | TLSServeOptions
+ | WebSocketServeOptions<T>
+ | TLSWebSocketServeOptions<T>,
): Server;
/**
@@ -821,8 +831,9 @@ declare module "bun" {
* ```
*
*/
+
export class Transpiler {
- constructor(options: TranspilerOptions);
+ constructor(options?: TranspilerOptions);
/**
* Transpile code from TypeScript or JSX into valid JavaScript.
@@ -856,7 +867,7 @@ declare module "bun" {
* @param code The code to transpile
*
*/
- transformSync(code: StringOrBuffer, loader: JavaScriptLoader): string;
+ transformSync(code: StringOrBuffer, loader?: JavaScriptLoader): string;
/**
* Get a list of import paths and paths from a TypeScript, JSX, TSX, or JavaScript file.
@@ -1439,7 +1450,7 @@ declare module "bun" {
* "http://localhost:3000"
*
*/
- baseURI?: string;
+ // baseURI?: string;
/**
* What is the maximum size of a request body? (in bytes)
@@ -1527,6 +1538,9 @@ declare module "bun" {
): Response | undefined | Promise<Response | undefined>;
}
+ export interface TLSWebSocketServeOptions<WebSocketDataType = undefined>
+ extends WebSocketServeOptions<WebSocketDataType>,
+ TLSOptions {}
export interface Errorlike extends Error {
code?: string;
errno?: number;
@@ -1547,8 +1561,18 @@ declare module "bun" {
*/
certFile: string;
+ /**
+ * Passphrase for the TLS key
+ */
passphrase?: string;
+ /**
+ * File path to a .pem file for a custom root CA
+ */
caFile?: string;
+
+ /**
+ * File path to a .pem file custom Diffie Helman parameters
+ */
dhParamsFile?: string;
/**
@@ -1564,17 +1588,13 @@ declare module "bun" {
lowMemoryMode?: boolean;
}
- export type TLSServeOptions<WebSocketDataType = undefined> = (
- | WebSocketServeOptions<WebSocketDataType>
- | ServerWebSocket
- ) &
- TLSOptions & {
- /**
- * The keys are [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) hostnames.
- * The values are SSL options objects.
- */
- serverNames: Record<string, TLSOptions>;
- };
+ export interface TLSServeOptions extends ServeOptions, TLSOptions {
+ /**
+ * The keys are [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) hostnames.
+ * The values are SSL options objects.
+ */
+ serverNames?: Record<string, TLSOptions>;
+ }
/**
* HTTP & HTTPS Server
@@ -1754,11 +1774,6 @@ declare module "bun" {
readonly development: boolean;
}
- export type Serve<WebSocketDataType = undefined> =
- | TLSServeOptions<WebSocketDataType>
- | WebSocketServeOptions<WebSocketDataType>
- | ServeOptions;
-
/**
* [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) powered by the fastest system calls available for operating on files.
*
@@ -2775,20 +2790,18 @@ declare module "bun" {
readonly localPort: number;
}
- interface SocketListener<Options extends SocketOptions = SocketOptions> {
+ interface SocketListener<Data = undefined> {
stop(closeActiveConnections?: boolean): void;
ref(): void;
unref(): void;
- reload(options: Pick<Partial<Options>, "socket">): void;
- data: Options["data"];
+ reload(options: Pick<Partial<SocketOptions>, "socket">): void;
+ data: Data;
}
- interface TCPSocketListener<Options extends TCPSocketOptions<unknown>>
- extends SocketListener<Options> {
+ interface TCPSocketListener<Data> extends SocketListener<Data> {
readonly port: number;
readonly hostname: string;
}
- interface UnixSocketListener<Options extends UnixSocketOptions<unknown>>
- extends SocketListener<Options> {
+ interface UnixSocketListener<Data> extends SocketListener<Data> {
readonly unix: string;
}
@@ -2808,7 +2821,7 @@ declare module "bun" {
Data = unknown,
DataBinaryType extends BinaryType = "buffer",
> {
- open(socket: Socket<Data>): void | Promise<void>;
+ open?(socket: Socket<Data>): void | Promise<void>;
close?(socket: Socket<Data>): void | Promise<void>;
error?(socket: Socket<Data>, error: Error): void | Promise<void>;
data?(
@@ -2839,6 +2852,10 @@ declare module "bun" {
connectError?(socket: Socket<Data>, error: Error): void | Promise<void>;
/**
+ * Called when a message times out.
+ */
+ timeout?(socket: Socket<Data>): void | Promise<void>;
+ /**
* Choose what `ArrayBufferView` is returned in the {@link SocketHandler.data} callback.
*
* @default "buffer"
@@ -2858,12 +2875,25 @@ declare module "bun" {
interface SocketOptions<Data = unknown> {
socket: SocketHandler<Data>;
- tls?: boolean | TLSOptions;
data?: Data;
}
- interface TCPSocketOptions<Data = undefined> extends SocketOptions<Data> {
+ // interface TCPSocketOptions<Data = undefined> extends SocketOptions<Data> {
+ // hostname: string;
+ // port: number;
+ // }
+
+ interface TCPSocketListenOptions<Data = undefined>
+ extends SocketOptions<Data> {
hostname: string;
port: number;
+ tls?: TLSOptions;
+ }
+
+ interface TCPSocketConnectOptions<Data = undefined>
+ extends SocketOptions<Data> {
+ hostname: string;
+ port: number;
+ tls?: boolean;
}
interface UnixSocketOptions<Data = undefined> extends SocketOptions<Data> {
@@ -2884,7 +2914,7 @@ declare module "bun" {
*
*/
export function connect<Data = undefined>(
- options: TCPSocketOptions<Data>,
+ options: TCPSocketConnectOptions<Data>,
): Promise<TCPSocketListener<typeof options>>;
export function connect<Data = undefined>(
options: UnixSocketOptions<Data>,
@@ -2904,11 +2934,11 @@ declare module "bun" {
*
*/
export function listen<Data = undefined>(
- options: TCPSocketOptions<Data>,
- ): TCPSocketListener<typeof options>;
+ options: TCPSocketListenOptions<Data>,
+ ): TCPSocketListener<Data>;
export function listen<Data = undefined>(
options: UnixSocketOptions<Data>,
- ): UnixSocketListener<typeof options>;
+ ): UnixSocketListener<Data>;
namespace SpawnOptions {
type Readable =
@@ -2951,7 +2981,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.
*
*/
- env?: Record<string, string>;
+ env?: Record<string, string | number>;
/**
* The standard file descriptors of the process
@@ -3117,11 +3147,11 @@ declare module "bun" {
/** The base path to use when routing */
assetPrefix?: string;
-
origin?: string;
});
- match(input: string | Request | Response | URL): MatchedRoute | null;
+ // todo: URL
+ match(input: string | Request | Response): MatchedRoute | null;
readonly assetPrefix: string;
readonly origin: string;
diff --git a/packages/bun-types/sqlite.d.ts b/packages/bun-types/sqlite.d.ts
index e908f0281..92acce170 100644
--- a/packages/bun-types/sqlite.d.ts
+++ b/packages/bun-types/sqlite.d.ts
@@ -165,14 +165,14 @@ declare module "bun:sqlite" {
* | `bigint` | `INTEGER` |
* | `null` | `NULL` |
*/
- run<ParamsType = SQLQueryBindings>(
+ run<ParamsType extends SQLQueryBindings[]>(
sqlQuery: string,
...bindings: ParamsType[]
): void;
/**
This is an alias of {@link Database.prototype.run}
*/
- exec<ParamsType = SQLQueryBindings>(
+ exec<ParamsType extends SQLQueryBindings[]>(
sqlQuery: string,
...bindings: ParamsType[]
): void;
@@ -202,9 +202,12 @@ declare module "bun:sqlite" {
* Under the hood, this calls `sqlite3_prepare_v3`.
*
*/
- query<ParamsType = SQLQueryBindings, ReturnType = any>(
+ query<ReturnType, ParamsType extends SQLQueryBindings | SQLQueryBindings[]>(
sqlQuery: string,
- ): Statement<ParamsType, ReturnType>;
+ ): Statement<
+ ReturnType,
+ ParamsType extends Array<any> ? ParamsType : [ParamsType]
+ >;
/**
* Compile a SQL query and return a {@link Statement} object.
@@ -227,10 +230,15 @@ declare module "bun:sqlite" {
* Under the hood, this calls `sqlite3_prepare_v3`.
*
*/
- prepare<ParamsType = SQLQueryBindings, ReturnType = any>(
- sql: string,
- ...params: ParamsType[]
- ): Statement<ParamsType, ReturnType>;
+ prepare<
+ ReturnType,
+ ParamsType extends SQLQueryBindings | SQLQueryBindings[],
+ >(
+ sqlQuery: string,
+ ): Statement<
+ ReturnType,
+ ParamsType extends Array<any> ? ParamsType : [ParamsType]
+ >;
/**
* Is the database in a transaction?
@@ -383,7 +391,10 @@ declare module "bun:sqlite" {
* // => undefined
* ```
*/
- export class Statement<ParamsType = SQLQueryBindings, ReturnType = any> {
+ export class Statement<
+ ReturnType = unknown,
+ ParamsType extends SQLQueryBindings[] = any[],
+ > {
/**
* Creates a new prepared statement from native code.
*
@@ -410,7 +421,7 @@ declare module "bun:sqlite" {
* // => [{bar: "foo"}]
* ```
*/
- all(...params: ParamsType[]): ReturnType[];
+ all(...params: ParamsType): ReturnType[];
/**
* Execute the prepared statement and return **the first** result.
@@ -446,7 +457,7 @@ declare module "bun:sqlite" {
* | `null` | `NULL` |
*
*/
- get(...params: ParamsType[]): ReturnType | null;
+ get(...params: ParamsType): ReturnType | null;
/**
* Execute the prepared statement. This returns `undefined`.
@@ -479,7 +490,7 @@ declare module "bun:sqlite" {
* | `null` | `NULL` |
*
*/
- run(...params: ParamsType[]): void;
+ run(...params: ParamsType): void;
/**
* Execute the prepared statement and return the results as an array of arrays.
@@ -516,7 +527,7 @@ declare module "bun:sqlite" {
*
*/
values(
- ...params: ParamsType[]
+ ...params: ParamsType
): Array<Array<string | bigint | number | boolean | Uint8Array>>;
/**
diff --git a/packages/bun-types/tests/serve.test-d.ts b/packages/bun-types/tests/serve.test-d.ts
new file mode 100644
index 000000000..67a450f7e
--- /dev/null
+++ b/packages/bun-types/tests/serve.test-d.ts
@@ -0,0 +1,81 @@
+Bun.serve({
+ fetch(req) {
+ console.log(req.url); // => http://localhost:3000/
+ return new Response("Hello World");
+ },
+});
+
+Bun.serve({
+ fetch(req) {
+ console.log(req.url); // => http://localhost:3000/
+ return new Response("Hello World");
+ },
+ keyFile: "ca.pem",
+ certFile: "cert.pem",
+});
+
+Bun.serve({
+ websocket: {
+ message(ws, message) {
+ ws.send(message);
+ },
+ },
+
+ fetch(req, server) {
+ // Upgrade to a ServerWebSocket if we can
+ // This automatically checks for the `Sec-WebSocket-Key` header
+ // meaning you don't have to check headers, you can just call `upgrade()`
+ if (server.upgrade(req))
+ // When upgrading, we return undefined since we don't want to send a Response
+ return;
+
+ return new Response("Regular HTTP response");
+ },
+});
+
+type User = {
+ name: string;
+};
+
+Bun.serve<User>({
+ fetch(req, server) {
+ if (req.url === "/chat") {
+ if (
+ server.upgrade(req, {
+ data: {
+ name: new URL(req.url).searchParams.get("name") || "Friend",
+ },
+ headers: {
+ "Set-Cookie": "name=" + new URL(req.url).searchParams.get("name"),
+ },
+ })
+ )
+ return;
+ }
+
+ return new Response("Expected a websocket connection", { status: 400 });
+ },
+
+ websocket: {
+ open(ws) {
+ console.log("WebSocket opened");
+ ws.subscribe("the-group-chat");
+ },
+
+ message(ws, message) {
+ ws.publish("the-group-chat", `${ws.data.name}: ${message}`);
+ },
+
+ close(ws, code, reason) {
+ ws.publish("the-group-chat", `${ws.data.name} left the chat`);
+ },
+
+ drain(ws) {
+ console.log("Please send me data. I am ready to receive it.");
+ },
+
+ perMessageDeflate: true,
+ },
+});
+
+export {};
diff --git a/packages/bun-types/tests/spawn.test-d.ts b/packages/bun-types/tests/spawn.test-d.ts
new file mode 100644
index 000000000..cd776e43f
--- /dev/null
+++ b/packages/bun-types/tests/spawn.test-d.ts
@@ -0,0 +1,70 @@
+Bun.spawn(["echo", "hello"]);
+{
+ const proc = Bun.spawn(["echo", "hello"], {
+ cwd: "./path/to/subdir", // specify a working direcory
+ env: { ...process.env, FOO: "bar" }, // specify environment variables
+ onExit(proc, exitCode, signalCode, error) {
+ // exit handler
+ },
+ });
+
+ proc.pid; // process ID of subprocess
+}
+
+{
+ const proc = Bun.spawn(["cat"], {
+ stdin: await fetch(
+ "https://raw.githubusercontent.com/oven-sh/bun/main/examples/hashing.js",
+ ),
+ });
+
+ const text = await new Response(proc.stdout).text();
+ console.log(text); // "const input = "hello world".repeat(400); ..."
+}
+
+{
+ const proc = Bun.spawn(["cat"], {
+ stdin: "pipe", // return a FileSink for writing
+ });
+
+ // enqueue string data
+ proc.stdin!.write("hello");
+
+ // enqueue binary data
+ const enc = new TextEncoder();
+ proc.stdin!.write(enc.encode(" world!"));
+
+ // send buffered data
+ proc.stdin!.flush();
+
+ // close the input stream
+ proc.stdin!.end();
+}
+
+{
+ const proc = Bun.spawn(["echo", "hello"]);
+ const text = await new Response(proc.stdout).text();
+ console.log(text); // => "hello"
+}
+
+{
+ const proc = Bun.spawn(["echo", "hello"], {
+ onExit(proc, exitCode, signalCode, error) {
+ // exit handler
+ },
+ });
+
+ await proc.exited; // resolves when process exit
+ proc.killed; // boolean — was the process killed?
+ proc.exitCode; // null | number
+ proc.signalCode; // null | "SIGABRT" | "SIGALRM" | ...
+ proc.kill();
+ proc.killed; // true
+
+ proc.kill(); // specify an exit code
+ proc.unref();
+}
+
+{
+}
+export {};
diff --git a/packages/bun-types/tests/sqlite.test-d.ts b/packages/bun-types/tests/sqlite.test-d.ts
new file mode 100644
index 000000000..b1c2e3ddb
--- /dev/null
+++ b/packages/bun-types/tests/sqlite.test-d.ts
@@ -0,0 +1,28 @@
+import { Database } from "bun:sqlite";
+import { expectType } from "tsd";
+
+const db = new Database(":memory:");
+const query1 = db.query<
+ { name: string; dob: number }, // return type first
+ { $id: string }
+>("select name, dob from users where id = $id");
+query1.all({ $id: "asdf" }); // => {name: string; dob:string}[]
+
+const query2 = db.query<
+ { name: string; dob: number },
+ [string, number] // pass tuple for positional params
+>("select ?1 as name, ?2 as dob");
+const allResults = query2.all("Shaq", 50); // => {name: string; dob:string}[]
+const getResults = query2.get("Shaq", 50); // => {name: string; dob:string}[]
+const runResults = query2.run("Shaq", 50); // => {name: string; dob:string}[]
+
+expectType<{ name: string; dob: number }[]>(allResults);
+expectType<{ name: string; dob: number } | null>(getResults);
+expectType<void>(runResults);
+
+const query3 = db.prepare<
+ { name: string; dob: number }, // return type first
+ [{ $id: string }]
+>("select name, dob from users where id = $id");
+const allResults3 = query3.all({ $id: "asdf" });
+expectType<{ name: string; dob: number }[]>(allResults3);
diff --git a/packages/bun-types/tests/tcp.test-d.ts b/packages/bun-types/tests/tcp.test-d.ts
index 2d5f66f52..f951163d6 100644
--- a/packages/bun-types/tests/tcp.test-d.ts
+++ b/packages/bun-types/tests/tcp.test-d.ts
@@ -26,10 +26,6 @@ await Bun.connect({
},
hostname: "adsf",
port: 324,
- tls: {
- certFile: "asdf",
- keyFile: "adsf",
- },
});
await Bun.connect({