From aa055494974eb911ec784e6462691aafefd98125 Mon Sep 17 00:00:00 2001 From: Ame_x <121654029+EdamAme-x@users.noreply.github.com> Date: Sat, 1 Jun 2024 11:35:21 +0900 Subject: [PATCH] fix(zod-validator): validator support async hook (#552) * fix(zod-validator): validator support async hook * fix * changeset * refactor * chore: format (includes other middleware) * fix * revert * Revert "chore: format (includes other middleware)" This reverts commit 16b446201413d7d89c80e00f63a523003b5c2700. * changeset * revert --- .changeset/honest-humans-heal.md | 5 ++ packages/zod-validator/src/index.ts | 10 ++-- packages/zod-validator/test/index.test.ts | 63 ++++++++++++++++++++--- 3 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 .changeset/honest-humans-heal.md diff --git a/.changeset/honest-humans-heal.md b/.changeset/honest-humans-heal.md new file mode 100644 index 00000000..2a3bc32f --- /dev/null +++ b/.changeset/honest-humans-heal.md @@ -0,0 +1,5 @@ +--- +'@hono/zod-validator': patch +--- + +fix: support async hook diff --git a/packages/zod-validator/src/index.ts b/packages/zod-validator/src/index.ts index ec355f41..40777017 100644 --- a/packages/zod-validator/src/index.ts +++ b/packages/zod-validator/src/index.ts @@ -5,7 +5,7 @@ import type { z, ZodSchema, ZodError } from 'zod' export type Hook = ( result: { success: true; data: T } | { success: false; error: ZodError; data: T }, c: Context -) => Response | Promise | void | Promise | TypedResponse +) => Response | void | TypedResponse | Promise> type HasUndefined = undefined extends T ? true : false @@ -45,11 +45,12 @@ export const zValidator = < const result = await schema.safeParseAsync(value) if (hook) { - const hookResult = hook({ data: value, ...result }, c) + const hookResult = await hook({ data: value, ...result }, c) if (hookResult) { - if (hookResult instanceof Response || hookResult instanceof Promise) { + if (hookResult instanceof Response) { return hookResult } + if ('response' in hookResult) { return hookResult.response } @@ -60,6 +61,5 @@ export const zValidator = < return c.json(result, 400) } - const data = result.data as z.infer - return data + return result.data as z.infer }) diff --git a/packages/zod-validator/test/index.test.ts b/packages/zod-validator/test/index.test.ts index a48a49c8..25d57e04 100644 --- a/packages/zod-validator/test/index.test.ts +++ b/packages/zod-validator/test/index.test.ts @@ -159,15 +159,66 @@ describe('With Hook', () => { if (!result.success) { return c.text(`${result.data.id} is invalid!`, 400) } - const data = result.data - return c.text(`${data.id} is valid!`) }), (c) => { const data = c.req.valid('json') - return c.json({ - success: true, - message: `${data.id} is ${data.title}`, - }) + return c.text(`${data.id} is valid!`) + } + ) + + it('Should return 200 response', async () => { + const req = new Request('http://localhost/post', { + body: JSON.stringify({ + id: 123, + title: 'Hello', + }), + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }) + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(200) + expect(await res.text()).toBe('123 is valid!') + }) + + it('Should return 400 response', async () => { + const req = new Request('http://localhost/post', { + body: JSON.stringify({ + id: '123', + title: 'Hello', + }), + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }) + const res = await app.request(req) + expect(res).not.toBeNull() + expect(res.status).toBe(400) + expect(await res.text()).toBe('123 is invalid!') + }) +}) + +describe('With Async Hook', () => { + const app = new Hono() + + const schema = z.object({ + id: z.number(), + title: z.string(), + }) + + app.post( + '/post', + zValidator('json', schema, async (result, c) => { + if (!result.success) { + return c.text(`${result.data.id} is invalid!`, 400) + } + }), + (c) => { + const data = c.req.valid('json') + return c.text(`${data.id} is valid!`) } )