feat(zod-openapi): support Zod v4 (#1223)

* feat(zod-openapi): support Zod v4

* update `peerDependencies`

* add changeset

* fixed type error

* update dependencies
pull/1314/head
Yusuke Wada 2025-07-18 16:40:21 +09:00 committed by GitHub
parent 2a589b0728
commit 845e336ff4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 33 additions and 20 deletions

View File

@ -0,0 +1,9 @@
---
'@hono/zod-openapi': major
---
feat: support Zod v4
Zod OpenAPI has been migrated the Zod version from v3 to v4. As a result, the `zod` in `peerDependencies` has been updated to 4.0.0 or higher.
Although this is not a breaking change, it is a major change, so it is considered a major version upgrade.

View File

@ -41,7 +41,7 @@
"homepage": "https://github.com/honojs/middleware",
"peerDependencies": {
"hono": ">=4.3.6",
"zod": ">=3.0.0"
"zod": "^4.0.0"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.17.4",
@ -51,10 +51,10 @@
"typescript": "^5.8.2",
"vitest": "^3.2.4",
"yaml": "^2.4.3",
"zod": "^3.22.1"
"zod": "^4.0.5"
},
"dependencies": {
"@asteasolutions/zod-to-openapi": "^7.3.0",
"@asteasolutions/zod-to-openapi": "^8.0.0",
"@hono/zod-validator": "workspace:^",
"openapi3-ts": "^4.5.0"
},

View File

@ -240,7 +240,7 @@ describe('coerce', () => {
type Actual = ExtractSchema<typeof routes>['/api/users/:id']['$get']['input']
type Expected = {
param: {
id: number
id: unknown
}
}
type verify = Expect<Equal<Expected, Actual>>

View File

@ -11,6 +11,7 @@ import {
OpenApiGeneratorV3,
OpenApiGeneratorV31,
extendZodWithOpenApi,
getOpenApiMetadata,
} from '@asteasolutions/zod-to-openapi'
import { zValidator } from '@hono/zod-validator'
import { Hono } from 'hono'
@ -38,8 +39,8 @@ import type { JSONParsed, JSONValue, RemoveBlankRecord, SimplifyDeepArray } from
import { mergePath } from 'hono/utils/url'
import type { OpenAPIObject } from 'openapi3-ts/oas30'
import type { OpenAPIObject as OpenAPIV31bject } from 'openapi3-ts/oas31'
import type { ZodError, ZodSchema } from 'zod'
import { ZodType, z } from 'zod'
import { ZodType, z } from 'zod/v4'
import type { ZodError } from 'zod/v4'
type MaybePromise<T> = Promise<T> | T
@ -128,7 +129,7 @@ type InputTypeJson<R extends RouteConfig> = R['request'] extends RequestTypes
? {}
: R['request']['body']['content'][keyof R['request']['body']['content']] extends Record<
'schema',
ZodSchema<any>
ZodType<any>
>
? {
in: {
@ -154,7 +155,7 @@ type InputTypeForm<R extends RouteConfig> = R['request'] extends RequestTypes
? {}
: R['request']['body']['content'][keyof R['request']['body']['content']] extends Record<
'schema',
ZodSchema<any>
ZodType<any>
>
? {
in: {
@ -181,7 +182,7 @@ type InputTypeCookie<R extends RouteConfig> = InputTypeBase<R, 'cookies', 'cooki
type ExtractContent<T> = T extends {
[K in keyof T]: infer A
}
? A extends Record<'schema', ZodSchema>
? A extends Record<'schema', ZodType>
? z.infer<A['schema']>
: never
: never
@ -659,11 +660,14 @@ export class OpenAPIHono<
}
case 'schema':
return this.openAPIRegistry.register(def.schema._def.openapi._internal.refId, def.schema)
return this.openAPIRegistry.register(
getOpenApiMetadata(def.schema)._internal?.refId,
def.schema
)
case 'parameter':
return this.openAPIRegistry.registerParameter(
def.schema._def.openapi._internal.refId,
getOpenApiMetadata(def.schema)._internal?.refId,
def.schema
)

View File

@ -99,14 +99,14 @@ __metadata:
languageName: node
linkType: hard
"@asteasolutions/zod-to-openapi@npm:^7.3.0":
version: 7.3.0
resolution: "@asteasolutions/zod-to-openapi@npm:7.3.0"
"@asteasolutions/zod-to-openapi@npm:^8.0.0":
version: 8.0.0
resolution: "@asteasolutions/zod-to-openapi@npm:8.0.0"
dependencies:
openapi3-ts: "npm:^4.1.2"
peerDependencies:
zod: ^3.20.2
checksum: 10c0/f0a68a89929cdeaa3e21d2027489689f982824d676a9332c680e119f60881dd39b571324b24ad4837fda49bf6fe7c3e2af2199268b281bf1aec923d7a7cbfc40
zod: ^4.0.0
checksum: 10c0/b522d074832fb137dca724c8bd4bb134c7b4d4cad12c247ed3c864f993923b3475fc06580e6e1cbc4fd8641cd361679bbe1dd87c9bb42e142bc056d96d59fbc8
languageName: node
linkType: hard
@ -2734,7 +2734,7 @@ __metadata:
resolution: "@hono/zod-openapi@workspace:packages/zod-openapi"
dependencies:
"@arethetypeswrong/cli": "npm:^0.17.4"
"@asteasolutions/zod-to-openapi": "npm:^7.3.0"
"@asteasolutions/zod-to-openapi": "npm:^8.0.0"
"@hono/zod-validator": "workspace:^"
hono: "npm:^4.8.4"
openapi3-ts: "npm:^4.5.0"
@ -2743,10 +2743,10 @@ __metadata:
typescript: "npm:^5.8.2"
vitest: "npm:^3.2.4"
yaml: "npm:^2.4.3"
zod: "npm:^3.22.1"
zod: "npm:^4.0.5"
peerDependencies:
hono: ">=4.3.6"
zod: ">=3.0.0"
zod: ^4.0.0
languageName: unknown
linkType: soft
@ -16830,7 +16830,7 @@ __metadata:
languageName: node
linkType: hard
"zod@npm:^3.20.2, zod@npm:^3.22.1, zod@npm:^3.22.3":
"zod@npm:^3.20.2, zod@npm:^3.22.3":
version: 3.24.2
resolution: "zod@npm:3.24.2"
checksum: 10c0/c638c7220150847f13ad90635b3e7d0321b36cce36f3fc6050ed960689594c949c326dfe2c6fa87c14b126ee5d370ccdebd6efb304f41ef5557a4aaca2824565