Skip to content

fix(core): keep alias out of the OpenAPI doc; mutable doc-array types - #24

Merged
christensena merged 1 commit into
feat/codegen-route-wrappedfrom
fix/route-doc-leaks
Sep 1, 2026
Merged

fix(core): keep alias out of the OpenAPI doc; mutable doc-array types#24
christensena merged 1 commit into
feat/codegen-route-wrappedfrom
fix/route-doc-leaks

Conversation

@christensena

Copy link
Copy Markdown
Owner

Two fixes from adoption feedback (group-track), stacked on #22.

alias leaked into the OpenAPI document. route() destructures alias out of the config but Object.assigned it back enumerable, so the doc generator — which copies enumerable config keys into the operation object — emitted an alias key in every aliased operation, contrary to the documented "stripped from the OpenAPI document". It is now defined non-enumerable, mirroring getRoutingPath. Every consumer (client dispatch, error guards, codegen) reads it by direct property access, so behaviour is otherwise unchanged.

readonly doc arrays broke app.openapi(). ZodapiRouteConfig accepts readonly security/tags/servers/parameters (needed so as const contract values type-check), but zod-to-openapi's OperationObject types them mutable — so a readonly-captured array (an as const value, or even a plain inline literal, which route()'s const type parameter infers readonly) made the built route unassignable to app.openapi(...), failing the overload and collapsing c.req.valid() to never. ZodapiRoute now maps those four fields through a DeepWritable, so the built route's type is mutable-armed while configs stay readonly-friendly. The runtime value is the same plain array either way.

Tests: alias non-enumerability in core; a hono test mounting a route with as const security + inline tags (compiling at all is the type regression test — c.req.valid would error otherwise) and asserting the generated document carries security/tags but no alias; a type test pinning the readonly→mutable mapping. Changeset: @zodapi/core patch.

-- Claude

🤖 Generated with Claude Code

https://claude.ai/code/session_0197TQhAzcfxR5LQigesnfmv

Two fixes from adoption feedback:

- route() destructured alias out but Object.assign'd it back enumerable,
  so the doc generator copied it into every operation object, contrary to
  the documented "stripped from the OpenAPI document". Now defined
  non-enumerable, like getRoutingPath; still readable as route.alias.

- ZodapiRouteConfig accepts readonly security/tags/servers/parameters
  (needed for as-const contracts), but zod-to-openapi's OperationObject
  types them mutable, so a readonly-captured array made the built route
  unassignable to app.openapi() and collapsed c.req.valid() to never.
  ZodapiRoute now maps those four fields through DeepWritable; the
  runtime value is a plain array either way.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0197TQhAzcfxR5LQigesnfmv
@christensena
christensena merged commit 6d5ef1f into main Sep 1, 2026
1 of 2 checks passed
@christensena
christensena deleted the fix/route-doc-leaks branch September 1, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant