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 changesetpull/209/head
parent
d7a703b556
commit
46575b4395
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"@hono/zod-validator": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(zod-validator): make validation input optional when schema is optional
|
|
@ -7,17 +7,25 @@ export type Hook<T, E extends Env, P extends string, O = {}> = (
|
||||||
c: Context<E, P>
|
c: Context<E, P>
|
||||||
) => Response | Promise<Response> | void | Promise<Response | void> | TypedResponse<O>
|
) => Response | Promise<Response> | void | Promise<Response | void> | TypedResponse<O>
|
||||||
|
|
||||||
|
type HasUndefined<T> = undefined extends T ? true : false
|
||||||
|
|
||||||
export const zValidator = <
|
export const zValidator = <
|
||||||
T extends ZodSchema,
|
T extends ZodSchema,
|
||||||
Target extends keyof ValidationTargets,
|
Target extends keyof ValidationTargets,
|
||||||
E extends Env,
|
E extends Env,
|
||||||
P extends string,
|
P extends string,
|
||||||
|
I = z.input<T>,
|
||||||
|
O = z.output<T>,
|
||||||
V extends {
|
V extends {
|
||||||
in: { [K in Target]: z.input<T> }
|
in: HasUndefined<I> extends true
|
||||||
out: { [K in Target]: z.output<T> }
|
? { [K in Target]?: I }
|
||||||
|
: { [K in Target]: I };
|
||||||
|
out: { [K in Target]: O };
|
||||||
} = {
|
} = {
|
||||||
in: { [K in Target]: z.input<T> }
|
in: HasUndefined<I> extends true
|
||||||
out: { [K in Target]: z.output<T> }
|
? { [K in Target]?: I }
|
||||||
|
: { [K in Target]: I };
|
||||||
|
out: { [K in Target]: O };
|
||||||
}
|
}
|
||||||
>(
|
>(
|
||||||
target: Target,
|
target: Target,
|
||||||
|
|
|
@ -9,16 +9,23 @@ type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never
|
||||||
describe('Basic', () => {
|
describe('Basic', () => {
|
||||||
const app = new Hono()
|
const app = new Hono()
|
||||||
|
|
||||||
const schema = z.object({
|
const jsonSchema = z.object({
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
age: z.number(),
|
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 data = c.req.valid('json')
|
||||||
|
const query = c.req.valid('query')
|
||||||
|
|
||||||
return c.jsonT({
|
return c.jsonT({
|
||||||
success: true,
|
success: true,
|
||||||
message: `${data.name} is ${data.age}`,
|
message: `${data.name} is ${data.age}`,
|
||||||
|
queryName: query?.name,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -31,10 +38,15 @@ describe('Basic', () => {
|
||||||
name: string
|
name: string
|
||||||
age: number
|
age: number
|
||||||
}
|
}
|
||||||
|
} & {
|
||||||
|
query?: {
|
||||||
|
name?: string | undefined
|
||||||
|
} | undefined
|
||||||
}
|
}
|
||||||
output: {
|
output: {
|
||||||
success: boolean
|
success: boolean
|
||||||
message: string
|
message: string
|
||||||
|
queryName: string | undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +56,7 @@ describe('Basic', () => {
|
||||||
type verify = Expect<Equal<Expected, Actual>>
|
type verify = Expect<Equal<Expected, Actual>>
|
||||||
|
|
||||||
it('Should return 200 response', async () => {
|
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({
|
body: JSON.stringify({
|
||||||
name: 'Superman',
|
name: 'Superman',
|
||||||
age: 20,
|
age: 20,
|
||||||
|
@ -57,6 +69,7 @@ describe('Basic', () => {
|
||||||
expect(await res.json()).toEqual({
|
expect(await res.json()).toEqual({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Superman is 20',
|
message: 'Superman is 20',
|
||||||
|
queryName: 'Metallo'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue