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 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 interactive. |
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. |
@@ -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
- withCi = rl ? await askYesNo(rl, "Add hardened GitHub Actions and security files?", false) : false;
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
  {
2
2
  "name": "create-daloy",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "description": "Scaffold a new DaloyJS project. Run with `pnpm create daloy`, `npm create daloy@latest`, `yarn create daloy`, or `bun create daloy`.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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 — live OpenAPI 3.1 spec generated from your routes
24
- // GET /docs Scalar API reference UI that loads it
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 — live OpenAPI 3.1 spec generated from your routes
25
- // GET /docs Scalar API reference UI that loads it
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 — live OpenAPI 3.1 spec generated from your routes
26
- // GET /docs Scalar API reference UI that loads it
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` and `/openapi.json` from your Vercel Edge URL.
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` and a live OpenAPI 3.1 document at `/openapi.json`.
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 — live OpenAPI 3.1 spec generated from your routes
17
- // GET /docs Scalar API reference UI that loads it
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
  },