create-daloy 0.1.15 → 0.1.17
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 +9 -0
- package/bin/create-daloy.mjs +28 -8
- package/package.json +1 -1
- package/templates/bun-basic/AGENTS.md +20 -0
- package/templates/bun-basic/SKILL.md +68 -0
- package/templates/bun-basic/package.json +1 -1
- package/templates/cloudflare-worker/AGENTS.md +20 -0
- package/templates/cloudflare-worker/SKILL.md +68 -0
- package/templates/cloudflare-worker/package.json +2 -2
- package/templates/deno-basic/AGENTS.md +22 -0
- package/templates/deno-basic/SKILL.md +71 -0
- package/templates/deno-basic/deno.json +2 -2
- package/templates/node-basic/AGENTS.md +22 -0
- package/templates/node-basic/SKILL.md +70 -0
- package/templates/node-basic/package.json +5 -5
- package/templates/vercel-edge/AGENTS.md +20 -0
- package/templates/vercel-edge/SKILL.md +64 -0
- package/templates/vercel-edge/package.json +2 -2
package/README.md
CHANGED
|
@@ -118,3 +118,12 @@ re-run with `--minimal`, or delete the marked blocks by hand later.
|
|
|
118
118
|
- pnpm-specific `.npmrc` hardening is kept only when you choose `pnpm`; other package managers get a clean project without unsupported config warnings.
|
|
119
119
|
- pnpm projects ship with `ignore-scripts=true`, `minimum-release-age=1440`, `verify-store-integrity=true`, `prefer-frozen-lockfile=true`, and `strict-peer-dependencies=true` by default.
|
|
120
120
|
- The CLI never executes template scripts and never makes network calls beyond the package manager you select.
|
|
121
|
+
|
|
122
|
+
## AI agent helper files
|
|
123
|
+
|
|
124
|
+
Every scaffolded project ships with two files at the repo root that help AI coding agents (Copilot, Claude Code, Cursor, Codex, etc.) understand and work in your project:
|
|
125
|
+
|
|
126
|
+
- `AGENTS.md` — a small, top-of-context file (per the open [AGENTS.md](https://agents.md) convention): one-line project description, package manager / runtime, and the few commands an agent needs. It points to `SKILL.md` for the rest.
|
|
127
|
+
- `SKILL.md` — operational guidance for AI agents: when to use the skill, project structure, core workflows (adding routes, regenerating the OpenAPI spec and client), decision rules, and pitfalls to avoid.
|
|
128
|
+
|
|
129
|
+
Both files are tailored to the chosen template (Node, Bun, Deno, Vercel Edge, or Cloudflare Workers), and Node-style templates rewrite their commands to match your selected package manager. They follow the "instruction budget" advice — small root file, progressive disclosure for the rest — so they don't waste agent tokens. Edit or delete them freely; the framework does not depend on them at runtime.
|
package/bin/create-daloy.mjs
CHANGED
|
@@ -221,16 +221,33 @@ async function patchPackageJson(dir, projectName, packageManager) {
|
|
|
221
221
|
await writeFile(file, JSON.stringify(json, null, 2) + "\n", "utf8");
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
async function
|
|
224
|
+
async function patchTemplateTextFiles(dir, packageManager) {
|
|
225
225
|
if (packageManager === "pnpm") return;
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
226
|
+
for (const fileName of ["README.md", "AGENTS.md", "SKILL.md"]) {
|
|
227
|
+
const file = path.join(dir, fileName);
|
|
228
|
+
if (!existsSync(file)) continue;
|
|
229
|
+
const raw = await readFile(file, "utf8");
|
|
230
|
+
const next = rewritePackageManagerText(raw, packageManager);
|
|
231
|
+
if (next !== raw) await writeFile(file, next, "utf8");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function rewritePackageManagerText(raw, packageManager) {
|
|
236
|
+
return raw
|
|
237
|
+
.replace(
|
|
238
|
+
"Package manager: pnpm (use `pnpm` unless the project's `package.json` was rewritten for npm/yarn/bun).",
|
|
239
|
+
`Package manager: ${packageManager}.`,
|
|
240
|
+
)
|
|
230
241
|
.replace(/\bpnpm install\b/g, `${packageManager} install`)
|
|
242
|
+
.replace(/\bpnpm gen:openapi\b/g, `${packageManager} run gen:openapi`)
|
|
243
|
+
.replace(/\bpnpm gen:client\b/g, `${packageManager} run gen:client`)
|
|
244
|
+
.replace(/\bpnpm typecheck\b/g, `${packageManager} run typecheck`)
|
|
245
|
+
.replace(/\bpnpm build\b/g, `${packageManager} run build`)
|
|
246
|
+
.replace(/\bpnpm deploy\b/g, `${packageManager} run deploy`)
|
|
231
247
|
.replace(/\bpnpm dev\b/g, `${packageManager} run dev`)
|
|
232
248
|
.replace(/\bpnpm gen\b/g, `${packageManager} run gen`)
|
|
233
|
-
.replace(/\bpnpm
|
|
249
|
+
.replace(/\bpnpm test\b/g, `${packageManager} test`)
|
|
250
|
+
.replace(/\bpnpm audit\b/g, `${packageManager} audit`)
|
|
234
251
|
.replace(
|
|
235
252
|
"- Hardened `.npmrc` for safer installs.",
|
|
236
253
|
`- Package-manager scripts adjusted for ${packageManager}.`,
|
|
@@ -238,8 +255,11 @@ async function patchReadme(dir, packageManager) {
|
|
|
238
255
|
.replace(
|
|
239
256
|
"- Hey API codegen wired to `pnpm gen`.",
|
|
240
257
|
`- Hey API codegen wired to \`${packageManager} run gen\`.`,
|
|
258
|
+
)
|
|
259
|
+
.replace(
|
|
260
|
+
"- Do not add runtime dependencies without checking the hardened `.npmrc` (installs wait 24h after publish by default).",
|
|
261
|
+
`- Add runtime dependencies with \`${packageManager} install <package>\` and rerun the quality gates after dependency changes.`,
|
|
241
262
|
);
|
|
242
|
-
await writeFile(file, next, "utf8");
|
|
243
263
|
}
|
|
244
264
|
|
|
245
265
|
/**
|
|
@@ -545,7 +565,7 @@ async function main() {
|
|
|
545
565
|
if (!skipPackageManager) {
|
|
546
566
|
await patchPackageJson(targetDir, projectName, packageManager);
|
|
547
567
|
logStep("Package metadata written", projectName);
|
|
548
|
-
await
|
|
568
|
+
await patchTemplateTextFiles(targetDir, packageManager);
|
|
549
569
|
await normalizePackageManagerFiles(targetDir, packageManager);
|
|
550
570
|
if (packageManager !== "pnpm") {
|
|
551
571
|
logStep("Package-manager config normalized", packageManager);
|
package/package.json
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
A [DaloyJS](https://daloyjs.dev) REST API for the [Bun](https://bun.sh) runtime. Contract-first: routes are defined with Zod schemas and OpenAPI 3.1 is generated from them.
|
|
4
|
+
|
|
5
|
+
- Package manager / runtime: Bun.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
- `bun run dev` — hot-reload server on http://localhost:3000
|
|
10
|
+
- `bun run typecheck` — `tsc --noEmit`
|
|
11
|
+
- `bun test` — run tests with Bun's native test runner
|
|
12
|
+
- `bun run gen:openapi` then `bun run gen:client` — regenerate `generated/openapi.json` + the Hey API client
|
|
13
|
+
|
|
14
|
+
## Structure hints
|
|
15
|
+
|
|
16
|
+
- Route + middleware wiring lives in `src/build-app.ts` (`buildApp()` factory; pure, no side effects).
|
|
17
|
+
- The HTTP listener is started in `src/index.ts` via `@daloyjs/core/bun`.
|
|
18
|
+
- Codegen reads from `buildApp()` only — never import `src/index.ts` from scripts.
|
|
19
|
+
|
|
20
|
+
For workflows (adding routes, regenerating the SDK, common pitfalls) see [SKILL.md](SKILL.md).
|
|
@@ -0,0 +1,68 @@
|
|
|
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>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
A [DaloyJS](https://daloyjs.dev) REST API deployed to **Cloudflare Workers**. Contract-first: routes are defined with Zod schemas and OpenAPI 3.1 is generated from them.
|
|
4
|
+
|
|
5
|
+
- Package manager: pnpm (use `pnpm` unless the project's `package.json` was rewritten for npm/yarn/bun).
|
|
6
|
+
- Runtime: Cloudflare Workers (Web Standard `Request`/`Response`).
|
|
7
|
+
|
|
8
|
+
## Commands
|
|
9
|
+
|
|
10
|
+
- `pnpm dev` — `wrangler dev` on http://localhost:8787
|
|
11
|
+
- `pnpm typecheck`
|
|
12
|
+
- `pnpm test`
|
|
13
|
+
- `pnpm deploy` — `wrangler deploy`
|
|
14
|
+
|
|
15
|
+
## Structure hints
|
|
16
|
+
|
|
17
|
+
- Worker entrypoint: `src/index.ts`. Builds the `App`, registers routes/middleware, and exports `default { fetch: toFetchHandler(app) }` from `@daloyjs/core/cloudflare`.
|
|
18
|
+
- `wrangler.toml` controls runtime config, bindings, and deploy targets.
|
|
19
|
+
|
|
20
|
+
For workflows (adding routes, deploy, common pitfalls) see [SKILL.md](SKILL.md).
|
|
@@ -0,0 +1,68 @@
|
|
|
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>
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
"dev": "wrangler dev",
|
|
8
8
|
"deploy": "wrangler deploy",
|
|
9
9
|
"typecheck": "tsc --noEmit",
|
|
10
|
-
"test": "node --import tsx --test tests/**/*.test.ts"
|
|
10
|
+
"test": "node --import tsx/esm --test tests/**/*.test.ts"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@daloyjs/core": "^0.
|
|
13
|
+
"@daloyjs/core": "^0.5.0",
|
|
14
14
|
"zod": "^4.4.3"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
A [DaloyJS](https://daloyjs.dev) REST API for the [Deno](https://deno.com) runtime. Contract-first: routes are defined with Zod schemas and OpenAPI 3.1 is generated from them.
|
|
4
|
+
|
|
5
|
+
- Runtime: Deno (no Node package manager). Dependencies are loaded via `npm:` specifiers in `deno.json`.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
- `deno task dev` — watch-mode server on http://localhost:3000
|
|
10
|
+
- `deno task typecheck`
|
|
11
|
+
- `deno task test`
|
|
12
|
+
- `deno task gen:openapi` — write `generated/openapi.json`
|
|
13
|
+
|
|
14
|
+
The typed Hey API SDK is generated outside Deno (Hey API has no Deno entrypoint yet). Run `npx @hey-api/openapi-ts` against `generated/openapi.json` if you need the client.
|
|
15
|
+
|
|
16
|
+
## Structure hints
|
|
17
|
+
|
|
18
|
+
- Route + middleware wiring lives in `src/build-app.ts` (`buildApp()` factory; pure, no side effects).
|
|
19
|
+
- The HTTP listener is started in `src/main.ts` via `@daloyjs/core/deno`.
|
|
20
|
+
- Codegen reads from `buildApp()` only — never import `src/main.ts` from scripts.
|
|
21
|
+
|
|
22
|
+
For workflows (adding routes, regenerating the spec, common pitfalls) see [SKILL.md](SKILL.md).
|
|
@@ -0,0 +1,71 @@
|
|
|
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>
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"gen:openapi": "deno run --allow-net --allow-env --allow-read --allow-write scripts/dump-openapi.ts"
|
|
9
9
|
},
|
|
10
10
|
"imports": {
|
|
11
|
-
"@daloyjs/core": "npm:@daloyjs/core@^0.
|
|
12
|
-
"@daloyjs/core/": "npm:@daloyjs/core@^0.
|
|
11
|
+
"@daloyjs/core": "npm:@daloyjs/core@^0.5.0",
|
|
12
|
+
"@daloyjs/core/": "npm:@daloyjs/core@^0.5.0/",
|
|
13
13
|
"zod": "npm:zod@^4.4.3"
|
|
14
14
|
},
|
|
15
15
|
"compilerOptions": {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
A [DaloyJS](https://daloyjs.dev) Node.js REST API. Contract-first: routes are defined with Zod schemas and OpenAPI 3.1 is generated from them.
|
|
4
|
+
|
|
5
|
+
- Package manager: pnpm (use `pnpm` unless the project's `package.json` was rewritten for npm/yarn/bun).
|
|
6
|
+
- Runtime: Node.js >= 20.10.
|
|
7
|
+
|
|
8
|
+
## Commands
|
|
9
|
+
|
|
10
|
+
- `pnpm dev` — watch-mode dev server on http://localhost:3000
|
|
11
|
+
- `pnpm typecheck` — `tsc --noEmit`
|
|
12
|
+
- `pnpm test` — Node built-in test runner
|
|
13
|
+
- `pnpm gen` — regenerate `generated/openapi.json` and the typed Hey API client
|
|
14
|
+
- `pnpm build` — emit `dist/`
|
|
15
|
+
|
|
16
|
+
## Structure hints
|
|
17
|
+
|
|
18
|
+
- Route + middleware wiring lives in `src/build-app.ts` (`buildApp()` factory; pure, no side effects).
|
|
19
|
+
- The HTTP listener is started in `src/index.ts` via `@daloyjs/core/node`.
|
|
20
|
+
- Codegen reads from `buildApp()` only — never import `src/index.ts` from scripts.
|
|
21
|
+
|
|
22
|
+
For workflows (adding routes, regenerating the SDK, common pitfalls) see [SKILL.md](SKILL.md).
|
|
@@ -0,0 +1,70 @@
|
|
|
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>
|
|
@@ -7,18 +7,18 @@
|
|
|
7
7
|
"node": ">=20.10.0"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"dev": "node --import tsx --watch src/index.ts",
|
|
11
|
-
"start": "node --import tsx src/index.ts",
|
|
10
|
+
"dev": "node --import tsx/esm --watch src/index.ts",
|
|
11
|
+
"start": "node --import tsx/esm src/index.ts",
|
|
12
12
|
"build": "tsc -p tsconfig.json",
|
|
13
13
|
"typecheck": "tsc --noEmit",
|
|
14
|
-
"test": "node --import tsx --test tests/**/*.test.ts",
|
|
15
|
-
"gen:openapi": "node --import tsx scripts/dump-openapi.ts",
|
|
14
|
+
"test": "node --import tsx/esm --test tests/**/*.test.ts",
|
|
15
|
+
"gen:openapi": "node --import tsx/esm scripts/dump-openapi.ts",
|
|
16
16
|
"gen:client": "openapi-ts",
|
|
17
17
|
"gen": "pnpm gen:openapi && pnpm gen:client",
|
|
18
18
|
"audit": "pnpm audit --prod"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@daloyjs/core": "^0.
|
|
21
|
+
"@daloyjs/core": "^0.5.0",
|
|
22
22
|
"zod": "^4.4.3"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
A [DaloyJS](https://daloyjs.dev) REST API deployed to **Vercel Edge**. Contract-first: routes are defined with Zod schemas and OpenAPI 3.1 is generated from them.
|
|
4
|
+
|
|
5
|
+
- Package manager: pnpm (use `pnpm` unless the project's `package.json` was rewritten for npm/yarn/bun).
|
|
6
|
+
- Runtime: Vercel Edge (Web Standard `Request`/`Response`).
|
|
7
|
+
|
|
8
|
+
## Commands
|
|
9
|
+
|
|
10
|
+
- `pnpm dev` — local Vercel dev server on http://localhost:3000
|
|
11
|
+
- `pnpm typecheck`
|
|
12
|
+
- `pnpm test`
|
|
13
|
+
- `pnpm deploy` — deploy to Vercel
|
|
14
|
+
|
|
15
|
+
## Structure hints
|
|
16
|
+
|
|
17
|
+
- The Edge entrypoint is `api/[...path].ts` — a catch-all that delegates to DaloyJS via `toEdgeHandler(app)` from `@daloyjs/core/vercel`. Keep it as a catch-all so DaloyJS owns routing.
|
|
18
|
+
- Build the `App` inside that file (or import a factory it uses); the file must export `default toEdgeHandler(app)` and `export const config = { runtime: "edge" }`.
|
|
19
|
+
|
|
20
|
+
For workflows (adding routes, regenerating the SDK, common pitfalls) see [SKILL.md](SKILL.md).
|
|
@@ -0,0 +1,64 @@
|
|
|
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>
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
"dev": "vercel dev",
|
|
8
8
|
"deploy": "vercel deploy",
|
|
9
9
|
"typecheck": "tsc --noEmit",
|
|
10
|
-
"test": "node --import tsx --test tests/**/*.test.ts"
|
|
10
|
+
"test": "node --import tsx/esm --test tests/**/*.test.ts"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@daloyjs/core": "^0.
|
|
13
|
+
"@daloyjs/core": "^0.5.0",
|
|
14
14
|
"zod": "^4.4.3"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|