Releases: block65/openapi-codegen
v10.0.3
v10.0.2
Fixed
- Generated Hono middleware validators now reference the coerced sibling schemas instead of the exact ones, so HTTP query, path, and header values (which always arrive as strings) validate correctly. Previously a request like
?limit=20would fail because"20"was not av.number(). Body validators are unaffected in practice — JSON-typed numbers still pass through the coerced union. UseexactOnlyto opt out.
v10.0.1
Fix
Honors x-typescript-hint on string schemas inside oneOf/anyOf/allOf. Previously the recursive string branch ignored the hint, so a schema like oneOf: [{ enum: ["native"] }, { type: string, x-typescript-hint: "EmbedUrl" }] collapsed to "native" | string. The fix mirrors the top-level handling in the recursive case.
Other
- Refactor: prefer
toSorted/toReversedandiifeblocks over deeply-nested ternaries. - Chore: drop leftover prettier config, the unused
@ts-morph/commondevDep, and the unicorn nested-ternary lint rule. - Chore: enable composite tsconfig; ignore
*.tsbuildinfo. - Style: fix indentation on the undici
@ts-expect-errorcomment block in the test fetch wrappers.
v10.0.0
Whats change
v9.x generated a single valibot schema per type that mixed concerns - sometimes strict, sometimes coercing. This made it impossible to cleanly separate server validation (reject bad input) from client-side convenience (accept realistic wire types, trim whitespace, coerce strings to numbers). You ended up needing stripUndefined calls and other runtime workarounds to satisfy types that were stricter than necessary for the context.
v10 generates two schema variants per type: exact (the API contract - what the spec says) and coerced (the DX helper - accepts what the wire actually gives you, produces spec-compliant values). The server uses exact schemas and validates strictly. The client uses coerced schemas and gets clean data without manual cleanup. Each side gets exactly the schema it needs.
Breaking
- All schemas now have
exactFooSchema(strict) +fooSchema(coerced) variants - consumers importing schema names directly will need to update - Hono middleware uses exact schemas - the server no longer silently coerces or trims input. Malformed data is rejected, not rescued
- Coerced schemas use
v.optional()instead ofv.exactOptional()—undefinedvalues are accepted in coerced mode since they can't survive JSON serialization anyway
New
- Dual schemas — exact validates that data is spec-compliant; coerced takes untrusted data and makes it spec-compliant. Coerced composes exact via pipe, so constraints are never duplicated
- int64 coercion — JSON can't represent bigint, so the coerced schema accepts
string | number | bigintand producesbigintviav.toBigint(). Only applied where the wire format genuinely forces a different type - HTTP param coercion — query and header params are always strings on the wire. Coerced schemas accept strings and coerce to the spec type via
v.toNumber()/v.toBigint(). Exact schemas expect the native type - String trimming — coerced mode applies
v.trim()before validation for user-typed fields (strings, emails, URLs). Not applied to machine-generated values (UUIDs, patterns, enums, const values, byte/binary/password). Exact mode never trims - Command static schema props — generated commands now carry
bodySchema,paramsSchema,querySchema,responseSchemaas static properties. rest-client will consume these for automatic response validation and input checking in a future release --exact-onlyCLI flag —openapi-codegen --exact-onlyemits only exact schemas, no coerced variants- Schema deduplication — when exact and coerced are structurally identical (enums, UUIDs, patterns, const values), the coerced schema is
export const fooSchema = exactFooSchemainstead of a full duplicate
Fixes
- Emit
unknownoutput type when a response has no JSON content — previously the Output type argument was omitted, shifting Query and Header generics into the wrong positions. This caused type errors for specs with streaming or non-JSON endpoints (e.g. Docker Engine API)
Tooling
- Replaced biome with oxlint + oxfmt
- Updated to undici 8, vitest 4, vite 8, TypeScript 6
v9.4.1
What's Changed
Fixes
- Use RegExp constructor for valibot pattern validation — Regex literal construction only escaped forward slashes; patterns with backslashes, quotes, or newlines would produce invalid source code.
new RegExp(JSON.stringify(pattern))handles all edge cases.
Full Changelog: v9.4.0...v9.4.1
v9.4.0
What's Changed
Features
- Zero-parameter command constructors — Commands with no path/query/header params (e.g.
ListBillingAccountsCommand) now generate a no-arg constructor withsuper(pathname)directly - Optional input for all-optional params — Commands where all parameters are optional no longer require an empty
{}argument (e.g.new FindPetsCommand()now works)
Fixes
- Skip response type for non-JSON endpoints — Endpoints without JSON response content no longer incorrectly get
unspecifiedKeywordas a response type argument - Remove
| undefinedfrom optional header types — Optional header properties now use?only, fixing compatibility with theCommandgeneric constraint (Record<string, string | number | boolean>)
Chores
- Bump
@block65/rest-clientpeer dependency to^12.1.0(4th generic for headers) - Add biome config
Full Changelog: v9.3.0...v9.4.0
v9.3.0
What's Changed
- fix: generate v.null() for type: "null" schemas in valibot by @maxholman in #16
- feat: wire header params into Command constructor by @maxholman in #17
Full Changelog: v9.2.2...v9.3.0
v9.2.2
What's Changed
- fix: resolve $ref schemas for query and header param coercion by @maxholman in #15
Full Changelog: v9.2.1...v9.2.2
v9.2.1
What's Changed
- fix: coerce integer query and header params from strings by @maxholman in #14
Full Changelog: v9.2.0...v9.2.1
v9.2.0
What's Changed
- feat: generate typed header parameters with valibot validation by @maxholman in #13
Full Changelog: v9.1.0...v9.2.0