create-daloy 0.1.17 → 0.1.19
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 +14 -5
- package/bin/create-daloy.mjs +567 -91
- package/package.json +1 -1
- package/templates/bun-basic/AGENTS.md +29 -8
- package/templates/bun-basic/README.md +1 -1
- package/templates/bun-basic/_agents/skills/daloyjs-best-practices/SKILL.md +233 -0
- package/templates/cloudflare-worker/AGENTS.md +29 -7
- package/templates/cloudflare-worker/README.md +6 -0
- package/templates/cloudflare-worker/_agents/skills/daloyjs-best-practices/SKILL.md +236 -0
- package/templates/deno-basic/AGENTS.md +29 -8
- package/templates/deno-basic/README.md +1 -1
- package/templates/deno-basic/_agents/skills/daloyjs-best-practices/SKILL.md +225 -0
- package/templates/node-basic/AGENTS.md +27 -6
- package/templates/node-basic/README.md +1 -1
- package/templates/node-basic/_agents/skills/daloyjs-best-practices/SKILL.md +298 -0
- package/templates/vercel-edge/AGENTS.md +27 -7
- package/templates/vercel-edge/README.md +11 -0
- package/templates/vercel-edge/_agents/skills/daloyjs-best-practices/SKILL.md +204 -0
- package/templates/bun-basic/SKILL.md +0 -68
- package/templates/cloudflare-worker/SKILL.md +0 -68
- package/templates/deno-basic/SKILL.md +0 -71
- package/templates/node-basic/SKILL.md +0 -70
- package/templates/vercel-edge/SKILL.md +0 -64
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# SKILL.md — DaloyJS best practices (Vercel Edge)
|
|
2
|
+
|
|
3
|
+
Operational guidance and best practices for AI coding agents working in this
|
|
4
|
+
DaloyJS **Vercel Edge** project. This is the project's **single source of
|
|
5
|
+
truth** for how to add routes, write tests, ship secure defaults, and run
|
|
6
|
+
the quality gates. Read this in full before making non-trivial changes.
|
|
7
|
+
|
|
8
|
+
## When to use this skill
|
|
9
|
+
|
|
10
|
+
Use this skill when you need to:
|
|
11
|
+
|
|
12
|
+
- Add, modify, or remove HTTP routes in this project.
|
|
13
|
+
- Adjust middleware, validation, or error handling.
|
|
14
|
+
- Run tests or typecheck the project.
|
|
15
|
+
- Deploy or troubleshoot the Edge runtime entrypoint.
|
|
16
|
+
- Harden the API (auth, CORS, rate limits, secrets, dependency hygiene).
|
|
17
|
+
|
|
18
|
+
Do **not** use this skill for tasks unrelated to the API itself.
|
|
19
|
+
|
|
20
|
+
## Core principles
|
|
21
|
+
|
|
22
|
+
DaloyJS is a **contract-first** framework. On Vercel Edge, additionally:
|
|
23
|
+
|
|
24
|
+
1. **Stay on the Edge runtime.** Only Web Standards APIs (no `node:`
|
|
25
|
+
modules, no `fs`, no `Buffer`). If a feature requires Node APIs, the
|
|
26
|
+
user must switch to a Node template.
|
|
27
|
+
2. **The route definition is the contract.** Method, path, request
|
|
28
|
+
schemas, and response schemas live in one place (`app.route({...})`).
|
|
29
|
+
3. **Zod schemas validate at every boundary.**
|
|
30
|
+
4. **Preserve literal types.** Return `status: 200 as const`.
|
|
31
|
+
5. **Secure by default.** `requestId()`, `secureHeaders()`, and
|
|
32
|
+
`rateLimit()` are registered before route definitions. Note the
|
|
33
|
+
in-memory rate limiter resets per instance — for high-traffic
|
|
34
|
+
deployments, prefer Vercel's native rate-limiting (e.g.
|
|
35
|
+
`@vercel/edge` + KV) or an external store.
|
|
36
|
+
6. **One catch-all entrypoint.** `api/[...path].ts` owns all routing so
|
|
37
|
+
DaloyJS can generate a unified OpenAPI spec.
|
|
38
|
+
|
|
39
|
+
## Project shape
|
|
40
|
+
|
|
41
|
+
- `api/[...path].ts` — the Edge entrypoint. Builds the `App`, registers
|
|
42
|
+
routes/middleware, and exports `default toEdgeHandler(app)` plus
|
|
43
|
+
`export const config = { runtime: "edge" }`.
|
|
44
|
+
- `vercel.json` — Vercel build/runtime configuration.
|
|
45
|
+
- `tests/` — test files (`*.test.ts`).
|
|
46
|
+
|
|
47
|
+
## Commands cheat-sheet
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pnpm dev # local Vercel dev server on http://localhost:3000
|
|
51
|
+
pnpm typecheck # tsc --noEmit
|
|
52
|
+
pnpm test # run test suite
|
|
53
|
+
pnpm deploy # deploy to Vercel
|
|
54
|
+
pnpm audit # supply-chain audit
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Always run `pnpm typecheck` and `pnpm test` before declaring a task done.
|
|
58
|
+
|
|
59
|
+
## Workflow: add a new route
|
|
60
|
+
|
|
61
|
+
1. **Open `api/[...path].ts`.**
|
|
62
|
+
2. **Design schemas first.** Use `z.object({...}).strict()` for inputs.
|
|
63
|
+
3. **Call `app.route({...})`** with `method`, `path`, `operationId`,
|
|
64
|
+
`tags`, `responses`, `handler` (plus `request` when accepting input).
|
|
65
|
+
4. **Return `{ status, body, headers? }`** with `status: 200 as const`.
|
|
66
|
+
5. **Throw typed errors** (`NotFoundError`, `BadRequestError`, etc.)
|
|
67
|
+
from `@daloyjs/core`.
|
|
68
|
+
6. **Add a test** under `tests/` using in-process `app.request(...)`.
|
|
69
|
+
7. **Run the quality gates**: `pnpm typecheck && pnpm test`.
|
|
70
|
+
|
|
71
|
+
### Example: a typed route
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { z } from "zod";
|
|
75
|
+
import { NotFoundError } from "@daloyjs/core";
|
|
76
|
+
|
|
77
|
+
const Book = z.object({ id: z.string(), title: z.string() }).strict();
|
|
78
|
+
const BookParams = z.object({ id: z.string().min(1) }).strict();
|
|
79
|
+
|
|
80
|
+
app.route({
|
|
81
|
+
method: "GET",
|
|
82
|
+
path: "/books/:id",
|
|
83
|
+
operationId: "getBookById",
|
|
84
|
+
tags: ["Books"],
|
|
85
|
+
request: { params: BookParams },
|
|
86
|
+
responses: {
|
|
87
|
+
200: { description: "Found", body: Book },
|
|
88
|
+
404: { description: "Not found" },
|
|
89
|
+
},
|
|
90
|
+
handler: async ({ params }) => {
|
|
91
|
+
const book = await store.find(params.id);
|
|
92
|
+
if (!book) throw new NotFoundError(`Book ${params.id} not found`);
|
|
93
|
+
return { status: 200 as const, body: book };
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Validation & schema conventions
|
|
99
|
+
|
|
100
|
+
- **Inputs**: use `.strict()` on top-level object schemas.
|
|
101
|
+
- **IDs**: prefer `z.string().min(1)`; use `z.string().uuid()` when
|
|
102
|
+
applicable.
|
|
103
|
+
- **Numbers from query strings**: `z.coerce.number().int().min(...)`.
|
|
104
|
+
- **Optional vs nullable**: differ in OpenAPI output.
|
|
105
|
+
- **Pagination**: standardize on `{ items, nextCursor }` cursor
|
|
106
|
+
pagination.
|
|
107
|
+
- **Discriminated unions**: `z.discriminatedUnion("kind", [...])`.
|
|
108
|
+
|
|
109
|
+
## Error handling
|
|
110
|
+
|
|
111
|
+
- Throw typed errors from `@daloyjs/core` — they serialize to RFC 7807
|
|
112
|
+
problem responses.
|
|
113
|
+
- Add a `responses[code]` entry for every error you throw.
|
|
114
|
+
|
|
115
|
+
## Middleware
|
|
116
|
+
|
|
117
|
+
Register middleware **before** route definitions. Order matters.
|
|
118
|
+
|
|
119
|
+
Keep the secure baseline (`requestId`, `secureHeaders`, `rateLimit`).
|
|
120
|
+
Add CORS only when needed, with an explicit `origin` allowlist.
|
|
121
|
+
|
|
122
|
+
## Testing best practices
|
|
123
|
+
|
|
124
|
+
Tests use in-process `app.request(...)` — no port, no Edge runtime
|
|
125
|
+
needed for unit tests.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { test } from "node:test";
|
|
129
|
+
import assert from "node:assert/strict";
|
|
130
|
+
import handler from "../api/[...path].ts";
|
|
131
|
+
|
|
132
|
+
// Either import the underlying app, or test via the Edge handler's
|
|
133
|
+
// fetch interface by passing a Web Request.
|
|
134
|
+
test("GET /healthz returns ok", async () => {
|
|
135
|
+
const res = await handler(new Request("http://local/healthz"));
|
|
136
|
+
assert.equal(res.status, 200);
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Cover **happy paths and unhappy paths** for every route: valid input,
|
|
141
|
+
validation failures (400), auth failures (401/403), not-found (404),
|
|
142
|
+
conflict (409), rate limiting (429). For external services, inject an
|
|
143
|
+
in-memory fake during tests.
|
|
144
|
+
|
|
145
|
+
Aim for **100% line and function coverage** on the routes you add.
|
|
146
|
+
|
|
147
|
+
## Security best practices
|
|
148
|
+
|
|
149
|
+
- Keep `secureHeaders()`, `requestId()`, and `rateLimit()` enabled. For
|
|
150
|
+
production traffic, back rate-limiting with Vercel KV or another
|
|
151
|
+
shared store so limits apply across instances.
|
|
152
|
+
- Never log secrets — filter `authorization`, `cookie`, etc.
|
|
153
|
+
- Read secrets from `process.env` (available on Edge). Validate via Zod
|
|
154
|
+
at module load.
|
|
155
|
+
- For auth, verify JWT signatures with the Web Crypto API
|
|
156
|
+
(`crypto.subtle`). Never trust the `alg` header from the token.
|
|
157
|
+
- Validate redirects against an allowlist.
|
|
158
|
+
- Set `bodyLimitBytes` and `requestTimeoutMs` on `new App({...})` to
|
|
159
|
+
mitigate DoS.
|
|
160
|
+
- Edge functions have small bundle and CPU limits; be cautious about
|
|
161
|
+
adding heavy dependencies. Inspect bundle size during deploy.
|
|
162
|
+
- Pin Vercel project settings (regions, runtime version) explicitly in
|
|
163
|
+
`vercel.json` rather than relying on dashboard defaults.
|
|
164
|
+
|
|
165
|
+
## Logging & observability
|
|
166
|
+
|
|
167
|
+
- Use `ctx.log` — it carries the request id.
|
|
168
|
+
- `console.log` on Edge shows up in Vercel's runtime logs; the framework
|
|
169
|
+
logger emits structured JSON for log aggregators.
|
|
170
|
+
|
|
171
|
+
## Configuration & secrets
|
|
172
|
+
|
|
173
|
+
- Use Vercel project env vars; mirror required names in `.env.example`.
|
|
174
|
+
- Validate `process.env` via a Zod schema at module load.
|
|
175
|
+
|
|
176
|
+
## Pitfalls and guardrails
|
|
177
|
+
|
|
178
|
+
- The catch-all `api/[...path].ts` must remain a catch-all so DaloyJS
|
|
179
|
+
handles routing. Do not split routes into multiple Vercel API files
|
|
180
|
+
unless the user explicitly asks (it disables shared middleware and a
|
|
181
|
+
unified OpenAPI).
|
|
182
|
+
- Use `toEdgeHandler(app)` from `@daloyjs/core/vercel` — never hand-roll
|
|
183
|
+
a `fetch(req)` adapter.
|
|
184
|
+
- Do not import `@daloyjs/core/node`, `@daloyjs/core/bun`, etc. — only
|
|
185
|
+
`@daloyjs/core` and `@daloyjs/core/vercel`.
|
|
186
|
+
- Avoid Node-only APIs (`Buffer`, `fs`, full `process` API). If a
|
|
187
|
+
feature needs Node, switch to a Node-runtime template.
|
|
188
|
+
- Do not weaken response literal types (`as const`).
|
|
189
|
+
- Do not return errors as `{ status: 4xx, body }`. Throw a typed error.
|
|
190
|
+
- Do not add runtime dependencies without checking the hardened `.npmrc` (installs wait 24h after publish by default).
|
|
191
|
+
|
|
192
|
+
## Process expectations
|
|
193
|
+
|
|
194
|
+
- Every new feature ships with happy-path and unhappy-path tests.
|
|
195
|
+
- Bug fixes include a regression test.
|
|
196
|
+
- `pnpm typecheck` and `pnpm test` must pass before completion.
|
|
197
|
+
- For deploys, ensure the user is logged in via `vercel login`; do not
|
|
198
|
+
authenticate on their behalf.
|
|
199
|
+
- Keep `README.md`, this `SKILL.md`, and `AGENTS.md` consistent.
|
|
200
|
+
|
|
201
|
+
## More
|
|
202
|
+
|
|
203
|
+
- Framework docs: <https://daloyjs.dev/docs>
|
|
204
|
+
- Issues: <https://github.com/daloyjs/daloy/issues>
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# SKILL.md
|
|
2
|
-
|
|
3
|
-
Operational guidance for AI coding agents working in this DaloyJS Bun project.
|
|
4
|
-
|
|
5
|
-
## When to use this skill
|
|
6
|
-
|
|
7
|
-
Use this skill when you need to:
|
|
8
|
-
|
|
9
|
-
- Add, modify, or remove HTTP routes in this project.
|
|
10
|
-
- Regenerate the OpenAPI spec or the typed Hey API SDK in `generated/`.
|
|
11
|
-
- Wire up new middleware, validation, or error handling.
|
|
12
|
-
- Run tests or typecheck the project under Bun.
|
|
13
|
-
|
|
14
|
-
Do **not** use this skill for tasks unrelated to the API itself.
|
|
15
|
-
|
|
16
|
-
## Project shape
|
|
17
|
-
|
|
18
|
-
- `src/build-app.ts` — exports `buildApp()`. All routes and middleware are registered here. **Pure function, no side effects.**
|
|
19
|
-
- `src/index.ts` — calls `buildApp()` and starts the Bun HTTP listener via `@daloyjs/core/bun`.
|
|
20
|
-
- `scripts/dump-openapi.ts` — imports `buildApp()` and writes `generated/openapi.json`.
|
|
21
|
-
- `openapi-ts.config.ts` — Hey API config; reads `generated/openapi.json` and writes `generated/client/`.
|
|
22
|
-
- `tests/` — Bun test files (`*.test.ts`).
|
|
23
|
-
|
|
24
|
-
## Core workflows
|
|
25
|
-
|
|
26
|
-
### Add a new route
|
|
27
|
-
|
|
28
|
-
1. Open `src/build-app.ts`.
|
|
29
|
-
2. Define request/response Zod schemas.
|
|
30
|
-
3. Call `app.route({ method, path, request, response, handler })`. Return `{ status, body }`; preserve literal types (`status: 200 as const`, `ok: true as const`) so codegen sees narrow types.
|
|
31
|
-
4. Add a test under `tests/`.
|
|
32
|
-
5. Regenerate the spec + client: `bun run gen:openapi && bun run gen:client`.
|
|
33
|
-
|
|
34
|
-
### Regenerate the OpenAPI spec and SDK
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
bun run gen:openapi # → generated/openapi.json
|
|
38
|
-
bun run gen:client # → generated/client/
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
If `gen:openapi` fails with a "server already listening" error, you imported `src/index.ts` (or `@daloyjs/core/bun`) from a place that codegen pulls in. Codegen must only touch `buildApp()`.
|
|
42
|
-
|
|
43
|
-
### Run quality gates
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
bun run typecheck
|
|
47
|
-
bun test
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Both must pass before considering a change done.
|
|
51
|
-
|
|
52
|
-
## Decision rules
|
|
53
|
-
|
|
54
|
-
- If the user asks to **change API behavior**, edit `src/build-app.ts`, then regenerate and run `bun test`.
|
|
55
|
-
- If the user asks to **consume the API from a client**, import from `generated/client/` — do not handwrite fetch calls.
|
|
56
|
-
- If the user asks for **new middleware**, register it on `app` inside `buildApp()` before route definitions so it applies globally.
|
|
57
|
-
|
|
58
|
-
## Pitfalls and guardrails
|
|
59
|
-
|
|
60
|
-
- Never import `@daloyjs/core/bun` from `src/build-app.ts` or any script under `scripts/`. That would start an HTTP listener as a side effect of codegen.
|
|
61
|
-
- Do not edit files under `generated/` by hand — they are overwritten by codegen.
|
|
62
|
-
- Keep `secureHeaders()`, `requestId()`, and `rateLimit()` enabled in `buildApp()` unless the user explicitly asks to remove them.
|
|
63
|
-
- Do not weaken response literal types (`as const`); the typed client depends on them.
|
|
64
|
-
|
|
65
|
-
## More
|
|
66
|
-
|
|
67
|
-
- Framework docs: <https://daloyjs.dev/docs>
|
|
68
|
-
- Issues: <https://github.com/daloyjs/daloy/issues>
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# SKILL.md
|
|
2
|
-
|
|
3
|
-
Operational guidance for AI coding agents working in this DaloyJS Cloudflare Workers project.
|
|
4
|
-
|
|
5
|
-
## When to use this skill
|
|
6
|
-
|
|
7
|
-
Use this skill when you need to:
|
|
8
|
-
|
|
9
|
-
- Add, modify, or remove HTTP routes in this Worker.
|
|
10
|
-
- Adjust middleware, validation, or error handling.
|
|
11
|
-
- Change Worker bindings (KV, D1, R2, env vars) in `wrangler.toml`.
|
|
12
|
-
- Run tests/typecheck or deploy the Worker.
|
|
13
|
-
|
|
14
|
-
Do **not** use this skill for tasks unrelated to the API itself.
|
|
15
|
-
|
|
16
|
-
## Project shape
|
|
17
|
-
|
|
18
|
-
- `src/index.ts` — the Worker entrypoint. Builds the `App`, registers routes/middleware, and exports `default { fetch: toFetchHandler(app) }` from `@daloyjs/core/cloudflare`.
|
|
19
|
-
- `wrangler.toml` — Worker configuration (name, compatibility date, bindings, routes).
|
|
20
|
-
|
|
21
|
-
## Core workflows
|
|
22
|
-
|
|
23
|
-
### Add a new route
|
|
24
|
-
|
|
25
|
-
1. Open `src/index.ts`.
|
|
26
|
-
2. Define request/response Zod schemas.
|
|
27
|
-
3. Call `app.route({ method, path, request, response, handler })`. Return `{ status, body }`; preserve literal types (`status: 200 as const`, `ok: true as const`) so codegen sees narrow types.
|
|
28
|
-
|
|
29
|
-
### Run quality gates
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
pnpm typecheck
|
|
33
|
-
pnpm test
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Both must pass before considering a change done.
|
|
37
|
-
|
|
38
|
-
### Deploy
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
pnpm deploy
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Wrangler will use the account/zone config from `wrangler.toml`. If the user has not run `wrangler login`, ask them to do so first — do not attempt to authenticate on their behalf.
|
|
45
|
-
|
|
46
|
-
### Add a binding
|
|
47
|
-
|
|
48
|
-
1. Add the binding (`[[kv_namespaces]]`, `[[d1_databases]]`, `[vars]`, etc.) to `wrangler.toml`.
|
|
49
|
-
2. Type the binding in the `Env` interface inside `src/index.ts` so handlers can read it from the second `fetch` argument.
|
|
50
|
-
3. Pass `env` into `buildApp(env)` if your factory needs it; never read bindings via globals.
|
|
51
|
-
|
|
52
|
-
## Decision rules
|
|
53
|
-
|
|
54
|
-
- Use `toFetchHandler(app)` from `@daloyjs/core/cloudflare` — never hand-roll a `fetch(req, env, ctx)` adapter.
|
|
55
|
-
- Stay on the Workers runtime: only Web Standards APIs and Cloudflare-specific bindings. No `node:` modules unless `nodejs_compat` is enabled in `wrangler.toml` and the user explicitly opts in.
|
|
56
|
-
- Long-running work belongs in `ctx.waitUntil(...)`, not blocking the response.
|
|
57
|
-
|
|
58
|
-
## Pitfalls and guardrails
|
|
59
|
-
|
|
60
|
-
- Do not import `@daloyjs/core/node`, `@daloyjs/core/bun`, etc. — only `@daloyjs/core` and `@daloyjs/core/cloudflare`.
|
|
61
|
-
- Do not weaken response literal types (`as const`).
|
|
62
|
-
- Keep `secureHeaders()`, `requestId()`, and `rateLimit()` enabled unless the user explicitly asks to remove them. (For `rateLimit`, prefer Cloudflare's native rate-limit binding for high traffic; the in-memory limiter resets per isolate.)
|
|
63
|
-
- Workers have CPU and bundle-size limits — be cautious about adding heavy dependencies.
|
|
64
|
-
|
|
65
|
-
## More
|
|
66
|
-
|
|
67
|
-
- Framework docs: <https://daloyjs.dev/docs>
|
|
68
|
-
- Issues: <https://github.com/daloyjs/daloy/issues>
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# SKILL.md
|
|
2
|
-
|
|
3
|
-
Operational guidance for AI coding agents working in this DaloyJS Deno project.
|
|
4
|
-
|
|
5
|
-
## When to use this skill
|
|
6
|
-
|
|
7
|
-
Use this skill when you need to:
|
|
8
|
-
|
|
9
|
-
- Add, modify, or remove HTTP routes in this project.
|
|
10
|
-
- Regenerate the OpenAPI spec.
|
|
11
|
-
- Wire up new middleware, validation, or error handling.
|
|
12
|
-
- Run tests or typecheck the project under Deno.
|
|
13
|
-
|
|
14
|
-
Do **not** use this skill for tasks unrelated to the API itself.
|
|
15
|
-
|
|
16
|
-
## Project shape
|
|
17
|
-
|
|
18
|
-
- `src/build-app.ts` — exports `buildApp()`. All routes and middleware are registered here. **Pure function, no side effects.**
|
|
19
|
-
- `src/main.ts` — calls `buildApp()` and starts the Deno HTTP listener via `@daloyjs/core/deno`.
|
|
20
|
-
- `scripts/dump-openapi.ts` — imports `buildApp()` and writes `generated/openapi.json`.
|
|
21
|
-
- `deno.json` — tasks, import map, and `npm:` specifiers (no `package.json`).
|
|
22
|
-
- `tests/` — Deno test files (`*.test.ts`).
|
|
23
|
-
|
|
24
|
-
## Core workflows
|
|
25
|
-
|
|
26
|
-
### Add a new route
|
|
27
|
-
|
|
28
|
-
1. Open `src/build-app.ts`.
|
|
29
|
-
2. Define request/response Zod schemas.
|
|
30
|
-
3. Call `app.route({ method, path, request, response, handler })`. Return `{ status, body }`; preserve literal types (`status: 200 as const`, `ok: true as const`) so codegen sees narrow types.
|
|
31
|
-
4. Add a test under `tests/`.
|
|
32
|
-
5. Regenerate: `deno task gen:openapi`.
|
|
33
|
-
|
|
34
|
-
### Regenerate the OpenAPI spec
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
deno task gen:openapi # → generated/openapi.json
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
To produce the typed client, run Hey API via Node tooling against the generated spec — Hey API does not yet ship a Deno entrypoint:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
npx @hey-api/openapi-ts -i generated/openapi.json -o generated/client
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Run quality gates
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
deno task typecheck
|
|
50
|
-
deno task test
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Both must pass before considering a change done.
|
|
54
|
-
|
|
55
|
-
## Decision rules
|
|
56
|
-
|
|
57
|
-
- Use `deno task ...`, not `npm`/`pnpm`. There is no `package.json` here.
|
|
58
|
-
- Permissions for `dev` are intentionally narrow: `--allow-net --allow-env --allow-read`. If a change requires more permissions, add them explicitly to the relevant task in `deno.json` and call it out to the user.
|
|
59
|
-
- If you need a new dependency, add it to `imports` in `deno.json` using a `npm:` or `jsr:` specifier; do not introduce a `package.json`.
|
|
60
|
-
|
|
61
|
-
## Pitfalls and guardrails
|
|
62
|
-
|
|
63
|
-
- Never import `@daloyjs/core/deno` from `src/build-app.ts` or any script under `scripts/`. That would start an HTTP listener as a side effect of codegen.
|
|
64
|
-
- Do not edit files under `generated/` by hand.
|
|
65
|
-
- Keep `secureHeaders()`, `requestId()`, and `rateLimit()` enabled in `buildApp()` unless the user explicitly asks to remove them.
|
|
66
|
-
- Do not weaken response literal types (`as const`).
|
|
67
|
-
|
|
68
|
-
## More
|
|
69
|
-
|
|
70
|
-
- Framework docs: <https://daloyjs.dev/docs>
|
|
71
|
-
- Issues: <https://github.com/daloyjs/daloy/issues>
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# SKILL.md
|
|
2
|
-
|
|
3
|
-
Operational guidance for AI coding agents working in this DaloyJS Node.js project.
|
|
4
|
-
|
|
5
|
-
## When to use this skill
|
|
6
|
-
|
|
7
|
-
Use this skill when you need to:
|
|
8
|
-
|
|
9
|
-
- Add, modify, or remove HTTP routes in this project.
|
|
10
|
-
- Regenerate the OpenAPI spec or the typed Hey API SDK in `generated/`.
|
|
11
|
-
- Wire up new middleware, validation, or error handling.
|
|
12
|
-
- Run tests, typecheck, or build the project.
|
|
13
|
-
|
|
14
|
-
Do **not** use this skill for tasks unrelated to the API itself (e.g. infra, CI workflows, unrelated docs sites).
|
|
15
|
-
|
|
16
|
-
## Project shape
|
|
17
|
-
|
|
18
|
-
- `src/build-app.ts` — exports `buildApp()`. All routes and middleware are registered here. **Pure function, no side effects.**
|
|
19
|
-
- `src/index.ts` — calls `buildApp()` and starts the Node HTTP listener via `@daloyjs/core/node`.
|
|
20
|
-
- `scripts/dump-openapi.ts` — imports `buildApp()` and writes `generated/openapi.json`.
|
|
21
|
-
- `openapi-ts.config.ts` — Hey API config; reads `generated/openapi.json` and writes `generated/client/`.
|
|
22
|
-
- `tests/` — Node test runner files (`*.test.ts`).
|
|
23
|
-
|
|
24
|
-
## Core workflows
|
|
25
|
-
|
|
26
|
-
### Add a new route
|
|
27
|
-
|
|
28
|
-
1. Open `src/build-app.ts`.
|
|
29
|
-
2. Define request/response Zod schemas inline or in a sibling module.
|
|
30
|
-
3. Call `app.route({ method, path, request, response, handler })`. Always return `{ status, body }`; preserve literal types (`status: 200 as const`, `ok: true as const`) so codegen sees narrow types.
|
|
31
|
-
4. Add a test under `tests/`.
|
|
32
|
-
5. Regenerate the spec + client: `pnpm gen`.
|
|
33
|
-
|
|
34
|
-
### Regenerate the OpenAPI spec and SDK
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
pnpm gen
|
|
38
|
-
# = pnpm gen:openapi → generated/openapi.json
|
|
39
|
-
# pnpm gen:client → generated/client/
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
If `pnpm gen:openapi` fails with a "server already listening" error, you imported `src/index.ts` (or `@daloyjs/core/node`) from somewhere it shouldn't be. Codegen must only touch `buildApp()`.
|
|
43
|
-
|
|
44
|
-
### Run quality gates
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
pnpm typecheck
|
|
48
|
-
pnpm test
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Both must pass before considering a change done.
|
|
52
|
-
|
|
53
|
-
## Decision rules
|
|
54
|
-
|
|
55
|
-
- If the user asks to **change API behavior**, edit `src/build-app.ts`, then run `pnpm gen` and `pnpm test`.
|
|
56
|
-
- If the user asks to **consume the API from a client**, import from `generated/client/` — do not handwrite fetch calls.
|
|
57
|
-
- If the user asks for **new middleware**, register it on `app` inside `buildApp()` before route definitions so it applies globally.
|
|
58
|
-
|
|
59
|
-
## Pitfalls and guardrails
|
|
60
|
-
|
|
61
|
-
- Never import `@daloyjs/core/node` (or any adapter that boots a server) from `src/build-app.ts` or any script under `scripts/`. That would start an HTTP listener as a side effect of codegen.
|
|
62
|
-
- Do not edit files under `generated/` by hand — they are overwritten by `pnpm gen`.
|
|
63
|
-
- Keep `secureHeaders()`, `requestId()`, and `rateLimit()` enabled in `buildApp()` unless the user explicitly asks to remove them; they are the project's secure defaults.
|
|
64
|
-
- Do not weaken response literal types (`as const`); the typed client depends on them.
|
|
65
|
-
- Do not add runtime dependencies without checking the hardened `.npmrc` (installs wait 24h after publish by default).
|
|
66
|
-
|
|
67
|
-
## More
|
|
68
|
-
|
|
69
|
-
- Framework docs: <https://daloyjs.dev/docs>
|
|
70
|
-
- Issues: <https://github.com/daloyjs/daloy/issues>
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# SKILL.md
|
|
2
|
-
|
|
3
|
-
Operational guidance for AI coding agents working in this DaloyJS Vercel Edge project.
|
|
4
|
-
|
|
5
|
-
## When to use this skill
|
|
6
|
-
|
|
7
|
-
Use this skill when you need to:
|
|
8
|
-
|
|
9
|
-
- Add, modify, or remove HTTP routes in this project.
|
|
10
|
-
- Adjust middleware, validation, or error handling.
|
|
11
|
-
- Run tests or typecheck the project.
|
|
12
|
-
- Deploy or troubleshoot the Edge runtime entrypoint.
|
|
13
|
-
|
|
14
|
-
Do **not** use this skill for tasks unrelated to the API itself.
|
|
15
|
-
|
|
16
|
-
## Project shape
|
|
17
|
-
|
|
18
|
-
- `api/[...path].ts` — the Edge entrypoint. Builds the `App`, registers routes/middleware, and exports `default toEdgeHandler(app)` plus `export const config = { runtime: "edge" }`.
|
|
19
|
-
- `vercel.json` — Vercel build/runtime configuration.
|
|
20
|
-
- `tests/` — test files (`*.test.ts`).
|
|
21
|
-
|
|
22
|
-
## Core workflows
|
|
23
|
-
|
|
24
|
-
### Add a new route
|
|
25
|
-
|
|
26
|
-
1. Open `api/[...path].ts`.
|
|
27
|
-
2. Define request/response Zod schemas.
|
|
28
|
-
3. Call `app.route({ method, path, request, response, handler })`. Return `{ status, body }`; preserve literal types (`status: 200 as const`, `ok: true as const`) so codegen sees narrow types.
|
|
29
|
-
4. Add a test under `tests/`.
|
|
30
|
-
|
|
31
|
-
### Run quality gates
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
pnpm typecheck
|
|
35
|
-
pnpm test
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Both must pass before considering a change done.
|
|
39
|
-
|
|
40
|
-
### Deploy
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
pnpm deploy
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
The `/docs` and `/openapi.json` routes registered in `api/[...path].ts` will be live at the deployed URL.
|
|
47
|
-
|
|
48
|
-
## Decision rules
|
|
49
|
-
|
|
50
|
-
- The catch-all `api/[...path].ts` must remain a catch-all so DaloyJS handles routing. Do not split routes into multiple Vercel API files unless the user explicitly asks for that pattern (it disables shared middleware and unified OpenAPI).
|
|
51
|
-
- Stay on the Edge runtime: only use APIs available in Web Standards (no `node:` modules, no `fs`, no `Buffer` reliance). If a feature requires Node, the user must choose a Node-runtime template instead.
|
|
52
|
-
- Use `toEdgeHandler(app)` from `@daloyjs/core/vercel` — never hand-roll a `fetch(req)` adapter.
|
|
53
|
-
|
|
54
|
-
## Pitfalls and guardrails
|
|
55
|
-
|
|
56
|
-
- Do not import `@daloyjs/core/node`, `@daloyjs/core/bun`, etc. — only `@daloyjs/core` and `@daloyjs/core/vercel`.
|
|
57
|
-
- Do not weaken response literal types (`as const`).
|
|
58
|
-
- Keep `secureHeaders()`, `requestId()`, and `rateLimit()` enabled unless the user explicitly asks to remove them.
|
|
59
|
-
- Edge functions have small bundle and CPU limits; be cautious about adding heavy dependencies.
|
|
60
|
-
|
|
61
|
-
## More
|
|
62
|
-
|
|
63
|
-
- Framework docs: <https://daloyjs.dev/docs>
|
|
64
|
-
- Issues: <https://github.com/daloyjs/daloy/issues>
|