@usetoki/toki 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -7
- package/dist/core/app.d.ts +42 -0
- package/dist/{app.js → core/app.js} +82 -190
- package/dist/core/app.js.map +1 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/{pipeline.d.ts → core/pipeline.d.ts} +2 -2
- package/dist/{pipeline.js → core/pipeline.js} +2 -2
- package/dist/core/pipeline.js.map +1 -0
- package/dist/{app.d.ts → core/scope.d.ts} +22 -48
- package/dist/core/scope.js +196 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/{types.d.ts → core/types.d.ts} +5 -3
- package/dist/core/types.js.map +1 -0
- package/dist/http/cookies.js.map +1 -0
- package/dist/http/forms.js.map +1 -0
- package/dist/{group.d.ts → http/group.d.ts} +1 -1
- package/dist/http/group.js.map +1 -0
- package/dist/http/inject.js.map +1 -0
- package/dist/{request.d.ts → http/request.d.ts} +2 -2
- package/dist/{request.js → http/request.js} +28 -7
- package/dist/http/request.js.map +1 -0
- package/dist/{response.d.ts → http/response.d.ts} +2 -2
- package/dist/http/response.js.map +1 -0
- package/dist/http/schema.js.map +1 -0
- package/dist/{static.d.ts → http/static.d.ts} +1 -1
- package/dist/http/static.js.map +1 -0
- package/dist/index.d.ts +22 -19
- package/dist/index.js +11 -9
- package/dist/index.js.map +1 -1
- package/dist/{native.d.ts → native/native.d.ts} +35 -1
- package/dist/{native.js → native/native.js} +2 -1
- package/dist/native/native.js.map +1 -0
- package/dist/{jwt.d.ts → security/jwt.d.ts} +1 -1
- package/dist/{jwt.js → security/jwt.js} +1 -1
- package/dist/security/jwt.js.map +1 -0
- package/dist/{middleware.d.ts → security/middleware.d.ts} +1 -1
- package/dist/{middleware.js → security/middleware.js} +1 -1
- package/dist/security/middleware.js.map +1 -0
- package/dist/websocket/websocket.d.ts +64 -0
- package/dist/websocket/websocket.js +145 -0
- package/dist/websocket/websocket.js.map +1 -0
- package/package.json +21 -16
- package/dist/app.js.map +0 -1
- package/dist/cookies.js.map +0 -1
- package/dist/forms.js.map +0 -1
- package/dist/group.js.map +0 -1
- package/dist/inject.js.map +0 -1
- package/dist/jwt.js.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/middleware.js.map +0 -1
- package/dist/native.js.map +0 -1
- package/dist/pipeline.js.map +0 -1
- package/dist/request.js.map +0 -1
- package/dist/response.js.map +0 -1
- package/dist/schema.js.map +0 -1
- package/dist/static.js.map +0 -1
- package/dist/types.js.map +0 -1
- /package/dist/{logger.d.ts → core/logger.d.ts} +0 -0
- /package/dist/{logger.js → core/logger.js} +0 -0
- /package/dist/{types.js → core/types.js} +0 -0
- /package/dist/{cookies.d.ts → http/cookies.d.ts} +0 -0
- /package/dist/{cookies.js → http/cookies.js} +0 -0
- /package/dist/{forms.d.ts → http/forms.d.ts} +0 -0
- /package/dist/{forms.js → http/forms.js} +0 -0
- /package/dist/{group.js → http/group.js} +0 -0
- /package/dist/{inject.d.ts → http/inject.d.ts} +0 -0
- /package/dist/{inject.js → http/inject.js} +0 -0
- /package/dist/{response.js → http/response.js} +0 -0
- /package/dist/{schema.d.ts → http/schema.d.ts} +0 -0
- /package/dist/{schema.js → http/schema.js} +0 -0
- /package/dist/{static.js → http/static.js} +0 -0
package/README.md
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
<strong>A blazing-fast HTTP framework for Node.js.</strong> ⚡
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://usetoki.github.io/toki/"><strong>📖 Documentation</strong></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
9
13
|
<p align="center">
|
|
10
14
|
A clean, fully-typed TypeScript API on top of a native HTTP engine written in
|
|
11
15
|
<strong>Zig</strong>. Parsing, routing, static files, and compression run in native
|
|
@@ -38,6 +42,8 @@ console.log("listening on http://127.0.0.1:3000");
|
|
|
38
42
|
- 🗂️ **Static files** — MIME, `ETag` / `304`, `HEAD`, traversal-safe, with pre-computed gzip/brotli.
|
|
39
43
|
- 🗜️ **Compression** — gzip + brotli, negotiated per `Accept-Encoding`, off the event loop.
|
|
40
44
|
- 🌊 **Streaming** — `reply.stream` over chunked transfer encoding, with native backpressure.
|
|
45
|
+
- 🔭 **WebSockets** — full RFC 6455 in native code: framing, masking, fragmentation, ping/pong, close codes, subprotocols, and a per-IP message-size guard.
|
|
46
|
+
- 🔒 **Direct HTTPS** — terminate TLS 1.2/1.3 in the native engine (AEAD ciphers, ALPN, SNI; RSA + EC keys), no reverse proxy required.
|
|
41
47
|
- 🛡️ **Hardened** — schema validation, JWT, a native per-IP rate limiter, slowloris guard, configurable limits.
|
|
42
48
|
- 🧪 **Testable** — `app.inject()` runs a real request in-process, no port needed.
|
|
43
49
|
|
|
@@ -50,6 +56,8 @@ npm install @usetoki/toki
|
|
|
50
56
|
Or build from source — see [Build from source](#-build-from-source). You'll need
|
|
51
57
|
[Zig](https://ziglang.org) 0.16.0 and Node.js 20+.
|
|
52
58
|
|
|
59
|
+
Full guides and the API reference live at **[usetoki.github.io/toki](https://usetoki.github.io/toki/)**.
|
|
60
|
+
|
|
53
61
|
## 📖 Features at a glance
|
|
54
62
|
|
|
55
63
|
```ts
|
|
@@ -117,10 +125,67 @@ app.listen(3000, { host: "0.0.0.0", maxBodyBytes: 5_000_000 });
|
|
|
117
125
|
| `headerTimeoutMs` | 0 | Close a connection stalled mid-request, in ms; `0` disables (slowloris guard). |
|
|
118
126
|
| `reusePort` | `false` | `SO_REUSEPORT` for kernel-balanced multi-worker scaling (Linux/BSD). |
|
|
119
127
|
| `rateLimit` | — | `{ max, windowMs }` — native per-IP limiter; over-limit requests get a `429` before reaching JS. |
|
|
128
|
+
| `unixPath` | — | Bind a unix-domain socket at this path instead of TCP (the port is ignored). Ideal for a reverse proxy → app on the same host. |
|
|
129
|
+
| `tls` | — | `{ cert, key }` PEM — terminate HTTPS directly (TLS 1.2/1.3); see [HTTPS](#-https). |
|
|
130
|
+
| `maxWsMessageBytes` | 16 MiB | Largest accepted WebSocket message; a larger one is closed with `1009`. |
|
|
131
|
+
| `wsCompression` | `false` | Offer `permessage-deflate` (RFC 7692) when a client requests it. |
|
|
120
132
|
|
|
121
133
|
`createApp({ logger, requestTimeoutMs })` configures the app; `app.listen` returns a
|
|
122
134
|
handle whose `close()` shuts the server down gracefully.
|
|
123
135
|
|
|
136
|
+
## 🔒 HTTPS
|
|
137
|
+
|
|
138
|
+
Pass a PEM certificate chain and private key to terminate TLS directly in the engine —
|
|
139
|
+
no reverse proxy. TLS 1.2 and 1.3, AEAD ciphers only (AES-GCM, ChaCha20-Poly1305), with
|
|
140
|
+
ALPN and SNI. RSA and EC keys both work.
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { readFileSync } from "node:fs";
|
|
144
|
+
|
|
145
|
+
app.listen(443, {
|
|
146
|
+
tls: {
|
|
147
|
+
cert: readFileSync("fullchain.pem"), // leaf first, then any intermediates
|
|
148
|
+
key: readFileSync("privkey.pem"),
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`cert` and `key` take a PEM string or a `Buffer`/`Uint8Array`. WebSockets (`wss://`),
|
|
154
|
+
streaming, and static files all ride over TLS unchanged. ALPN advertises `http/1.1`;
|
|
155
|
+
HTTP/2 is not offered (put it behind a reverse proxy if you need it).
|
|
156
|
+
|
|
157
|
+
## 🔭 WebSockets
|
|
158
|
+
|
|
159
|
+
`app.ws(path, handler)` registers a WebSocket endpoint. The handler runs once per
|
|
160
|
+
connection with the live socket and the upgrade request; the framing, masking,
|
|
161
|
+
fragmentation, ping/pong, and close handshake all run in native code, so handlers
|
|
162
|
+
only ever see complete messages.
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
app.ws("/chat", { protocols: ["chat"] }, (socket, req) => {
|
|
166
|
+
console.log(`connected from ${req.ip} as ${socket.protocol}`);
|
|
167
|
+
|
|
168
|
+
socket.on("message", (data, isBinary) => {
|
|
169
|
+
socket.send(isBinary ? data : `echo: ${data.toString()}`);
|
|
170
|
+
});
|
|
171
|
+
socket.on("close", (code, reason) => console.log("closed", code, reason));
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
- **Send:** `socket.send(string | Uint8Array)` (returns the write backlog in bytes),
|
|
176
|
+
`socket.ping()`, `socket.pong()`, `socket.close(code?)`.
|
|
177
|
+
- **Events:** `message` `(data, isBinary)`, `close` `(code, reason)`, `ping`, `pong`,
|
|
178
|
+
and `drain` (fires when a backpressured socket's write queue empties).
|
|
179
|
+
- **State:** `socket.data` is a free-form per-connection bag; `socket.protocol` is the
|
|
180
|
+
negotiated subprotocol.
|
|
181
|
+
- **Compression:** set `wsCompression: true` in `listen` to offer `permessage-deflate`
|
|
182
|
+
(RFC 7692). It's negotiated per connection and applied transparently — handlers send
|
|
183
|
+
and receive plain data.
|
|
184
|
+
- The `Buffer` passed to `message` / `ping` / `pong` is a view over native memory
|
|
185
|
+
valid only during the call — copy it (`Buffer.from(data)` / `data.toString()`) to keep it.
|
|
186
|
+
|
|
187
|
+
A plain `GET` to a WebSocket path (no `Upgrade` header) gets `426 Upgrade Required`.
|
|
188
|
+
|
|
124
189
|
## 🧭 Native vs JavaScript — the boundary
|
|
125
190
|
|
|
126
191
|
The shared, heavy logic is native: HTTP parsing, routing, the MIME table, ETag and
|
|
@@ -151,9 +216,13 @@ addon for any platform from one host.
|
|
|
151
216
|
|
|
152
217
|
| Folder | What |
|
|
153
218
|
| --- | --- |
|
|
154
|
-
| `src/` |
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
219
|
+
| `src/core/` | Engine state, the libuv hot path, and server lifecycle (`engine`, `loop`, `server`). |
|
|
220
|
+
| `src/http/` | HTTP layer — `parser`, `router`, `request`, `response`, `static`, `stream`, `mime`. |
|
|
221
|
+
| `src/websocket/` | WebSocket wire format (`frame`) and the session/dispatch layer (`session`). |
|
|
222
|
+
| `src/security/` | The native rate limiter. |
|
|
223
|
+
| `src/ffi/` | Hand-declared N-API and libuv bindings. |
|
|
224
|
+
| `ts/` | TypeScript framework layer (`core/`, `http/`, `websocket/`, `security/`, `native/`) → `dist/`. |
|
|
225
|
+
| `__test__/` | Node test suite (`node:test`, run as `.ts`); Zig unit tests live in `*.test.zig` beside their module. |
|
|
157
226
|
| `examples/` | A runnable, self-checking example per feature. |
|
|
158
227
|
|
|
159
228
|
## 🧪 Examples
|
|
@@ -163,14 +232,14 @@ node examples/routing.ts
|
|
|
163
232
|
```
|
|
164
233
|
|
|
165
234
|
Browse [`examples/`](./examples) for routing, async handlers, hooks, groups, plugins,
|
|
166
|
-
validation, cookies, static files, forms, CORS, compression, rate limiting, JWT,
|
|
235
|
+
validation, cookies, static files, forms, CORS, compression, rate limiting, JWT, TLS,
|
|
167
236
|
streaming, and graceful shutdown.
|
|
168
237
|
|
|
169
238
|
## Scope
|
|
170
239
|
|
|
171
|
-
Toki speaks HTTP/1.1
|
|
172
|
-
|
|
173
|
-
|
|
240
|
+
Toki speaks HTTP/1.1, with optional direct TLS (HTTPS) termination in the engine.
|
|
241
|
+
HTTP/2 is intentionally out of scope — put it behind a reverse proxy (nginx, Caddy) if
|
|
242
|
+
you need it.
|
|
174
243
|
|
|
175
244
|
## License
|
|
176
245
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type InjectOptions, type InjectResponse } from "../http/inject.js";
|
|
2
|
+
import { Scope, type Route } from "./scope.js";
|
|
3
|
+
import { type ServerOptions } from "../native/native.js";
|
|
4
|
+
import { type StaticOptions } from "../http/static.js";
|
|
5
|
+
import type { Handler, LifecycleHook, ListenHandle, Logger, TokiOptions } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* The application. Register routes (optionally with a validation schema and
|
|
8
|
+
* route-scoped hooks), global hooks, middleware, and plugins, then
|
|
9
|
+
* {@link Toki.listen}. The pipeline stays synchronous until a step returns a
|
|
10
|
+
* `Promise`, keeping the common sync request on the fast path.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Toki extends Scope {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(options?: TokiOptions);
|
|
15
|
+
/** @internal */
|
|
16
|
+
get _logger(): Logger;
|
|
17
|
+
/** @internal */
|
|
18
|
+
_pushRoute(route: Route): void;
|
|
19
|
+
/** @internal */
|
|
20
|
+
_decorate(name: string, value: unknown): void;
|
|
21
|
+
/** @internal */
|
|
22
|
+
_setNotFound(handler: Handler): void;
|
|
23
|
+
/** @internal */
|
|
24
|
+
_mountStatic(prefix: string, dir: string, options?: StaticOptions): void;
|
|
25
|
+
/** Run `fn` once at {@link Toki.listen}, before serving. */
|
|
26
|
+
onReady(fn: LifecycleHook): this;
|
|
27
|
+
/** Run `fn` when the server closes. */
|
|
28
|
+
onClose(fn: LifecycleHook): this;
|
|
29
|
+
/** Load all registered plugins, awaiting async ones. Call before {@link Toki.listen}
|
|
30
|
+
* when any plugin is async; `listen` loads sync plugins on its own. */
|
|
31
|
+
ready(): Promise<void>;
|
|
32
|
+
/** Bind `port` and serve. Returns a handle whose `close()` stops the server. */
|
|
33
|
+
listen(port: number, options?: ServerOptions): ListenHandle;
|
|
34
|
+
/**
|
|
35
|
+
* Inject a request in-process for testing. Sends a real request over loopback so
|
|
36
|
+
* the full native path runs, auto-binding an ephemeral port when not already
|
|
37
|
+
* listening. Returns the captured response.
|
|
38
|
+
*/
|
|
39
|
+
inject(options: InjectOptions | string): Promise<InjectResponse>;
|
|
40
|
+
}
|
|
41
|
+
/** Create a new application. */
|
|
42
|
+
export declare function createApp(options?: TokiOptions): Toki;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { inject } from "./inject.js";
|
|
1
|
+
import { inject } from "../http/inject.js";
|
|
3
2
|
import { resolveLogger } from "./logger.js";
|
|
4
|
-
import {
|
|
5
|
-
import { native, } from "
|
|
6
|
-
import {
|
|
7
|
-
import { TokiRequest } from "
|
|
8
|
-
import { isStreamResponse, isTokiResponse, reply, toNative } from "
|
|
9
|
-
import {
|
|
10
|
-
|
|
3
|
+
import { Scope } from "./scope.js";
|
|
4
|
+
import { native, } from "../native/native.js";
|
|
5
|
+
import { isThenable, materialize, runAfter, runBefore, runSerialization, validationStep, } from "./pipeline.js";
|
|
6
|
+
import { TokiRequest } from "../http/request.js";
|
|
7
|
+
import { isStreamResponse, isTokiResponse, reply, toNative } from "../http/response.js";
|
|
8
|
+
import { TokiWebSocket, WS_EVENT } from "../websocket/websocket.js";
|
|
9
|
+
import { buildStaticEntries } from "../http/static.js";
|
|
10
|
+
// TLS cert/key accepted as PEM text or raw bytes; the native side reads a Buffer.
|
|
11
|
+
function toPem(value) {
|
|
12
|
+
return typeof value === "string" ? Buffer.from(value, "utf8") : Buffer.from(value);
|
|
13
|
+
}
|
|
14
|
+
// shared by every streaming response; TextEncoder is stateless across encode() calls
|
|
15
|
+
const streamEncoder = new TextEncoder();
|
|
11
16
|
// must match `not_found_index` in Zig
|
|
12
17
|
const NOT_FOUND_INDEX = 0xffffffff;
|
|
13
18
|
// pause a stream producer once the connection's write backlog passes this (1 MiB)
|
|
@@ -26,181 +31,6 @@ function streamHeaderBlock(stream, staged) {
|
|
|
26
31
|
function asArray(value) {
|
|
27
32
|
return value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
28
33
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Encapsulated registration scope: own hooks, middleware, request decorators,
|
|
31
|
-
* error handler, and path prefix. Routes here run the hook chains of this scope
|
|
32
|
-
* and all ancestors. The root app ({@link Toki}) is itself a scope; {@link
|
|
33
|
-
* Scope.register} creates children.
|
|
34
|
-
*/
|
|
35
|
-
export class Scope {
|
|
36
|
-
parent;
|
|
37
|
-
prefix;
|
|
38
|
-
onRequest = [];
|
|
39
|
-
preParsing = [];
|
|
40
|
-
middleware = [];
|
|
41
|
-
preValidation = [];
|
|
42
|
-
preHandler = [];
|
|
43
|
-
preSerialization = [];
|
|
44
|
-
onResponse = [];
|
|
45
|
-
onSend = [];
|
|
46
|
-
onTimeout = [];
|
|
47
|
-
requestDecorators = {};
|
|
48
|
-
contentTypeParsers = [];
|
|
49
|
-
plugins = [];
|
|
50
|
-
errorHandler;
|
|
51
|
-
constructor(parent, prefix) {
|
|
52
|
-
this.parent = parent;
|
|
53
|
-
this.prefix = prefix;
|
|
54
|
-
}
|
|
55
|
-
get root() {
|
|
56
|
-
return this.parent ? this.parent.root : this;
|
|
57
|
-
}
|
|
58
|
-
get log() {
|
|
59
|
-
return this.root._logger;
|
|
60
|
-
}
|
|
61
|
-
get(path, a, b) {
|
|
62
|
-
return this.#add("GET", path, a, b);
|
|
63
|
-
}
|
|
64
|
-
post(path, a, b) {
|
|
65
|
-
return this.#add("POST", path, a, b);
|
|
66
|
-
}
|
|
67
|
-
put(path, a, b) {
|
|
68
|
-
return this.#add("PUT", path, a, b);
|
|
69
|
-
}
|
|
70
|
-
patch(path, a, b) {
|
|
71
|
-
return this.#add("PATCH", path, a, b);
|
|
72
|
-
}
|
|
73
|
-
delete(path, a, b) {
|
|
74
|
-
return this.#add("DELETE", path, a, b);
|
|
75
|
-
}
|
|
76
|
-
head(path, handler) {
|
|
77
|
-
return this.#add("HEAD", path, handler);
|
|
78
|
-
}
|
|
79
|
-
options(path, handler) {
|
|
80
|
-
return this.#add("OPTIONS", path, handler);
|
|
81
|
-
}
|
|
82
|
-
route(method, path, handler) {
|
|
83
|
-
return this.#add(method, path, handler);
|
|
84
|
-
}
|
|
85
|
-
#add(method, path, a, b) {
|
|
86
|
-
const [options, handler] = typeof a === "function" ? [{}, a] : [a, b];
|
|
87
|
-
this.root._pushRoute({
|
|
88
|
-
method,
|
|
89
|
-
path: joinPaths(this.prefix, path),
|
|
90
|
-
handler,
|
|
91
|
-
options,
|
|
92
|
-
groupMiddleware: NO_MIDDLEWARE,
|
|
93
|
-
scope: this,
|
|
94
|
-
});
|
|
95
|
-
return this;
|
|
96
|
-
}
|
|
97
|
-
/** Add middleware; runs before every handler in this scope and descendants. */
|
|
98
|
-
use(middleware) {
|
|
99
|
-
this.middleware.push(middleware);
|
|
100
|
-
return this;
|
|
101
|
-
}
|
|
102
|
-
addHook(name, fn) {
|
|
103
|
-
switch (name) {
|
|
104
|
-
case "onResponse":
|
|
105
|
-
this.onResponse.push(fn);
|
|
106
|
-
break;
|
|
107
|
-
case "onSend":
|
|
108
|
-
this.onSend.push(fn);
|
|
109
|
-
break;
|
|
110
|
-
case "preParsing":
|
|
111
|
-
this.preParsing.push(fn);
|
|
112
|
-
break;
|
|
113
|
-
case "preValidation":
|
|
114
|
-
this.preValidation.push(fn);
|
|
115
|
-
break;
|
|
116
|
-
case "preHandler":
|
|
117
|
-
this.preHandler.push(fn);
|
|
118
|
-
break;
|
|
119
|
-
case "preSerialization":
|
|
120
|
-
this.preSerialization.push(fn);
|
|
121
|
-
break;
|
|
122
|
-
case "onTimeout":
|
|
123
|
-
this.onTimeout.push(fn);
|
|
124
|
-
break;
|
|
125
|
-
default:
|
|
126
|
-
this.onRequest.push(fn);
|
|
127
|
-
}
|
|
128
|
-
return this;
|
|
129
|
-
}
|
|
130
|
-
/** Set the error handler for routes in this scope (alias: `onError`). */
|
|
131
|
-
setErrorHandler(handler) {
|
|
132
|
-
this.errorHandler = handler;
|
|
133
|
-
return this;
|
|
134
|
-
}
|
|
135
|
-
onError(handler) {
|
|
136
|
-
return this.setErrorHandler(handler);
|
|
137
|
-
}
|
|
138
|
-
/** Attach a property to every request handled in this scope. */
|
|
139
|
-
decorateRequest(name, value) {
|
|
140
|
-
this.requestDecorators[name] = value;
|
|
141
|
-
return this;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Register a body parser for one or more content types, consulted by
|
|
145
|
-
* `req.parseBody()`. `type` matches case-insensitively as a prefix (e.g.
|
|
146
|
-
* `"application/xml"`), a `RegExp`, or `"*"` for any. A child scope overrides
|
|
147
|
-
* an ancestor for the same type.
|
|
148
|
-
*/
|
|
149
|
-
addContentTypeParser(type, parser) {
|
|
150
|
-
const tests = Array.isArray(type) ? type : [type];
|
|
151
|
-
for (const t of tests) {
|
|
152
|
-
this.contentTypeParsers.push({ test: contentTypeMatcher(t), parser });
|
|
153
|
-
}
|
|
154
|
-
return this;
|
|
155
|
-
}
|
|
156
|
-
/** Attach a property to the application instance (app-global, not encapsulated). */
|
|
157
|
-
decorate(name, value) {
|
|
158
|
-
this.root._decorate(name, value);
|
|
159
|
-
return this;
|
|
160
|
-
}
|
|
161
|
-
/** Set the handler for unmatched routes (app-global). */
|
|
162
|
-
setNotFoundHandler(handler) {
|
|
163
|
-
this.root._setNotFound(handler);
|
|
164
|
-
return this;
|
|
165
|
-
}
|
|
166
|
-
/** Enable CORS: stage headers on every response and answer preflight `OPTIONS`. */
|
|
167
|
-
cors(options = {}) {
|
|
168
|
-
this.use(corsHeaders(options));
|
|
169
|
-
this.options("/*", corsPreflight(options));
|
|
170
|
-
return this;
|
|
171
|
-
}
|
|
172
|
-
/** Serve files under `dir` at `urlPrefix` (joined with this scope's prefix). */
|
|
173
|
-
static(urlPrefix, dir, options) {
|
|
174
|
-
this.root._mountStatic(joinPaths(this.prefix, urlPrefix), dir, options);
|
|
175
|
-
return this;
|
|
176
|
-
}
|
|
177
|
-
/** Register a prefixed group of routes with its own middleware. */
|
|
178
|
-
group(prefix, build) {
|
|
179
|
-
const group = new RouteGroup(prefix, (method, path, handler, middleware) => {
|
|
180
|
-
this.root._pushRoute({
|
|
181
|
-
method,
|
|
182
|
-
path: joinPaths(this.prefix, path),
|
|
183
|
-
handler,
|
|
184
|
-
options: {},
|
|
185
|
-
groupMiddleware: middleware,
|
|
186
|
-
scope: this,
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
build(group);
|
|
190
|
-
return this;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Register a plugin into a fresh child scope. The plugin receives that scope as
|
|
194
|
-
* its `instance`; routes/hooks/decorators it adds are encapsulated there (and
|
|
195
|
-
* inherited by its own children), not leaked to the parent. Async plugins load
|
|
196
|
-
* during {@link Toki.ready}. `opts.prefix` mounts the plugin's routes under a path.
|
|
197
|
-
*/
|
|
198
|
-
register(plugin, opts = {}) {
|
|
199
|
-
const prefix = joinPaths(this.prefix, typeof opts.prefix === "string" ? opts.prefix : "/");
|
|
200
|
-
this.plugins.push({ plugin, opts, scope: new Scope(this, prefix) });
|
|
201
|
-
return this;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
34
|
/**
|
|
205
35
|
* The application. Register routes (optionally with a validation schema and
|
|
206
36
|
* route-scoped hooks), global hooks, middleware, and plugins, then
|
|
@@ -217,6 +47,11 @@ export class Toki extends Scope {
|
|
|
217
47
|
#notFoundHandler;
|
|
218
48
|
#compiled = [];
|
|
219
49
|
#compiledNotFound;
|
|
50
|
+
// handler per native route index (undefined for non-ws routes), and live sockets by id
|
|
51
|
+
#wsHandlers = [];
|
|
52
|
+
#wsSockets = new Map();
|
|
53
|
+
// caps inflation of a compressed ws message (set from listen options)
|
|
54
|
+
#wsMaxMessage = 16 * 1024 * 1024;
|
|
220
55
|
#booted = false;
|
|
221
56
|
#boundPort = 0;
|
|
222
57
|
#listening = false;
|
|
@@ -282,9 +117,23 @@ export class Toki extends Scope {
|
|
|
282
117
|
serverOptions.rateLimitMax = options.rateLimit.max;
|
|
283
118
|
serverOptions.rateLimitWindowMs = options.rateLimit.windowMs;
|
|
284
119
|
}
|
|
285
|
-
|
|
120
|
+
if (options.tls) {
|
|
121
|
+
serverOptions.tlsCert = toPem(options.tls.cert);
|
|
122
|
+
serverOptions.tlsKey = toPem(options.tls.key);
|
|
123
|
+
}
|
|
124
|
+
const wsRouteIndices = [];
|
|
125
|
+
const wsProtocols = [];
|
|
126
|
+
this.#routes.forEach((route, index) => {
|
|
127
|
+
if (route.webSocket) {
|
|
128
|
+
wsRouteIndices.push(index);
|
|
129
|
+
wsProtocols.push((route.webSocket.options.protocols ?? []).join(","));
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
this.#wsMaxMessage = options.maxWsMessageBytes ?? this.#wsMaxMessage;
|
|
133
|
+
this.#boundPort = native.listen(port, methods, paths, (raw) => this.#dispatch(raw), staticEntries, serverOptions, (id, event, a, b, c) => this.#wsDispatch(id, event, a, b, c), wsRouteIndices, wsProtocols);
|
|
286
134
|
this.#listening = true;
|
|
287
135
|
return {
|
|
136
|
+
port: this.#boundPort,
|
|
288
137
|
close: () => {
|
|
289
138
|
for (const fn of this.#onClose) {
|
|
290
139
|
this.#runLifecycle(fn, "onClose");
|
|
@@ -315,6 +164,7 @@ export class Toki extends Scope {
|
|
|
315
164
|
}
|
|
316
165
|
#compileAll() {
|
|
317
166
|
this.#compiled = this.#routes.map((route) => this.#compile(route));
|
|
167
|
+
this.#wsHandlers = this.#routes.map((route) => route.webSocket?.handler);
|
|
318
168
|
this.#compiledNotFound =
|
|
319
169
|
this.#notFoundHandler !== undefined
|
|
320
170
|
? this.#compileNotFound(this.#notFoundHandler)
|
|
@@ -358,7 +208,8 @@ export class Toki extends Scope {
|
|
|
358
208
|
const onTimeout = [];
|
|
359
209
|
for (const s of chain)
|
|
360
210
|
onTimeout.push(...s.onTimeout);
|
|
361
|
-
const
|
|
211
|
+
const merged = Object.assign({}, ...chain.map((s) => s.requestDecorators));
|
|
212
|
+
const decorators = Object.keys(merged).length > 0 ? merged : undefined;
|
|
362
213
|
let errorHandler;
|
|
363
214
|
for (const s of chain) {
|
|
364
215
|
if (s.errorHandler)
|
|
@@ -393,7 +244,7 @@ export class Toki extends Scope {
|
|
|
393
244
|
serialization: [...this.preSerialization],
|
|
394
245
|
onTimeout: [...this.onTimeout],
|
|
395
246
|
parsers: [...this.contentTypeParsers],
|
|
396
|
-
decorators: this.requestDecorators,
|
|
247
|
+
decorators: Object.keys(this.requestDecorators).length > 0 ? this.requestDecorators : undefined,
|
|
397
248
|
...(this.errorHandler ? { errorHandler: this.errorHandler } : {}),
|
|
398
249
|
defaultStatus: 404,
|
|
399
250
|
};
|
|
@@ -404,7 +255,8 @@ export class Toki extends Scope {
|
|
|
404
255
|
return toNative(reply.empty(raw.routeIndex === NOT_FOUND_INDEX ? 404 : 500));
|
|
405
256
|
}
|
|
406
257
|
const req = new TokiRequest(raw, { log: this.#loggerInstance, parsers: route.parsers });
|
|
407
|
-
|
|
258
|
+
if (route.decorators !== undefined)
|
|
259
|
+
Object.assign(req, route.decorators);
|
|
408
260
|
try {
|
|
409
261
|
const outcome = this.#run(req, route);
|
|
410
262
|
if (isThenable(outcome)) {
|
|
@@ -439,6 +291,47 @@ export class Toki extends Scope {
|
|
|
439
291
|
return this.#safeToNative(this.#handleError(req, error, route.errorHandler), req);
|
|
440
292
|
}
|
|
441
293
|
}
|
|
294
|
+
// routes native WebSocket events to the live socket; one bad listener is logged,
|
|
295
|
+
// never allowed to escape into the native dispatch call
|
|
296
|
+
#wsDispatch(wsId, event, a, b, c) {
|
|
297
|
+
try {
|
|
298
|
+
switch (event) {
|
|
299
|
+
case WS_EVENT.open: {
|
|
300
|
+
const raw = a;
|
|
301
|
+
const handler = this.#wsHandlers[raw.routeIndex];
|
|
302
|
+
if (handler === undefined)
|
|
303
|
+
return;
|
|
304
|
+
const socket = new TokiWebSocket(wsId, b ?? "", c === 1, this.#wsMaxMessage);
|
|
305
|
+
this.#wsSockets.set(wsId, socket);
|
|
306
|
+
handler(socket, new TokiRequest(raw, { log: this.#loggerInstance }));
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
case WS_EVENT.message: {
|
|
310
|
+
const flags = a;
|
|
311
|
+
this.#wsSockets.get(wsId)?._message(b, (flags & 1) !== 0, (flags & 2) !== 0);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
case WS_EVENT.close: {
|
|
315
|
+
const socket = this.#wsSockets.get(wsId);
|
|
316
|
+
this.#wsSockets.delete(wsId);
|
|
317
|
+
socket?._close(a, b ?? "");
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
case WS_EVENT.ping:
|
|
321
|
+
this.#wsSockets.get(wsId)?._ping(b);
|
|
322
|
+
return;
|
|
323
|
+
case WS_EVENT.pong:
|
|
324
|
+
this.#wsSockets.get(wsId)?._pong(b);
|
|
325
|
+
return;
|
|
326
|
+
case WS_EVENT.drain:
|
|
327
|
+
this.#wsSockets.get(wsId)?._drain();
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
this.#loggerInstance.error("websocket handler threw", { error: String(error) });
|
|
333
|
+
}
|
|
334
|
+
}
|
|
442
335
|
#submit(id, req, result) {
|
|
443
336
|
if (isStreamResponse(result)) {
|
|
444
337
|
this.#driveSafe(id, req, result);
|
|
@@ -495,10 +388,9 @@ export class Toki extends Scope {
|
|
|
495
388
|
}
|
|
496
389
|
async #drive(id, req, stream) {
|
|
497
390
|
native.startStream(id, stream.status, streamHeaderBlock(stream, req.stagedResponseHeaders));
|
|
498
|
-
const encoder = new TextEncoder();
|
|
499
391
|
try {
|
|
500
392
|
for await (const chunk of stream.source) {
|
|
501
|
-
const bytes = typeof chunk === "string" ?
|
|
393
|
+
const bytes = typeof chunk === "string" ? streamEncoder.encode(chunk) : chunk;
|
|
502
394
|
if (bytes.length === 0) {
|
|
503
395
|
continue;
|
|
504
396
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../ts/core/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../ts/core/logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAA6B,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAEtF,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAW;IAClC,KAAK,KAAI,CAAC;IACV,IAAI,KAAI,CAAC;IACT,IAAI,KAAI,CAAC;IACT,KAAK,KAAI,CAAC;IACV,KAAK;QACH,OAAO,YAAY,CAAC;IACtB,CAAC;CACF,CAAC;AAEF,oEAAoE;AACpE,MAAM,UAAU,mBAAmB,CACjC,QAAkB,MAAM,EACxB,WAAoC,EAAE;IAEtC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAEhC,SAAS,GAAG,CAAC,EAAY,EAAE,OAAe,EAAE,MAAgC;QAC1E,IAAI,MAAM,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QACjF,IAAI,EAAE,KAAK,OAAO,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QACjC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QACnC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;KACxE,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,aAAa,CAAC,MAA6B;IACzD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7C,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TokiRequest } from "
|
|
2
|
-
import { type JSONSchema, type RouteSchema } from "
|
|
1
|
+
import type { TokiRequest } from "../http/request.js";
|
|
2
|
+
import { type JSONSchema, type RouteSchema } from "../http/schema.js";
|
|
3
3
|
import type { HandlerResult, Middleware, ResponseHook, SerializationHook, TokiResponse } from "./types.js";
|
|
4
4
|
export declare function isThenable<T>(value: unknown): value is Promise<T>;
|
|
5
5
|
/** What `materialize` needs off a compiled route — a CompiledRoute satisfies it. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isTokiResponse, jsonResponse, normalize, reply } from "
|
|
2
|
-
import { serialize, validate } from "
|
|
1
|
+
import { isTokiResponse, jsonResponse, normalize, reply } from "../http/response.js";
|
|
2
|
+
import { serialize, validate } from "../http/schema.js";
|
|
3
3
|
export function isThenable(value) {
|
|
4
4
|
return (value != null &&
|
|
5
5
|
(typeof value === "object" || typeof value === "function") &&
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../ts/core/pipeline.ts"],"names":[],"mappings":"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"}
|