0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-22 11:17:33 +01:00

feat!(validator): supports transformation (#2130)

* feat!(validator): supports transformation

* refactored

* denoify
This commit is contained in:
Yusuke Wada 2024-02-02 13:21:08 +09:00 committed by GitHub
parent 14cd5e6e54
commit ebbd444661
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 67 additions and 13 deletions

View File

@ -29,13 +29,22 @@ export const validator = <
M extends string,
U extends ValidationTargetByMethod<M>,
OutputType = ValidationTargets[U],
OutputTypeExcludeResponseType = ExcludeResponseType<OutputType>,
P2 extends string = P,
V extends {
in: { [K in U]: unknown extends InputType ? OutputType : InputType }
out: { [K in U]: ExcludeResponseType<OutputType> }
in: {
[K in U]: K extends 'json'
? InputType
: { [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2] }
}
out: { [K in U]: OutputTypeExcludeResponseType }
} = {
in: { [K in U]: unknown extends InputType ? OutputType : InputType }
out: { [K in U]: ExcludeResponseType<OutputType> }
in: {
[K in U]: K extends 'json'
? InputType
: { [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2] }
}
out: { [K in U]: OutputTypeExcludeResponseType }
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
E extends Env = any

View File

@ -322,8 +322,8 @@ describe('Infer the response/request type', () => {
type Actual = InferRequestType<typeof req>
type Expected = {
age: string
name: string
age: string | string[]
name: string | string[]
}
type verify = Expect<Equal<Expected, Actual['query']>>
})

View File

@ -602,7 +602,7 @@ it('With path parameters', () => {
$put: {
input: {
form: {
title: string
title: string | File
}
} & {
param: {
@ -646,11 +646,11 @@ it('`on`', () => {
$purge: {
input: {
form: {
tag: string
tag: string | File
}
} & {
query: {
q: string
q: string | string[]
}
}
output: {
@ -834,3 +834,39 @@ describe('Validator with using Zod directly', () => {
)
})
})
describe('Transform', () => {
it('Should be number when the type is transformed', () => {
const route = new Hono().get(
'/',
validator('query', async () => {
return {
page: 1,
}
}),
(c) => {
const { page } = c.req.valid('query')
expectTypeOf(page).toEqualTypeOf<number>()
return c.json({ page })
}
)
type Expected = {
'/': {
$get: {
input: {
query: {
page: string | string[]
}
}
output: {
page: number
}
}
}
}
type Actual = ExtractSchema<typeof route>
type verify = Expect<Equal<Expected, Actual>>
})
})

View File

@ -29,13 +29,22 @@ export const validator = <
M extends string,
U extends ValidationTargetByMethod<M>,
OutputType = ValidationTargets[U],
OutputTypeExcludeResponseType = ExcludeResponseType<OutputType>,
P2 extends string = P,
V extends {
in: { [K in U]: unknown extends InputType ? OutputType : InputType }
out: { [K in U]: ExcludeResponseType<OutputType> }
in: {
[K in U]: K extends 'json'
? InputType
: { [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2] }
}
out: { [K in U]: OutputTypeExcludeResponseType }
} = {
in: { [K in U]: unknown extends InputType ? OutputType : InputType }
out: { [K in U]: ExcludeResponseType<OutputType> }
in: {
[K in U]: K extends 'json'
? InputType
: { [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2] }
}
out: { [K in U]: OutputTypeExcludeResponseType }
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
E extends Env = any