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>
|
c: Context<E, P>
|
||||||
) => Response | Promise<Response> | void | Promise<Response | void>
|
) => Response | Promise<Response> | void | Promise<Response | void>
|
||||||
|
|
||||||
|
type HasUndefined<T> = undefined extends T ? true : false
|
||||||
|
|
||||||
export const vValidator = <
|
export const vValidator = <
|
||||||
T extends BaseSchema,
|
T extends BaseSchema,
|
||||||
Target extends keyof ValidationTargets,
|
Target extends keyof ValidationTargets,
|
||||||
E extends Env,
|
E extends Env,
|
||||||
P extends string,
|
P extends string,
|
||||||
V extends {
|
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> }
|
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> }
|
out: { [K in Target]: Output<T> }
|
||||||
}
|
}
|
||||||
>(
|
>(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
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 { number, object, string } from 'valibot'
|
import { number, object, string, optional } from 'valibot'
|
||||||
import { vValidator } from '../src'
|
import { vValidator } from '../src'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
@ -14,13 +14,26 @@ describe('Basic', () => {
|
||||||
age: number(),
|
age: number(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const route = app.post('/author', vValidator('json', schema), (c) => {
|
const querySchema = optional(
|
||||||
const data = c.req.valid('json')
|
object({
|
||||||
return c.jsonT({
|
search: optional(string()),
|
||||||
success: true,
|
|
||||||
message: `${data.name} is ${data.age}`,
|
|
||||||
})
|
})
|
||||||
})
|
)
|
||||||
|
|
||||||
|
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 Actual = ExtractSchema<typeof route>
|
||||||
type Expected = {
|
type Expected = {
|
||||||
|
@ -31,6 +44,12 @@ describe('Basic', () => {
|
||||||
name: string
|
name: string
|
||||||
age: number
|
age: number
|
||||||
}
|
}
|
||||||
|
} & {
|
||||||
|
query?:
|
||||||
|
| {
|
||||||
|
search?: string | undefined
|
||||||
|
}
|
||||||
|
| undefined
|
||||||
}
|
}
|
||||||
output: {
|
output: {
|
||||||
success: boolean
|
success: boolean
|
||||||
|
@ -44,7 +63,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?search=hello', {
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: 'Superman',
|
name: 'Superman',
|
||||||
age: 20,
|
age: 20,
|
||||||
|
@ -59,7 +78,7 @@ describe('Basic', () => {
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200)
|
||||||
expect(await res.json()).toEqual({
|
expect(await res.json()).toEqual({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Superman is 20',
|
message: 'Superman is 20, search is hello',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue