fix(valibot-validator): make validation input optional when schema is optional (#384)
* chore(valibot-validator): Replace `jsonT` in tests * fix(valibot-validator): Handle optional schema * test(valibot-validator): Update tests * chore(valibot-validator): Add changeset * chore(valibot-validator): Fix formattingpull/392/head
parent
df8d403182
commit
9b57c3bb30
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/valibot-validator': patch
|
||||
---
|
||||
|
||||
fix(valibot-validator): make validation input optional when schema is optional
|
|
@ -8,16 +8,22 @@ type Hook<T extends BaseSchema, E extends Env, P extends string> = (
|
|||
c: Context<E, P>
|
||||
) => Response | Promise<Response> | void | Promise<Response | void>
|
||||
|
||||
type HasUndefined<T> = undefined extends T ? true : false
|
||||
|
||||
export const vValidator = <
|
||||
T extends BaseSchema,
|
||||
Target extends keyof ValidationTargets,
|
||||
E extends Env,
|
||||
P extends string,
|
||||
V extends {
|
||||
in: { [K in Target]: Input<T> }
|
||||
in: HasUndefined<Input<T>> extends true
|
||||
? { [K in Target]?: Input<T> }
|
||||
: { [K in Target]: Input<T> }
|
||||
out: { [K in Target]: Output<T> }
|
||||
} = {
|
||||
in: { [K in Target]: Input<T> }
|
||||
in: HasUndefined<Input<T>> extends true
|
||||
? { [K in Target]?: Input<T> }
|
||||
: { [K in Target]: Input<T> }
|
||||
out: { [K in Target]: Output<T> }
|
||||
}
|
||||
>(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Hono } from 'hono'
|
||||
import type { Equal, Expect } from 'hono/utils/types'
|
||||
import { number, object, string } from 'valibot'
|
||||
import { number, object, string, optional } from 'valibot'
|
||||
import { vValidator } from '../src'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
@ -14,13 +14,26 @@ describe('Basic', () => {
|
|||
age: number(),
|
||||
})
|
||||
|
||||
const route = app.post('/author', vValidator('json', schema), (c) => {
|
||||
const data = c.req.valid('json')
|
||||
return c.jsonT({
|
||||
success: true,
|
||||
message: `${data.name} is ${data.age}`,
|
||||
const querySchema = optional(
|
||||
object({
|
||||
search: optional(string()),
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
const route = app.post(
|
||||
'/author',
|
||||
vValidator('json', schema),
|
||||
vValidator('query', querySchema),
|
||||
(c) => {
|
||||
const data = c.req.valid('json')
|
||||
const query = c.req.valid('query')
|
||||
|
||||
return c.json({
|
||||
success: true,
|
||||
message: `${data.name} is ${data.age}, search is ${query?.search}`,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
type Actual = ExtractSchema<typeof route>
|
||||
type Expected = {
|
||||
|
@ -31,6 +44,12 @@ describe('Basic', () => {
|
|||
name: string
|
||||
age: number
|
||||
}
|
||||
} & {
|
||||
query?:
|
||||
| {
|
||||
search?: string | undefined
|
||||
}
|
||||
| undefined
|
||||
}
|
||||
output: {
|
||||
success: boolean
|
||||
|
@ -44,7 +63,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?search=hello', {
|
||||
body: JSON.stringify({
|
||||
name: 'Superman',
|
||||
age: 20,
|
||||
|
@ -59,7 +78,7 @@ describe('Basic', () => {
|
|||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toEqual({
|
||||
success: true,
|
||||
message: 'Superman is 20',
|
||||
message: 'Superman is 20, search is hello',
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue