create-daloy 0.7.2 → 0.7.4
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 +2 -2
- package/bin/create-daloy.mjs +43 -3
- package/package.json +1 -1
- package/templates/bun-basic/AGENTS.md +1 -1
- package/templates/bun-basic/README.md +1 -0
- package/templates/bun-basic/_agents/skills/daloyjs-best-practices/SKILL.md +17 -0
- package/templates/bun-basic/src/build-app.ts +5 -3
- package/templates/cloudflare-worker/AGENTS.md +1 -1
- package/templates/cloudflare-worker/_agents/skills/daloyjs-best-practices/SKILL.md +18 -0
- package/templates/deno-basic/AGENTS.md +1 -1
- package/templates/deno-basic/README.md +1 -0
- package/templates/deno-basic/_agents/skills/daloyjs-best-practices/SKILL.md +17 -0
- package/templates/deno-basic/src/build-app.ts +5 -3
- package/templates/node-basic/AGENTS.md +2 -0
- package/templates/node-basic/README.md +1 -0
- package/templates/node-basic/_agents/skills/daloyjs-best-practices/SKILL.md +22 -0
- package/templates/node-basic/src/build-app.ts +6 -3
- package/templates/vercel-edge/AGENTS.md +1 -1
- package/templates/vercel-edge/README.md +3 -2
- package/templates/vercel-edge/_agents/skills/daloyjs-best-practices/SKILL.md +18 -0
- package/templates/vercel-edge/api/[...path].ts +4 -3
package/README.md
CHANGED
|
@@ -44,10 +44,10 @@ pnpm create daloy@latest my-api \
|
|
|
44
44
|
| `--template <name>` | `node-basic` (default), `vercel-edge`, `cloudflare-worker`, `bun-basic`, or `deno-basic`. |
|
|
45
45
|
| `--package-manager <pm>` | `pnpm` (default), `npm`, `yarn`, or `bun`. Ignored for `deno-basic`. |
|
|
46
46
|
| `--list-templates` | Print available templates with descriptions. |
|
|
47
|
-
| `--install` / `--no-install` | Install dependencies after scaffolding. Defaults to
|
|
47
|
+
| `--install` / `--no-install` | Install dependencies after scaffolding. Defaults to **Y** for npm/yarn/bun and **N** for pnpm (so first-time runs are not blocked by the 24h `minimumReleaseAge` embargo or the `pnpm.onlyBuiltDependencies` allowlist required by the hardened `.npmrc`). |
|
|
48
48
|
| `--git` / `--no-git` | Initialize a git repository. Defaults to interactive. |
|
|
49
49
|
| `--minimal` | Strip the bookstore demo route and the built-in `/docs` + `/openapi.json` routes so only the framework bootstrap and `/healthz` ship. |
|
|
50
|
-
| `--with-ci` / `--no-ci` | Add the hardened GitHub Actions, Dependabot, CODEOWNERS, SECURITY.md, and lockfile-source verification bundle. |
|
|
50
|
+
| `--with-ci` / `--no-ci` | Add the hardened GitHub Actions, Dependabot, CODEOWNERS, SECURITY.md, and lockfile-source verification bundle. **Defaults to Y** so scaffolded projects are secure by default. |
|
|
51
51
|
| `--code-owner <owner>` | Replace the CODEOWNERS placeholder when `--with-ci` is used, for example `@acme/security`. |
|
|
52
52
|
| `--force` | Overwrite an existing non-empty directory. |
|
|
53
53
|
| `--yes` | Accept all defaults; never prompt. |
|
package/bin/create-daloy.mjs
CHANGED
|
@@ -314,10 +314,10 @@ ${heading("Options")}
|
|
|
314
314
|
${color(COLORS.green, "--template <name>")} ${TEMPLATES.join(" | ")} ${color(COLORS.dim, "(default: node-basic)")}
|
|
315
315
|
${color(COLORS.green, "--package-manager <pm>")} ${PACKAGE_MANAGERS.join(" | ")} ${color(COLORS.dim, "(default: pnpm)")}
|
|
316
316
|
${color(COLORS.green, "--list-templates")} Print available templates and exit.
|
|
317
|
-
${color(COLORS.green, "--install / --no-install")} Install dependencies after scaffolding.
|
|
317
|
+
${color(COLORS.green, "--install / --no-install")} Install dependencies after scaffolding. ${color(COLORS.dim, "(default: Y, except pnpm \u2014 N to respect minimumReleaseAge + onlyBuiltDependencies)")}
|
|
318
318
|
${color(COLORS.green, "--git / --no-git")} Initialize a git repository.
|
|
319
319
|
${color(COLORS.green, "--minimal")} Strip the bookstore + OpenAPI docs demo routes.
|
|
320
|
-
${color(COLORS.green, "--with-ci / --no-ci")} Add hardened GitHub Actions + governance files.
|
|
320
|
+
${color(COLORS.green, "--with-ci / --no-ci")} Add hardened GitHub Actions + governance files. ${color(COLORS.dim, "(default: Y)")}
|
|
321
321
|
${color(COLORS.green, "--code-owner <owner>")} CODEOWNERS owner for --with-ci, e.g. @acme/security.
|
|
322
322
|
${color(COLORS.green, "--force")} Overwrite an existing non-empty directory.
|
|
323
323
|
${color(COLORS.green, "--yes, -y")} Accept all defaults; never prompt.
|
|
@@ -1114,6 +1114,23 @@ function printSummary({ projectName, template, packageManager, installDeps, skip
|
|
|
1114
1114
|
console.log(` ${arrow} ${color(COLORS.cyan, `${packageManager} run dev`)}`);
|
|
1115
1115
|
}
|
|
1116
1116
|
|
|
1117
|
+
if (!installDeps && !skipPackageManager && packageManager === "pnpm") {
|
|
1118
|
+
console.log("");
|
|
1119
|
+
console.log(`${color(COLORS.bold, "Heads-up before \`pnpm install\`")}`);
|
|
1120
|
+
console.log(
|
|
1121
|
+
` ${color(COLORS.gray, SYMBOLS.pointer)} ${color(COLORS.dim, "pnpm-workspace.yaml sets minimumReleaseAge: 1440 \u2014 newly-published deps")}`,
|
|
1122
|
+
);
|
|
1123
|
+
console.log(
|
|
1124
|
+
` ${color(COLORS.gray, SYMBOLS.pointer)} ${color(COLORS.dim, "(including a just-released @daloyjs/core) are embargoed for 24 h.")}`,
|
|
1125
|
+
);
|
|
1126
|
+
console.log(
|
|
1127
|
+
` ${color(COLORS.gray, SYMBOLS.pointer)} ${color(COLORS.dim, "Lifecycle scripts are blocked by default; allowlist trusted builds in")}`,
|
|
1128
|
+
);
|
|
1129
|
+
console.log(
|
|
1130
|
+
` ${color(COLORS.gray, SYMBOLS.pointer)} ${color(COLORS.dim, "package.json under pnpm.onlyBuiltDependencies if install complains.")}`,
|
|
1131
|
+
);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1117
1134
|
console.log("");
|
|
1118
1135
|
console.log(`${color(COLORS.bold, "Useful commands")}`);
|
|
1119
1136
|
if (skipPackageManager) {
|
|
@@ -1228,6 +1245,27 @@ async function main() {
|
|
|
1228
1245
|
if (installDeps === undefined) {
|
|
1229
1246
|
if (skipPackageManager) {
|
|
1230
1247
|
installDeps = false;
|
|
1248
|
+
} else if (packageManager === "pnpm") {
|
|
1249
|
+
// Deny-by-default for pnpm: the scaffolded `pnpm-workspace.yaml` ships
|
|
1250
|
+
// with `minimumReleaseAge: 1440` (24 h embargo on newly-published
|
|
1251
|
+
// versions) and the `.npmrc` blocks lifecycle scripts unless they're
|
|
1252
|
+
// allowlisted in `package.json` under `pnpm.onlyBuiltDependencies`.
|
|
1253
|
+
// Both are security best practices, but they mean a fresh
|
|
1254
|
+
// `pnpm install` can fail until the user (a) waits 24 h for newly
|
|
1255
|
+
// published `@daloyjs/core` versions to clear the embargo, or (b)
|
|
1256
|
+
// allowlists any dep that needs a build script. Defaulting to N
|
|
1257
|
+
// makes that explicit instead of failing the install silently.
|
|
1258
|
+
if (rl) {
|
|
1259
|
+
console.log(
|
|
1260
|
+
color(
|
|
1261
|
+
COLORS.gray,
|
|
1262
|
+
" (pnpm install may fail until you set pnpm.onlyBuiltDependencies in package.json and wait 24h for fresh @daloyjs/core releases \u2014 see pnpm-workspace.yaml)",
|
|
1263
|
+
),
|
|
1264
|
+
);
|
|
1265
|
+
installDeps = await askYesNo(rl, `Install dependencies with ${packageManager}?`, false);
|
|
1266
|
+
} else {
|
|
1267
|
+
installDeps = false;
|
|
1268
|
+
}
|
|
1231
1269
|
} else {
|
|
1232
1270
|
installDeps = rl ? await askYesNo(rl, `Install dependencies with ${packageManager}?`, true) : false;
|
|
1233
1271
|
}
|
|
@@ -1240,7 +1278,9 @@ async function main() {
|
|
|
1240
1278
|
|
|
1241
1279
|
let withCi = opts.ci;
|
|
1242
1280
|
if (withCi === undefined) {
|
|
1243
|
-
|
|
1281
|
+
// Default to Y — the hardened GitHub Actions + Dependabot + CODEOWNERS
|
|
1282
|
+
// + SECURITY.md bundle is opt-out, not opt-in. Most users want it.
|
|
1283
|
+
withCi = rl ? await askYesNo(rl, "Add hardened GitHub Actions and security files?", true) : true;
|
|
1244
1284
|
}
|
|
1245
1285
|
|
|
1246
1286
|
rl?.close();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
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.
|
|
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. When `docs: true` is set in `new App({...})`, three routes are auto-mounted: `GET /openapi.json`, `GET /openapi.yaml`, and `GET /docs` (Scalar UI).
|
|
4
4
|
|
|
5
5
|
- Package manager / runtime: Bun.
|
|
6
6
|
|
|
@@ -24,6 +24,7 @@ curl http://localhost:3000/books/1
|
|
|
24
24
|
- API docs (Scalar): <http://localhost:3000/docs>
|
|
25
25
|
- OpenAPI 3.1 JSON: <http://localhost:3000/openapi.json>
|
|
26
26
|
- OpenAPI 3.1 YAML: <http://localhost:3000/openapi.yaml>
|
|
27
|
+
- OpenAPI 3.1 YAML: <http://localhost:3000/openapi.yaml>
|
|
27
28
|
<!-- daloy-minimal:strip-end docs -->
|
|
28
29
|
|
|
29
30
|
## Generate OpenAPI + typed client
|
|
@@ -65,6 +65,23 @@ Always run `bun run typecheck` and `bun test` before declaring a task done.
|
|
|
65
65
|
If a change touches route shapes, also rerun `bun run gen:openapi && bun
|
|
66
66
|
run gen:client` so the client stays in sync.
|
|
67
67
|
|
|
68
|
+
## OpenAPI & docs routes
|
|
69
|
+
|
|
70
|
+
When `docs: true` is set on `new App({...})` (the default in this template),
|
|
71
|
+
three routes are auto-mounted off the spec generated from your route
|
|
72
|
+
definitions:
|
|
73
|
+
|
|
74
|
+
- `GET /openapi.json` — OpenAPI 3.1 spec as JSON.
|
|
75
|
+
- `GET /openapi.yaml` — OpenAPI 3.1 spec as YAML (served inline as
|
|
76
|
+
`text/yaml; charset=utf-8`, since `@daloyjs/core` 0.13.1).
|
|
77
|
+
- `GET /docs` — Scalar API reference UI that loads the spec.
|
|
78
|
+
|
|
79
|
+
Customize via `docs: { openapiPath, openapiYamlPath, path, ui }`. Set
|
|
80
|
+
`openapiYamlPath: false` to disable just the YAML route, `docs: "auto"` to
|
|
81
|
+
mount only outside production, or `docs: false` to disable all three.
|
|
82
|
+
For hand-rolled mounting, `openapiToYAML` is exported from
|
|
83
|
+
`@daloyjs/core/openapi`.
|
|
84
|
+
|
|
68
85
|
## Workflow: add a new route
|
|
69
86
|
|
|
70
87
|
1. **Open `src/build-app.ts`.**
|
|
@@ -19,9 +19,11 @@ export function buildApp(): App {
|
|
|
19
19
|
requestTimeoutMs: 5_000,
|
|
20
20
|
production: process.env.NODE_ENV === "production",
|
|
21
21
|
// daloy-minimal:strip-start docs
|
|
22
|
-
// Auto-mounted docs:
|
|
23
|
-
// GET /openapi.json —
|
|
24
|
-
// GET /
|
|
22
|
+
// Auto-mounted docs (when `docs: true`):
|
|
23
|
+
// GET /openapi.json — OpenAPI 3.1 spec (JSON)
|
|
24
|
+
// GET /openapi.yaml — OpenAPI 3.1 spec (YAML, served inline as text/yaml)
|
|
25
|
+
// GET /docs — Scalar API reference UI that loads the spec
|
|
26
|
+
// Customize via `docs: { openapiYamlPath: false }` to disable the YAML route.
|
|
25
27
|
// `info.title` / `info.version` are pulled from package.json by default;
|
|
26
28
|
// set `openapi.info` here to override them.
|
|
27
29
|
openapi: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
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.
|
|
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. This starter omits `docs: true` to keep the Worker bundle small — enable it explicitly via `new App({ docs: true })` to auto-mount `GET /openapi.json`, `GET /openapi.yaml`, and `GET /docs` (Scalar UI).
|
|
4
4
|
|
|
5
5
|
- Package manager: pnpm (use `pnpm` unless the project's `package.json` was rewritten for npm/yarn/bun).
|
|
6
6
|
- Runtime: Cloudflare Workers (Web Standard `Request`/`Response`).
|
|
@@ -59,6 +59,24 @@ pnpm audit # supply-chain audit
|
|
|
59
59
|
|
|
60
60
|
Always run `pnpm typecheck` and `pnpm test` before declaring a task done.
|
|
61
61
|
|
|
62
|
+
## OpenAPI & docs routes (opt-in)
|
|
63
|
+
|
|
64
|
+
This Worker starter omits `docs: true` to keep the bundle small (Workers
|
|
65
|
+
have a hard size limit). When you opt in via `new App({ docs: true })`,
|
|
66
|
+
three routes are auto-mounted off the spec generated from your route
|
|
67
|
+
definitions:
|
|
68
|
+
|
|
69
|
+
- `GET /openapi.json` — OpenAPI 3.1 spec as JSON.
|
|
70
|
+
- `GET /openapi.yaml` — OpenAPI 3.1 spec as YAML (served inline as
|
|
71
|
+
`text/yaml; charset=utf-8`, since `@daloyjs/core` 0.13.1).
|
|
72
|
+
- `GET /docs` — Scalar API reference UI that loads the spec.
|
|
73
|
+
|
|
74
|
+
On Workers the Scalar UI adds the most weight; consider
|
|
75
|
+
`docs: { ui: "swagger" }` or `docs: "auto"` (off in production), or pass
|
|
76
|
+
`docs: { openapiYamlPath: false }` to drop the YAML route only.
|
|
77
|
+
For hand-rolled mounting, `openapiToYAML` is exported from
|
|
78
|
+
`@daloyjs/core/openapi`.
|
|
79
|
+
|
|
62
80
|
## Workflow: add a new route
|
|
63
81
|
|
|
64
82
|
1. **Open `src/index.ts`.**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
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.
|
|
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. When `docs: true` is set in `new App({...})`, three routes are auto-mounted: `GET /openapi.json`, `GET /openapi.yaml`, and `GET /docs` (Scalar UI).
|
|
4
4
|
|
|
5
5
|
- Runtime: Deno (no Node package manager). Dependencies are loaded via `npm:` and `jsr:` specifiers in `deno.json`.
|
|
6
6
|
|
|
@@ -23,6 +23,7 @@ curl http://localhost:3000/books/1
|
|
|
23
23
|
- API docs (Scalar): <http://localhost:3000/docs>
|
|
24
24
|
- OpenAPI 3.1 JSON: <http://localhost:3000/openapi.json>
|
|
25
25
|
- OpenAPI 3.1 YAML: <http://localhost:3000/openapi.yaml>
|
|
26
|
+
- OpenAPI 3.1 YAML: <http://localhost:3000/openapi.yaml>
|
|
26
27
|
<!-- daloy-minimal:strip-end docs -->
|
|
27
28
|
|
|
28
29
|
## Generate the OpenAPI spec
|
|
@@ -67,6 +67,23 @@ npx @hey-api/openapi-ts -i generated/openapi.json -o generated/client
|
|
|
67
67
|
Always run `deno task typecheck` and `deno task test` before declaring a
|
|
68
68
|
task done.
|
|
69
69
|
|
|
70
|
+
## OpenAPI & docs routes
|
|
71
|
+
|
|
72
|
+
When `docs: true` is set on `new App({...})` (the default in this template),
|
|
73
|
+
three routes are auto-mounted off the spec generated from your route
|
|
74
|
+
definitions:
|
|
75
|
+
|
|
76
|
+
- `GET /openapi.json` — OpenAPI 3.1 spec as JSON.
|
|
77
|
+
- `GET /openapi.yaml` — OpenAPI 3.1 spec as YAML (served inline as
|
|
78
|
+
`text/yaml; charset=utf-8`, since `@daloyjs/core` 0.13.1).
|
|
79
|
+
- `GET /docs` — Scalar API reference UI that loads the spec.
|
|
80
|
+
|
|
81
|
+
Customize via `docs: { openapiPath, openapiYamlPath, path, ui }`. Set
|
|
82
|
+
`openapiYamlPath: false` to disable just the YAML route, `docs: "auto"` to
|
|
83
|
+
mount only outside production, or `docs: false` to disable all three.
|
|
84
|
+
For hand-rolled mounting, `openapiToYAML` is exported from
|
|
85
|
+
`@daloyjs/core/openapi`.
|
|
86
|
+
|
|
70
87
|
## Workflow: add a new route
|
|
71
88
|
|
|
72
89
|
1. **Open `src/build-app.ts`.**
|
|
@@ -20,9 +20,11 @@ export function buildApp(): App {
|
|
|
20
20
|
requestTimeoutMs: 5_000,
|
|
21
21
|
production: Deno.env.get("DENO_ENV") === "production",
|
|
22
22
|
// daloy-minimal:strip-start docs
|
|
23
|
-
// Auto-mounted docs:
|
|
24
|
-
// GET /openapi.json —
|
|
25
|
-
// GET /
|
|
23
|
+
// Auto-mounted docs (when `docs: true`):
|
|
24
|
+
// GET /openapi.json — OpenAPI 3.1 spec (JSON)
|
|
25
|
+
// GET /openapi.yaml — OpenAPI 3.1 spec (YAML, served inline as text/yaml)
|
|
26
|
+
// GET /docs — Scalar API reference UI that loads the spec
|
|
27
|
+
// Customize via `docs: { openapiYamlPath: false }` to disable the YAML route.
|
|
26
28
|
// `info.title` / `info.version` are pulled from deno.json by default;
|
|
27
29
|
// set `openapi.info` here to override them.
|
|
28
30
|
openapi: {
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A [DaloyJS](https://daloyjs.dev) Node.js REST API. **Contract-first**:
|
|
4
4
|
routes are defined with Zod schemas and OpenAPI 3.1 is generated from them.
|
|
5
|
+
When `docs: true` is set in `new App({...})`, three routes are auto-mounted:
|
|
6
|
+
`GET /openapi.json`, `GET /openapi.yaml`, and `GET /docs` (Scalar UI).
|
|
5
7
|
|
|
6
8
|
- Package manager: pnpm (use `pnpm` unless the project's `package.json` was rewritten for npm/yarn/bun).
|
|
7
9
|
- Runtime: Node.js >= 24.15 (active LTS).
|
|
@@ -24,6 +24,7 @@ curl http://localhost:3000/books/1
|
|
|
24
24
|
- API docs (Scalar): <http://localhost:3000/docs>
|
|
25
25
|
- OpenAPI 3.1 JSON: <http://localhost:3000/openapi.json>
|
|
26
26
|
- OpenAPI 3.1 YAML: <http://localhost:3000/openapi.yaml>
|
|
27
|
+
- OpenAPI 3.1 YAML: <http://localhost:3000/openapi.yaml>
|
|
27
28
|
|
|
28
29
|
The spec is generated live from your routes, so it stays in sync with what is actually deployed.
|
|
29
30
|
<!-- daloy-minimal:strip-end docs -->
|
|
@@ -72,6 +72,28 @@ Always run `pnpm typecheck` and `pnpm test` before declaring a task done.
|
|
|
72
72
|
If a change touches route shapes, also run `pnpm gen` so the client stays
|
|
73
73
|
in sync.
|
|
74
74
|
|
|
75
|
+
## OpenAPI & docs routes
|
|
76
|
+
|
|
77
|
+
When `docs: true` is set on `new App({...})` (the default in this template),
|
|
78
|
+
three routes are auto-mounted off the spec generated from your route
|
|
79
|
+
definitions:
|
|
80
|
+
|
|
81
|
+
- `GET /openapi.json` — OpenAPI 3.1 spec as JSON.
|
|
82
|
+
- `GET /openapi.yaml` — OpenAPI 3.1 spec as YAML (served inline as
|
|
83
|
+
`text/yaml; charset=utf-8`, since `@daloyjs/core` 0.13.1).
|
|
84
|
+
- `GET /docs` — Scalar API reference UI that loads the spec.
|
|
85
|
+
|
|
86
|
+
Customize via `docs: { openapiPath, openapiYamlPath, path, ui }`. Set
|
|
87
|
+
`openapiYamlPath: false` to disable just the YAML route, `docs: "auto"` to
|
|
88
|
+
mount only outside production, or `docs: false` to disable all three.
|
|
89
|
+
|
|
90
|
+
For hand-rolled mounting (when `docs: false`), the YAML serializer is
|
|
91
|
+
exported from the openapi subpath:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { generateOpenAPI, openapiToYAML } from "@daloyjs/core/openapi";
|
|
95
|
+
```
|
|
96
|
+
|
|
75
97
|
## Workflow: add a new route
|
|
76
98
|
|
|
77
99
|
Follow these steps in order. Skipping any of them is a common source of
|
|
@@ -21,11 +21,14 @@ export function buildApp(): App {
|
|
|
21
21
|
requestTimeoutMs: 5_000,
|
|
22
22
|
production: process.env.NODE_ENV === "production",
|
|
23
23
|
// daloy-minimal:strip-start docs
|
|
24
|
-
// Auto-mounted docs:
|
|
25
|
-
// GET /openapi.json —
|
|
26
|
-
// GET /
|
|
24
|
+
// Auto-mounted docs (when `docs: true`):
|
|
25
|
+
// GET /openapi.json — OpenAPI 3.1 spec (JSON)
|
|
26
|
+
// GET /openapi.yaml — OpenAPI 3.1 spec (YAML, served inline as text/yaml)
|
|
27
|
+
// GET /docs — Scalar API reference UI that loads the spec
|
|
27
28
|
// `docs: true` always mounts. Use `docs: "auto"` to mount only when
|
|
28
29
|
// `NODE_ENV !== "production"`, or `docs: false` to disable entirely.
|
|
30
|
+
// Customize paths via `docs: { openapiPath, openapiYamlPath, path, ui }`,
|
|
31
|
+
// or pass `openapiYamlPath: false` to disable just the YAML route.
|
|
29
32
|
// `info.title` / `info.version` are pulled from package.json by default;
|
|
30
33
|
// set `openapi.info` here to override them.
|
|
31
34
|
openapi: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
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.
|
|
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. When `docs: true` is set in `new App({...})`, three routes are auto-mounted: `GET /openapi.json`, `GET /openapi.yaml`, and `GET /docs` (Scalar UI).
|
|
4
4
|
|
|
5
5
|
- Package manager: pnpm (use `pnpm` unless the project's `package.json` was rewritten for npm/yarn/bun).
|
|
6
6
|
- Runtime: Vercel Edge (Web Standard `Request`/`Response`).
|
|
@@ -24,8 +24,9 @@ curl http://localhost:3000/books/1
|
|
|
24
24
|
- API docs (Scalar): <http://localhost:3000/docs>
|
|
25
25
|
- OpenAPI 3.1 JSON: <http://localhost:3000/openapi.json>
|
|
26
26
|
- OpenAPI 3.1 YAML: <http://localhost:3000/openapi.yaml>
|
|
27
|
+
- OpenAPI 3.1 YAML: <http://localhost:3000/openapi.yaml>
|
|
27
28
|
|
|
28
|
-
After deploying, the same routes serve `/docs
|
|
29
|
+
After deploying, the same routes serve `/docs`, `/openapi.json`, and `/openapi.yaml` from your Vercel Edge URL.
|
|
29
30
|
<!-- daloy-minimal:strip-end docs -->
|
|
30
31
|
|
|
31
32
|
## Deploy
|
|
@@ -62,5 +63,5 @@ That catch-all API route lets DaloyJS own routing while Vercel handles the runti
|
|
|
62
63
|
- A health route and a contract-first `/books/:id` route with Zod validation.
|
|
63
64
|
<!-- daloy-minimal:strip-end books -->
|
|
64
65
|
<!-- daloy-minimal:strip-start docs -->
|
|
65
|
-
- A Scalar API reference UI at `/docs
|
|
66
|
+
- A Scalar API reference UI at `/docs`, plus live OpenAPI 3.1 specs at `/openapi.json` and `/openapi.yaml`.
|
|
66
67
|
<!-- daloy-minimal:strip-end docs -->
|
|
@@ -56,6 +56,24 @@ pnpm audit # supply-chain audit
|
|
|
56
56
|
|
|
57
57
|
Always run `pnpm typecheck` and `pnpm test` before declaring a task done.
|
|
58
58
|
|
|
59
|
+
## OpenAPI & docs routes
|
|
60
|
+
|
|
61
|
+
When `docs: true` is set on `new App({...})` (the default in this template),
|
|
62
|
+
three routes are auto-mounted off the spec generated from your route
|
|
63
|
+
definitions:
|
|
64
|
+
|
|
65
|
+
- `GET /openapi.json` — OpenAPI 3.1 spec as JSON.
|
|
66
|
+
- `GET /openapi.yaml` — OpenAPI 3.1 spec as YAML (served inline as
|
|
67
|
+
`text/yaml; charset=utf-8`, since `@daloyjs/core` 0.13.1).
|
|
68
|
+
- `GET /docs` — Scalar API reference UI that loads the spec.
|
|
69
|
+
|
|
70
|
+
Customize via `docs: { openapiPath, openapiYamlPath, path, ui }`. Set
|
|
71
|
+
`openapiYamlPath: false` to disable just the YAML route, `docs: "auto"` to
|
|
72
|
+
mount only outside production, or `docs: false` to disable all three.
|
|
73
|
+
On Vercel Edge the YAML serializer is pure-string (no Node deps) and
|
|
74
|
+
adds <1KB to the bundle. For hand-rolled mounting, `openapiToYAML` is
|
|
75
|
+
exported from `@daloyjs/core/openapi`.
|
|
76
|
+
|
|
59
77
|
## Workflow: add a new route
|
|
60
78
|
|
|
61
79
|
1. **Open `api/[...path].ts`.**
|
|
@@ -12,9 +12,10 @@ const app = new App({
|
|
|
12
12
|
requestTimeoutMs: 5_000,
|
|
13
13
|
production: process.env.NODE_ENV === "production",
|
|
14
14
|
// daloy-minimal:strip-start docs
|
|
15
|
-
// Auto-mounted docs:
|
|
16
|
-
// GET /openapi.json —
|
|
17
|
-
// GET /
|
|
15
|
+
// Auto-mounted docs (when `docs: true`):
|
|
16
|
+
// GET /openapi.json — OpenAPI 3.1 spec (JSON)
|
|
17
|
+
// GET /openapi.yaml — OpenAPI 3.1 spec (YAML, served inline as text/yaml)
|
|
18
|
+
// GET /docs — Scalar API reference UI that loads the spec
|
|
18
19
|
openapi: {
|
|
19
20
|
info: { title: "My Daloy Edge API", version: "0.0.1" },
|
|
20
21
|
},
|