From d563f5b83168ff9a175cabf95fc67a74328492e5 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Sun, 7 Jul 2024 12:38:11 +0900 Subject: [PATCH 1/2] fix(zod-openapi): support `coerce` --- packages/zod-openapi/src/index.ts | 15 ++++++++-- packages/zod-openapi/test/index.test-d.ts | 36 +++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/zod-openapi/src/index.ts b/packages/zod-openapi/src/index.ts index 7c08bdef7..7f74c455c 100644 --- a/packages/zod-openapi/src/index.ts +++ b/packages/zod-openapi/src/index.ts @@ -24,6 +24,7 @@ import type { Schema, ToSchema, TypedResponse, + ValidationTargets, } from 'hono' import type { MergePath, MergeSchemaPath } from 'hono/types' import type { JSONParsed, RemoveBlankRecord } from 'hono/utils/types' @@ -71,14 +72,24 @@ type RequestPart = Part extends keyo ? R['request'][Part] : {} +type HasUndefined = undefined extends T ? true : false + type InputTypeBase< R extends RouteConfig, Part extends string, - Type extends string + Type extends keyof ValidationTargets > = R['request'] extends RequestTypes ? RequestPart extends ZodType ? { - in: { [K in Type]: z.input> } + in: { + [K in Type]: HasUndefined extends true + ? { + [K2 in keyof z.input>]?: ValidationTargets[K][K2] + } + : { + [K2 in keyof z.input>]: ValidationTargets[K][K2] + } + } out: { [K in Type]: z.output> } } : {} diff --git a/packages/zod-openapi/test/index.test-d.ts b/packages/zod-openapi/test/index.test-d.ts index 7386e12f6..22f5d77b3 100644 --- a/packages/zod-openapi/test/index.test-d.ts +++ b/packages/zod-openapi/test/index.test-d.ts @@ -1,6 +1,8 @@ import type { Env, Hono, ToSchema } from 'hono' import { assertType, describe, expectTypeOf, it } from 'vitest' import { OpenAPIHono, createRoute, z } from '../src/index' +import type { ExtractSchema } from 'hono/types' +import type { Equal, Expect } from 'hono/utils/types' describe('Types', () => { const RequestSchema = z.object({ @@ -198,3 +200,37 @@ describe('Response schema includes a Date type', () => { ) }) }) + +describe('coerce', () => { + it('Should not throw type errors', () => { + const routes = new OpenAPIHono().openapi( + createRoute({ + method: 'get', + path: '/api/users/{id}', + request: { + params: z.object({ + id: z.coerce.number().openapi({ description: 'userId', example: 1 }), + }), + }, + responses: { + 200: { + description: 'Get a user', + }, + }, + }), + (c) => { + const { id } = c.req.valid('param') + assertType(id) + return c.json({ id }) + } + ) + + type Actual = ExtractSchema['/api/users/:id']['$get']['input'] + type Expected = { + param: { + id: string | undefined + } + } + type verify = Expect> + }) +}) From 30e593605e4f9c72b18dcb66dd56eeebb925d324 Mon Sep 17 00:00:00 2001 From: Yusuke Wada Date: Sun, 7 Jul 2024 12:41:49 +0900 Subject: [PATCH 2/2] add changeset --- .changeset/thirty-waves-play.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/thirty-waves-play.md diff --git a/.changeset/thirty-waves-play.md b/.changeset/thirty-waves-play.md new file mode 100644 index 000000000..73756dfce --- /dev/null +++ b/.changeset/thirty-waves-play.md @@ -0,0 +1,5 @@ +--- +'@hono/zod-openapi': patch +--- + +fix: support `coerce`