Validation, completed — this release closes the gap between what a route
documents and what it enforces, and fixes the codegen type-safety holes
that pushed consumers back to hand-written types.
Added
- Path-parameter schemas + validation —
defineRoutenow accepts
request: { params }, so:idand friends are validated by the same Zod
schema that documents them, with a structured 422 on mismatch. Works across
Express, Fastify, Hono, Koa, and NestJS — no more hand-rolledrequireUuid
helpers repeated on every route. - Request write-back. Opt in with
validate: { writeback: true }and the
parsed payload — Zod coercions and.default()s applied — is written back
ontoreq.body/req.query/req.params, so the handler reads coerced
values instead of re-parsing them. (Koa and Hono expose coerced path params
viactx.state.doctreenValidated/c.get('doctreenValidated').) - Dev-mode response assertion.
validate: { response: 'warn' | 'throw' }
checks the handler's response against the declared Zodresponseschema —
'warn'logs a mismatch and passes through,'throw'surfaces a 500 in
development. Never coerces the response. - Status-keyed responses.
response: { 201: schema, 200: schema }documents
each status with its own schema and drives the OpenAPI export; the plain
response: schemaform still means200. defaultErrorsconfig. Declare shared error responses (401 / 403 / 422 …)
once — they merge into every route, with the route's ownerrorswinning on a
status conflict.- Standard
DoctreenValidationErrorenvelope. Validated routes document
their 422{ error, issues[] }body as a named component, so codegen emits a
DoctreenValidationErrortype and clients stop guessing the error shape. - Offline OpenAPI emit.
getOpenApiDocument(app)(on every adapter) and the
newdoctreen emit-openapiCLI build a staticopenapi.jsonwithout starting
a server, so codegen and CI can run fully offline.
Fixed
defineSchemanow works with Zod schemas. Named schemas were matched by
object identity, which Zod→SchemaNode conversion breaks — so Zod-defined named
schemas fell through to anonymousSchema1/Schema2types in codegen. They
now emit$ref: '#/components/schemas/<name>'and codegen produces
interface User, at the top level, nested, and inside arrays.- Deep schemas no longer collapse to
unknown. The Zod conversion depth cap
was raised from 5 to 12, so deep-but-non-recursive trees (menu → categories →
items → variants → options) keep their leaf types. Recursion is best expressed
withdefineSchema, which now emits a terminating$ref.