fix(tbValidator): Fix tbValidator not calling hook when there's a fail case (#742)

* Fix tbValidator not calling hook when there's a fail case

* add tests

* Add changeset
pull/744/head
Lindelwe Michael Ncube 2024-09-24 17:04:59 +07:00 committed by GitHub
parent 58c8e237a9
commit 39cb252df9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 64 additions and 2 deletions

View File

@ -0,0 +1,5 @@
---
'@hono/typebox-validator': patch
---
Fix fail case not returning error array in hook

View File

@ -72,6 +72,15 @@ export function tbValidator<
} }
return data return data
} }
return c.json({ success: false, errors: [...Value.Errors(schema, data)] }, 400)
const errors = Array.from(Value.Errors(schema, data));
if (hook) {
const hookResult = hook({ success: false, errors }, c);
if (hookResult instanceof Response || hookResult instanceof Promise) {
return hookResult;
}
}
return c.json({ success: false, errors }, 400);
}) })
} }

View File

@ -1,7 +1,8 @@
import { Type as T } from '@sinclair/typebox' import { Type as T, TypeBoxError } from '@sinclair/typebox';
import { Hono } from 'hono' import { Hono } from 'hono'
import type { Equal, Expect } from 'hono/utils/types' import type { Equal, Expect } from 'hono/utils/types'
import { tbValidator } from '../src' import { tbValidator } from '../src'
import { ValueError } from '@sinclair/typebox/value';
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never
@ -106,6 +107,18 @@ describe('With Hook', () => {
message: `${data.id} is ${data.title}`, message: `${data.id} is ${data.title}`,
}) })
} }
).post(
'/errorTest',
tbValidator('json', schema, (result, c) => {
return c.json(result, 400)
}),
(c) => {
const data = c.req.valid('json')
return c.json({
success: true,
message: `${data.id} is ${data.title}`,
})
}
) )
it('Should return 200 response', async () => { it('Should return 200 response', async () => {
@ -140,4 +153,39 @@ describe('With Hook', () => {
expect(res).not.toBeNull() expect(res).not.toBeNull()
expect(res.status).toBe(400) expect(res.status).toBe(400)
}) })
it('Should return 400 response and error array', async () => {
const req = new Request('http://localhost/errorTest', {
body: JSON.stringify({
id: 123,
}),
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
const res = await app.request(req)
expect(res).not.toBeNull()
expect(res.status).toBe(400)
const {errors, success} = (await res.json()) as { success: boolean; errors: any[] }
expect(success).toBe(false)
expect(Array.isArray(errors)).toBe(true)
expect(errors.map((e: ValueError) => ({
'type': e?.schema?.type,
path: e?.path,
message: e?.message
}))).toEqual([
{
"type": "string",
"path": "/title",
"message": "Required property"
},
{
"type": "string",
"path": "/title",
"message": "Expected string"
}
])
})
}) })