@daloyjs/core 0.1.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 +296 -0
- package/dist/adapters/bun.d.ts +16 -0
- package/dist/adapters/bun.d.ts.map +1 -0
- package/dist/adapters/bun.js +25 -0
- package/dist/adapters/bun.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +11 -0
- package/dist/adapters/cloudflare.d.ts.map +1 -0
- package/dist/adapters/cloudflare.js +6 -0
- package/dist/adapters/cloudflare.js.map +1 -0
- package/dist/adapters/deno.d.ts +12 -0
- package/dist/adapters/deno.d.ts.map +1 -0
- package/dist/adapters/deno.js +13 -0
- package/dist/adapters/deno.js.map +1 -0
- package/dist/adapters/node.d.ts +25 -0
- package/dist/adapters/node.d.ts.map +1 -0
- package/dist/adapters/node.js +90 -0
- package/dist/adapters/node.js.map +1 -0
- package/dist/adapters/vercel.d.ts +13 -0
- package/dist/adapters/vercel.d.ts.map +1 -0
- package/dist/adapters/vercel.js +4 -0
- package/dist/adapters/vercel.js.map +1 -0
- package/dist/app.d.ts +104 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +487 -0
- package/dist/app.js.map +1 -0
- package/dist/client.d.ts +40 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +61 -0
- package/dist/client.js.map +1 -0
- package/dist/contract.d.ts +31 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +76 -0
- package/dist/contract.js.map +1 -0
- package/dist/docs.d.ts +16 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/docs.js +51 -0
- package/dist/docs.js.map +1 -0
- package/dist/errors.d.ts +75 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +155 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +26 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +74 -0
- package/dist/logger.js.map +1 -0
- package/dist/middleware.d.ts +62 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +201 -0
- package/dist/middleware.js.map +1 -0
- package/dist/openapi.d.ts +28 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +178 -0
- package/dist/openapi.js.map +1 -0
- package/dist/router.d.ts +30 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +135 -0
- package/dist/router.js.map +1 -0
- package/dist/schema.d.ts +45 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +13 -0
- package/dist/schema.js.map +1 -0
- package/dist/security.d.ts +21 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +107 -0
- package/dist/security.js.map +1 -0
- package/dist/types.d.ts +98 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +108 -0
package/README.md
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# DaloyJS
|
|
2
|
+
|
|
3
|
+
> A **runtime-portable TypeScript web framework** with built-in **contract-first routing**, **validation**, **OpenAPI (Hey API)**, **typed client generation**, **large-scale maintainability**, and **highly secured by default (pnpm)**.
|
|
4
|
+
|
|
5
|
+
📚 **Documentation site:** [`./daloyjs.dev`](./daloyjs.dev) — a Next.js 16 + shadcn/ui + Tailwind v4 site with the landing page, getting-started guide, tutorials, security docs, and full API reference. Run it with:
|
|
6
|
+
|
|
7
|
+
```zsh
|
|
8
|
+
cd daloyjs.dev
|
|
9
|
+
pnpm install
|
|
10
|
+
pnpm dev # http://localhost:3000
|
|
11
|
+
pnpm build # static prerender of every docs route
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
DaloyJS exists to be the framework you'd build if you took the best ideas from each modern stack:
|
|
17
|
+
|
|
18
|
+
| You want | Today's best-of | What DaloyJS gives you |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| Best **OpenAPI ergonomics** | [FastAPI](https://fastapi.tiangolo.com) | First-class OpenAPI 3.1 generation from a single route definition. |
|
|
21
|
+
| Best **Vercel / serverless / edge fit** | [Hono](https://hono.dev/docs/) | Web-standard `Request → Response` core, multi-runtime adapters. |
|
|
22
|
+
| Mature **Swagger / docs / ops** in Node | [Fastify](https://fastify.dev/docs/latest/Reference/) | Encapsulated plugins, structured logger, graceful shutdown, request ids, hooks. |
|
|
23
|
+
| Modern **TS-first DX**, Bun acceptable | [Elysia](https://elysiajs.com/at-glance.html) | End-to-end typed handlers, typed context, typed client. |
|
|
24
|
+
| Best-in-class **typed client codegen** for any consumer | [Hey API](https://heyapi.dev/openapi-ts/get-started) | One command (`pnpm gen`) emits a fully-typed fetch SDK from your spec. |
|
|
25
|
+
| **Better supply-chain security** than npm | [pnpm](https://pnpm.io/motivation) | Strict, content-addressable installs; reproducible lockfile; per-project `.npmrc` hardening. |
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
56/56 tests passing · clean strict TypeScript 6 · runs on Node, Bun, Deno, Cloudflare, Vercel
|
|
29
|
+
~12.3M static-route ops/sec · ~1.5M dynamic-route ops/sec on M-class CPU
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Why a new framework?
|
|
35
|
+
|
|
36
|
+
Each existing stack is excellent at one thing and forces tradeoffs everywhere else:
|
|
37
|
+
|
|
38
|
+
- Hono is small and portable but OpenAPI is a plugin afterthought.
|
|
39
|
+
- Elysia has gorgeous typing but pulls you toward Bun.
|
|
40
|
+
- Fastify has the best Node ops story but is Node-only and validation/types/docs are not unified.
|
|
41
|
+
- FastAPI has the best docs ergonomics — but it's Python.
|
|
42
|
+
- Hey API gives you the best typed client — but you still need a server that produces a clean spec.
|
|
43
|
+
- npm leaves supply-chain protection up to you.
|
|
44
|
+
|
|
45
|
+
DaloyJS combines the wins:
|
|
46
|
+
|
|
47
|
+
1. **Explicit contracts, minimal ceremony.** One `app.route({...})` is the source of truth for validation, types, OpenAPI, the typed client, and contract tests.
|
|
48
|
+
2. **One source of truth for validation, typing, and docs** via [Standard Schema](https://github.com/standard-schema/standard-schema) — Zod 4 / Valibot / ArkType / TypeBox all work, no lock-in.
|
|
49
|
+
3. **Portable core, optional runtime optimizations** — the only thing the core knows is `Request → Response`. Adapters live at the edge.
|
|
50
|
+
4. **Secure by default — bad defaults are bugs.** Body limits, prototype-pollution-safe JSON, path-traversal rejection, request timeouts, Helmet-grade headers, RFC 9457 problem+json errors with prod-mode redaction.
|
|
51
|
+
5. **Tooling and inspectability over magic.** `app.introspect()` is a public API; contract-test runner is built in.
|
|
52
|
+
6. **Optimize for large-team maintenance**, not only solo-dev speed. Encapsulated plugins, decorators, request ids, structured logger.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
DaloyJS is distributed via **pnpm** for [supply-chain hygiene](https://pnpm.io/motivation) — strict isolation, content-addressable store, deterministic lockfile, no phantom dependencies.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pnpm add daloy zod@^4
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Zod 4 is the recommended validator for new DaloyJS apps because it is modern, smaller, and Standard-Schema-compatible. DaloyJS still accepts any Standard Schema validator, so teams can use Valibot, ArkType, TypeBox, or another compatible schema library when that better fits their stack.
|
|
65
|
+
|
|
66
|
+
The repo ships an [`.npmrc`](.npmrc) with hardened defaults:
|
|
67
|
+
|
|
68
|
+
```ini
|
|
69
|
+
auto-install-peers=true
|
|
70
|
+
strict-peer-dependencies=true
|
|
71
|
+
prefer-frozen-lockfile=true
|
|
72
|
+
verify-store-integrity=true
|
|
73
|
+
# Optional: pnpm 10+ supply-chain controls
|
|
74
|
+
# minimum-release-age=1440 # wait 24h before installing fresh releases
|
|
75
|
+
# ignore-scripts=true # whitelist install scripts via approve-builds
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Run `pnpm audit --prod` regularly (or `pnpm run audit` in this repo) — and `pnpm install --frozen-lockfile` in CI.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Hello world
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { z } from "zod";
|
|
86
|
+
import { App, NotFoundError, secureHeaders, rateLimit, requestId } from "daloy";
|
|
87
|
+
import { serve } from "daloy/node";
|
|
88
|
+
|
|
89
|
+
const app = new App({ bodyLimitBytes: 1024 * 1024, requestTimeoutMs: 5_000 });
|
|
90
|
+
|
|
91
|
+
// Security defaults — usually three plugins in other frameworks.
|
|
92
|
+
app.use(requestId());
|
|
93
|
+
app.use(secureHeaders());
|
|
94
|
+
app.use(rateLimit({ windowMs: 60_000, max: 120 }));
|
|
95
|
+
|
|
96
|
+
app.route({
|
|
97
|
+
method: "GET",
|
|
98
|
+
path: "/books/:id",
|
|
99
|
+
operationId: "getBookById",
|
|
100
|
+
tags: ["Books"],
|
|
101
|
+
request: { params: z.object({ id: z.string() }) },
|
|
102
|
+
responses: {
|
|
103
|
+
200: { description: "Found", body: z.object({ id: z.string(), title: z.string() }) },
|
|
104
|
+
404: { description: "Not found" },
|
|
105
|
+
},
|
|
106
|
+
handler: async ({ params }) => ({
|
|
107
|
+
status: 200,
|
|
108
|
+
body: { id: params.id, title: `Book ${params.id}` },
|
|
109
|
+
}),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
serve(app, { port: 3000 });
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## OpenAPI + Hey API typed client
|
|
118
|
+
|
|
119
|
+
DaloyJS produces a clean OpenAPI 3.1 document with **zero plugins**, then [@hey-api/openapi-ts](https://heyapi.dev/openapi-ts/get-started) turns that into a fully typed TypeScript SDK that any consumer (your web app, mobile RN bundle, internal CLI) can drop in.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pnpm gen # writes generated/openapi.json + generated/client/
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
That single command runs the two scripts:
|
|
126
|
+
|
|
127
|
+
```jsonc
|
|
128
|
+
// package.json
|
|
129
|
+
"scripts": {
|
|
130
|
+
"gen:openapi": "node --import tsx scripts/dump-openapi.ts",
|
|
131
|
+
"gen:client": "openapi-ts",
|
|
132
|
+
"gen": "pnpm gen:openapi && pnpm gen:client"
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`openapi-ts.config.ts`:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { defineConfig } from "@hey-api/openapi-ts";
|
|
140
|
+
export default defineConfig({
|
|
141
|
+
input: "./generated/openapi.json",
|
|
142
|
+
output: { path: "./generated/client", postProcess: ["prettier"] },
|
|
143
|
+
plugins: ["@hey-api/client-fetch", "@hey-api/typescript", "@hey-api/sdk"],
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
For TypeScript consumers in the same monorepo you can skip codegen entirely and use the **in-process typed client**:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { createClient } from "daloy/client";
|
|
151
|
+
const client = createClient(app, { baseUrl: "http://localhost:3000" });
|
|
152
|
+
const r = await client.getBookById({ params: { id: "1" } });
|
|
153
|
+
// ^? { status: 200; body: { id: string; title: string } } | { status: 404; ... }
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Built-in docs UI (Scalar / Swagger UI)
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import { scalarHtml, htmlResponse } from "daloy/docs";
|
|
162
|
+
// returns a self-contained HTML page that loads /openapi.json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Mount at `/docs` and the UI is always contract-accurate — never stale.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Security defaults (no plugins required)
|
|
170
|
+
|
|
171
|
+
| Threat | Default behavior |
|
|
172
|
+
|---|---|
|
|
173
|
+
| **Body-size DoS** | Streamed read, hard cap (default 1 MiB), `Content-Length` checked first. |
|
|
174
|
+
| **Prototype pollution** | `safeJsonParse` strips `__proto__` / `constructor` / `prototype` via reviver. |
|
|
175
|
+
| **Header / response splitting** | `sanitizeHeaderName` / `sanitizeHeaderValue` reject CRLF + NUL. |
|
|
176
|
+
| **Path traversal** | Router rejects `..` segments and `//` before walking. |
|
|
177
|
+
| **Slow-loris / hung handlers** | `requestTimeoutMs` aborts handlers (default 30 s); Node adapter sets `requestTimeout` + `headersTimeout` + `maxHeaderSize`. |
|
|
178
|
+
| **MIME sniffing** | `secureHeaders()` sets `X-Content-Type-Options: nosniff`. |
|
|
179
|
+
| **Clickjacking** | `X-Frame-Options: DENY` + CSP `frame-ancestors 'none'`. |
|
|
180
|
+
| **XSS via injected scripts** | Strict CSP `default-src 'self'` baseline. |
|
|
181
|
+
| **Cross-origin leakage** | `cross-origin-opener-policy` + `cross-origin-resource-policy` set to `same-origin`. |
|
|
182
|
+
| **Information disclosure (5xx)** | Production mode strips `detail` from 5xx problem+json automatically. |
|
|
183
|
+
| **Credential timing attacks** | `timingSafeEqual()` for tokens & signatures. |
|
|
184
|
+
| **Brute-force / scraping** | `rateLimit()` with token-bucket + `Retry-After`. |
|
|
185
|
+
| **Method confusion** | Real **405** with `Allow` header, not a misleading 404. |
|
|
186
|
+
| **CORS misconfig** | Explicit allowlist; never `*` with credentials. |
|
|
187
|
+
| **Request correlation** | Cryptographic `randomId()` request ids on every response. |
|
|
188
|
+
| **Supply chain** | Distributed via pnpm with hardening `.npmrc`; reproducible lockfile; opt-in `ignore-scripts` + `minimum-release-age`. |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Performance
|
|
193
|
+
|
|
194
|
+
```text
|
|
195
|
+
$ pnpm bench
|
|
196
|
+
static route lookup 12,363,799 ops/sec
|
|
197
|
+
dynamic 4-segment lookup 1,513,983 ops/sec
|
|
198
|
+
miss 4,763,878 ops/sec
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
- Static (no-param) routes resolve via a single `Map.get` — **~12M ops/sec**.
|
|
202
|
+
- Dynamic routes walk a trie, **O(path-segments)** regardless of route count.
|
|
203
|
+
- Body parsing is lazy and only runs when a route declares a body schema.
|
|
204
|
+
- No regex on the hot path.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Test client + contract tests
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
const res = await app.request("/books/1");
|
|
212
|
+
|
|
213
|
+
import { runContractTests } from "daloy/contract";
|
|
214
|
+
const report = await runContractTests(app);
|
|
215
|
+
if (!report.ok) process.exit(1);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The contract runner verifies that declared examples actually match their schemas, flags duplicate/missing operationIds, dead routes, and accidental body schemas on safe methods.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Plugin encapsulation (Fastify-style)
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
const usersPlugin = {
|
|
226
|
+
name: "users",
|
|
227
|
+
register(app) {
|
|
228
|
+
app.route({ method: "GET", path: "/me", operationId: "me",
|
|
229
|
+
responses: { 200: { description: "ok" } },
|
|
230
|
+
handler: async () => ({ status: 200, body: { user: "alice" } }) });
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
app.register(usersPlugin, { prefix: "/users", tags: ["Users"] });
|
|
234
|
+
await app.ready();
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Multi-runtime
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
import { serve } from "daloy/node"; // Node
|
|
243
|
+
import { serve } from "daloy/bun"; // Bun
|
|
244
|
+
import { serve } from "daloy/deno"; // Deno
|
|
245
|
+
import { toFetchHandler } from "daloy/cloudflare"; // Cloudflare Workers
|
|
246
|
+
import { toEdgeHandler } from "daloy/vercel"; // Vercel Edge / Next.js
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The core only ever sees `Request → Response`. Adapters live at the edge.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## References
|
|
254
|
+
|
|
255
|
+
- Hey API — typed OpenAPI client codegen: <https://heyapi.dev/openapi-ts/get-started>
|
|
256
|
+
- Hono — portable web-standard router: <https://hono.dev/docs/>
|
|
257
|
+
- Elysia — TS-first DX & typed context: <https://elysiajs.com/at-glance.html>
|
|
258
|
+
- Fastify — production Node web framework: <https://fastify.dev/docs/latest/Reference/>
|
|
259
|
+
- pnpm — strict, secure, content-addressable package manager: <https://pnpm.io/motivation>
|
|
260
|
+
- Standard Schema — universal validator interface: <https://github.com/standard-schema/standard-schema>
|
|
261
|
+
- RFC 9457 — Problem Details for HTTP APIs: <https://www.rfc-editor.org/rfc/rfc9457>
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Status & roadmap
|
|
266
|
+
|
|
267
|
+
**Implemented (v0.1):**
|
|
268
|
+
|
|
269
|
+
- [x] Trie router with static fast path + 405 with `Allow` + traversal guard
|
|
270
|
+
- [x] Contract-first `app.route()`, groups, encapsulated plugins, decorators
|
|
271
|
+
- [x] Standard Schema validation (Zod 4 / Valibot / ArkType / TypeBox)
|
|
272
|
+
- [x] Problem+json error model with prod-mode redaction
|
|
273
|
+
- [x] OpenAPI 3.1 generator (built-in)
|
|
274
|
+
- [x] In-process test client + contract-test runner
|
|
275
|
+
- [x] In-process typed client factory + Hey API codegen integration (`pnpm gen`)
|
|
276
|
+
- [x] Node / Bun / Deno / Cloudflare / Vercel adapters
|
|
277
|
+
- [x] Security: body limits, content-type allowlist, prototype-pollution-safe JSON, path-traversal rejection, request timeout, header injection guards
|
|
278
|
+
- [x] Security middleware: `secureHeaders` / `cors` / `rateLimit` / `requestId` / `bearerAuth` / `timing` / `timingSafeEqual`
|
|
279
|
+
- [x] Pluggable structured logger + request id propagation
|
|
280
|
+
- [x] Graceful shutdown
|
|
281
|
+
- [x] Mock mode
|
|
282
|
+
- [x] Scalar + Swagger UI handlers
|
|
283
|
+
- [x] **pnpm-first distribution with hardened `.npmrc`**
|
|
284
|
+
|
|
285
|
+
**Next:**
|
|
286
|
+
|
|
287
|
+
- [ ] WebSocket primitives + adapter coverage
|
|
288
|
+
- [ ] Streaming response helpers (SSE, NDJSON)
|
|
289
|
+
- [ ] CSRF helper
|
|
290
|
+
- [ ] CLI: route inspector, schema inspector, dead-route detector
|
|
291
|
+
- [ ] OpenTelemetry tracing hook
|
|
292
|
+
- [ ] HTTP/2 + HTTP/3 adapters
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
MIT
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bun adapter — `Bun.serve` already speaks web-standard fetch,
|
|
3
|
+
* so this is the smallest possible wrapper.
|
|
4
|
+
*/
|
|
5
|
+
import type { App } from "../app.js";
|
|
6
|
+
export interface BunServeOptions {
|
|
7
|
+
port?: number;
|
|
8
|
+
hostname?: string;
|
|
9
|
+
/** Maximum request body bytes (Bun-level cap). Default: 16 MiB. */
|
|
10
|
+
maxRequestBodySize?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function serve(app: App, opts?: BunServeOptions): {
|
|
13
|
+
stop: () => Promise<void>;
|
|
14
|
+
port: number;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=bun.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../../src/adapters/bun.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,GAAE,eAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA0BvG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function serve(app, opts = {}) {
|
|
2
|
+
const Bun = globalThis.Bun;
|
|
3
|
+
if (!Bun?.serve)
|
|
4
|
+
throw new Error("Bun runtime not detected");
|
|
5
|
+
const server = Bun.serve({
|
|
6
|
+
port: opts.port ?? 3000,
|
|
7
|
+
hostname: opts.hostname ?? "0.0.0.0",
|
|
8
|
+
maxRequestBodySize: opts.maxRequestBodySize ?? 16 * 1024 * 1024,
|
|
9
|
+
fetch: (req) => app.fetch(req),
|
|
10
|
+
error: (err) => new Response(JSON.stringify({
|
|
11
|
+
type: "https://daloyjs.dev/errors/internal",
|
|
12
|
+
title: "Internal Server Error",
|
|
13
|
+
status: 500,
|
|
14
|
+
detail: err.message,
|
|
15
|
+
}), { status: 500, headers: { "content-type": "application/problem+json" } }),
|
|
16
|
+
});
|
|
17
|
+
return {
|
|
18
|
+
port: server.port,
|
|
19
|
+
stop: async () => {
|
|
20
|
+
await app.shutdown();
|
|
21
|
+
server.stop(true);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=bun.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun.js","sourceRoot":"","sources":["../../src/adapters/bun.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,KAAK,CAAC,GAAQ,EAAE,OAAwB,EAAE;IACxD,MAAM,GAAG,GAAI,UAAkB,CAAC,GAAG,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS;QACpC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI;QAC/D,KAAK,EAAE,CAAC,GAAY,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;QACvC,KAAK,EAAE,CAAC,GAAU,EAAE,EAAE,CACpB,IAAI,QAAQ,CACV,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,qCAAqC;YAC3C,KAAK,EAAE,uBAAuB;YAC9B,MAAM,EAAE,GAAG;YACX,MAAM,EAAE,GAAG,CAAC,OAAO;SACpB,CAAC,EACF,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,EAAE,CACzE;KACJ,CAAC,CAAC;IACH,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Workers / generic fetch handler adapter.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* export default toFetchHandler(app);
|
|
6
|
+
*/
|
|
7
|
+
import type { App } from "../app.js";
|
|
8
|
+
export declare function toFetchHandler(app: App): {
|
|
9
|
+
fetch: (req: Request, env?: unknown, ctx?: unknown) => Promise<Response>;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../src/adapters/cloudflare.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAErC,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG;IAAE,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CAAE,CAIrH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../src/adapters/cloudflare.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,cAAc,CAAC,GAAQ;IACrC,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;KAC/B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deno adapter — `Deno.serve` is web-standard fetch.
|
|
3
|
+
*/
|
|
4
|
+
import type { App } from "../app.js";
|
|
5
|
+
export interface DenoServeOptions {
|
|
6
|
+
port?: number;
|
|
7
|
+
hostname?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function serve(app: App, opts?: DenoServeOptions): {
|
|
10
|
+
shutdown: () => Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=deno.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deno.d.ts","sourceRoot":"","sources":["../../src/adapters/deno.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,GAAE,gBAAqB,GAAG;IAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAa9F"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function serve(app, opts = {}) {
|
|
2
|
+
const D = globalThis.Deno;
|
|
3
|
+
if (!D?.serve)
|
|
4
|
+
throw new Error("Deno runtime not detected");
|
|
5
|
+
const server = D.serve({ port: opts.port ?? 3000, hostname: opts.hostname ?? "0.0.0.0" }, (req) => app.fetch(req));
|
|
6
|
+
return {
|
|
7
|
+
shutdown: async () => {
|
|
8
|
+
await app.shutdown();
|
|
9
|
+
await server.shutdown?.();
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=deno.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deno.js","sourceRoot":"","sources":["../../src/adapters/deno.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,KAAK,CAAC,GAAQ,EAAE,OAAyB,EAAE;IACzD,MAAM,CAAC,GAAI,UAAkB,CAAC,IAAI,CAAC;IACnC,IAAI,CAAC,CAAC,EAAE,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CACpB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS,EAAE,EACjE,CAAC,GAAY,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CACjC,CAAC;IACF,OAAO;QACL,QAAQ,EAAE,KAAK,IAAI,EAAE;YACnB,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node adapter: translates IncomingMessage/ServerResponse to web-standard
|
|
3
|
+
* Request/Response. Includes graceful shutdown wired to SIGTERM/SIGINT.
|
|
4
|
+
*/
|
|
5
|
+
import { type Server } from "node:http";
|
|
6
|
+
import type { App } from "../app.js";
|
|
7
|
+
export interface NodeServerOptions {
|
|
8
|
+
port?: number;
|
|
9
|
+
hostname?: string;
|
|
10
|
+
/** Connection-level timeout in ms. Default: 30000. */
|
|
11
|
+
connectionTimeoutMs?: number;
|
|
12
|
+
/** Drain timeout for graceful shutdown. Default: 10000. */
|
|
13
|
+
shutdownTimeoutMs?: number;
|
|
14
|
+
/** Listen for SIGTERM/SIGINT and shut down. Default: true. */
|
|
15
|
+
handleSignals?: boolean;
|
|
16
|
+
/** Maximum HTTP header size bytes (DoS protection). Default: 16 KiB. */
|
|
17
|
+
maxHeaderBytes?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface NodeServerHandle {
|
|
20
|
+
server: Server;
|
|
21
|
+
port: number;
|
|
22
|
+
close(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export declare function serve(app: App, opts?: NodeServerOptions): NodeServerHandle;
|
|
25
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA2D,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEjG,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,GAAE,iBAAsB,GAAG,gBAAgB,CAmD9E"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node adapter: translates IncomingMessage/ServerResponse to web-standard
|
|
3
|
+
* Request/Response. Includes graceful shutdown wired to SIGTERM/SIGINT.
|
|
4
|
+
*/
|
|
5
|
+
import { createServer } from "node:http";
|
|
6
|
+
import { Readable } from "node:stream";
|
|
7
|
+
export function serve(app, opts = {}) {
|
|
8
|
+
const server = createServer({ maxHeaderSize: opts.maxHeaderBytes ?? 16 * 1024 }, async (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const request = await toWebRequest(req);
|
|
11
|
+
const response = await app.fetch(request);
|
|
12
|
+
await sendWebResponse(response, res);
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
if (!res.headersSent) {
|
|
16
|
+
res.statusCode = 500;
|
|
17
|
+
res.setHeader("content-type", "application/problem+json");
|
|
18
|
+
res.end(JSON.stringify({
|
|
19
|
+
type: "https://daloyjs.dev/errors/internal",
|
|
20
|
+
title: "Internal Server Error",
|
|
21
|
+
status: 500,
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
res.destroy(e);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
server.requestTimeout = opts.connectionTimeoutMs ?? 30_000;
|
|
30
|
+
server.headersTimeout = opts.connectionTimeoutMs ?? 30_000;
|
|
31
|
+
server.keepAliveTimeout = 5_000;
|
|
32
|
+
const port = opts.port ?? 3000;
|
|
33
|
+
const hostname = opts.hostname ?? "0.0.0.0";
|
|
34
|
+
server.listen(port, hostname);
|
|
35
|
+
let closed = false;
|
|
36
|
+
const close = async () => {
|
|
37
|
+
if (closed)
|
|
38
|
+
return;
|
|
39
|
+
closed = true;
|
|
40
|
+
await app.shutdown(opts.shutdownTimeoutMs ?? 10_000);
|
|
41
|
+
await new Promise((resolve, reject) => server.close((err) => (err ? reject(err) : resolve())));
|
|
42
|
+
};
|
|
43
|
+
if (opts.handleSignals !== false) {
|
|
44
|
+
const onSignal = (sig) => {
|
|
45
|
+
app.log.info({ sig }, "DaloyJS received signal, shutting down");
|
|
46
|
+
void close().then(() => process.exit(0));
|
|
47
|
+
};
|
|
48
|
+
process.once("SIGTERM", () => onSignal("SIGTERM"));
|
|
49
|
+
process.once("SIGINT", () => onSignal("SIGINT"));
|
|
50
|
+
}
|
|
51
|
+
return { server, port, close };
|
|
52
|
+
}
|
|
53
|
+
async function toWebRequest(req) {
|
|
54
|
+
const host = req.headers.host ?? "localhost";
|
|
55
|
+
const url = `http://${host}${req.url ?? "/"}`;
|
|
56
|
+
const headers = new Headers();
|
|
57
|
+
for (const [k, v] of Object.entries(req.headers)) {
|
|
58
|
+
if (v === undefined)
|
|
59
|
+
continue;
|
|
60
|
+
if (Array.isArray(v))
|
|
61
|
+
headers.set(k, v.join(", "));
|
|
62
|
+
else
|
|
63
|
+
headers.set(k, String(v));
|
|
64
|
+
}
|
|
65
|
+
const method = req.method ?? "GET";
|
|
66
|
+
const init = { method, headers };
|
|
67
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
68
|
+
init.body = Readable.toWeb(req);
|
|
69
|
+
init.duplex = "half";
|
|
70
|
+
}
|
|
71
|
+
return new Request(url, init);
|
|
72
|
+
}
|
|
73
|
+
async function sendWebResponse(res, out) {
|
|
74
|
+
out.statusCode = res.status;
|
|
75
|
+
res.headers.forEach((v, k) => out.setHeader(k, v));
|
|
76
|
+
if (!res.body) {
|
|
77
|
+
out.end();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const reader = res.body.getReader();
|
|
81
|
+
while (true) {
|
|
82
|
+
const { done, value } = await reader.read();
|
|
83
|
+
if (done)
|
|
84
|
+
break;
|
|
85
|
+
if (value)
|
|
86
|
+
out.write(value);
|
|
87
|
+
}
|
|
88
|
+
out.end();
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel Edge / generic Web-standard handler.
|
|
3
|
+
*
|
|
4
|
+
* Usage in Next.js Route Handlers:
|
|
5
|
+
* export const GET = (req) => app.fetch(req);
|
|
6
|
+
* export const POST = (req) => app.fetch(req);
|
|
7
|
+
*
|
|
8
|
+
* Or just:
|
|
9
|
+
* export default toEdgeHandler(app);
|
|
10
|
+
*/
|
|
11
|
+
import type { App } from "../app.js";
|
|
12
|
+
export declare function toEdgeHandler(app: App): (req: Request) => Promise<Response>;
|
|
13
|
+
//# sourceMappingURL=vercel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel.d.ts","sourceRoot":"","sources":["../../src/adapters/vercel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAErC,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,IAC5B,KAAK,OAAO,uBACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel.js","sourceRoot":"","sources":["../../src/adapters/vercel.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,aAAa,CAAC,GAAQ;IACpC,OAAO,CAAC,GAAY,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC1C,CAAC"}
|