fix(zod-validator): make validation input optional when schema is optional (#208)

* fix(zod-validator): make validation input optional when schema is optional

* feat(index.test.ts): add tests for optional schema

* feat(index.test.ts): add more tests for optional schema

* chore: add changeset
pull/209/head
Andrew 2023-10-22 22:18:23 +02:00 committed by GitHub
parent d7a703b556
commit 46575b4395
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 7 deletions

View File

@ -0,0 +1,5 @@
---
"@hono/zod-validator": patch
---
fix(zod-validator): make validation input optional when schema is optional

View File

@ -7,17 +7,25 @@ export type Hook<T, E extends Env, P extends string, O = {}> = (
c: Context<E, P>
) => Response | Promise<Response> | void | Promise<Response | void> | TypedResponse<O>
type HasUndefined<T> = undefined extends T ? true : false
export const zValidator = <
T extends ZodSchema,
Target extends keyof ValidationTargets,
E extends Env,
P extends string,
I = z.input<T>,
O = z.output<T>,
V extends {
in: { [K in Target]: z.input<T> }
out: { [K in Target]: z.output<T> }
in: HasUndefined<I> extends true
? { [K in Target]?: I }
: { [K in Target]: I };
out: { [K in Target]: O };
} = {
in: { [K in Target]: z.input<T> }
out: { [K in Target]: z.output<T> }
in: HasUndefined<I> extends true
? { [K in Target]?: I }
: { [K in Target]: I };
out: { [K in Target]: O };
}
>(
target: Target,

View File

@ -9,16 +9,23 @@ type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never
describe('Basic', () => {
const app = new Hono()
const schema = z.object({
const jsonSchema = z.object({
name: z.string(),
age: z.number(),
})
const route = app.post('/author', zValidator('json', schema), (c) => {
const querySchema = z.object({
name: z.string().optional()
}).optional()
const route = app.post('/author', zValidator('json', jsonSchema), zValidator('query', querySchema), (c) => {
const data = c.req.valid('json')
const query = c.req.valid('query')
return c.jsonT({
success: true,
message: `${data.name} is ${data.age}`,
queryName: query?.name,
})
})
@ -31,10 +38,15 @@ describe('Basic', () => {
name: string
age: number
}
} & {
query?: {
name?: string | undefined
} | undefined
}
output: {
success: boolean
message: string
queryName: string | undefined
}
}
}
@ -44,7 +56,7 @@ describe('Basic', () => {
type verify = Expect<Equal<Expected, Actual>>
it('Should return 200 response', async () => {
const req = new Request('http://localhost/author', {
const req = new Request('http://localhost/author?name=Metallo', {
body: JSON.stringify({
name: 'Superman',
age: 20,
@ -57,6 +69,7 @@ describe('Basic', () => {
expect(await res.json()).toEqual({
success: true,
message: 'Superman is 20',
queryName: 'Metallo'
})
})