2023-02-10 16:18:27 +00:00
|
|
|
import type { Context } from '../context.ts'
|
2023-08-21 06:22:37 +00:00
|
|
|
import { getCookie } from '../helper/cookie/index.ts'
|
2023-02-13 21:21:30 +00:00
|
|
|
import type { Env, ValidationTargets, MiddlewareHandler } from '../types.ts'
|
2022-12-28 02:25:48 +00:00
|
|
|
|
2023-02-13 21:21:30 +00:00
|
|
|
type ValidationTargetKeysWithBody = 'form' | 'json'
|
|
|
|
type ValidationTargetByMethod<M> = M extends 'get' | 'head' // GET and HEAD request must not have a body content.
|
|
|
|
? Exclude<keyof ValidationTargets, ValidationTargetKeysWithBody>
|
|
|
|
: keyof ValidationTargets
|
2023-01-03 00:09:04 +00:00
|
|
|
|
2023-03-15 13:20:50 +00:00
|
|
|
export type ValidationFunction<
|
|
|
|
InputType,
|
|
|
|
OutputType,
|
|
|
|
E extends Env = {},
|
|
|
|
P extends string = string
|
2023-08-07 12:26:53 +00:00
|
|
|
> = (
|
|
|
|
value: InputType,
|
|
|
|
c: Context<E, P>
|
|
|
|
) => OutputType | Response | Promise<OutputType> | Promise<Response>
|
2023-03-11 13:17:08 +00:00
|
|
|
|
2022-12-29 05:59:57 +00:00
|
|
|
export const validator = <
|
2023-03-11 13:17:08 +00:00
|
|
|
InputType,
|
2023-01-22 12:21:37 +00:00
|
|
|
P extends string,
|
|
|
|
M extends string,
|
2023-02-13 21:21:30 +00:00
|
|
|
U extends ValidationTargetByMethod<M>,
|
2023-03-11 13:17:08 +00:00
|
|
|
OutputType = ValidationTargets[U],
|
2023-03-15 13:20:50 +00:00
|
|
|
P2 extends string = P,
|
2023-03-11 13:17:08 +00:00
|
|
|
V extends {
|
|
|
|
in: { [K in U]: unknown extends InputType ? OutputType : InputType }
|
|
|
|
out: { [K in U]: OutputType }
|
|
|
|
} = {
|
|
|
|
in: { [K in U]: unknown extends InputType ? OutputType : InputType }
|
|
|
|
out: { [K in U]: OutputType }
|
|
|
|
},
|
2023-01-16 13:57:47 +00:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
E extends Env = any
|
2022-12-29 05:59:57 +00:00
|
|
|
>(
|
2023-02-13 21:21:30 +00:00
|
|
|
target: U,
|
2023-03-14 14:43:33 +00:00
|
|
|
validationFunc: ValidationFunction<
|
|
|
|
unknown extends InputType ? ValidationTargets[U] : InputType,
|
|
|
|
OutputType,
|
2023-03-15 13:20:50 +00:00
|
|
|
E,
|
|
|
|
P2
|
2023-03-14 14:43:33 +00:00
|
|
|
>
|
2023-01-22 12:21:37 +00:00
|
|
|
): MiddlewareHandler<E, P, V> => {
|
2022-12-29 05:59:57 +00:00
|
|
|
return async (c, next) => {
|
2022-12-28 02:25:48 +00:00
|
|
|
let value = {}
|
|
|
|
|
2023-02-13 21:21:30 +00:00
|
|
|
switch (target) {
|
2022-12-28 02:25:48 +00:00
|
|
|
case 'json':
|
2023-01-02 23:15:23 +00:00
|
|
|
try {
|
2023-08-18 07:25:48 +00:00
|
|
|
value = await c.req.json()
|
2023-01-02 23:15:23 +00:00
|
|
|
} catch {
|
|
|
|
console.error('Error: Malformed JSON in request body')
|
|
|
|
return c.json(
|
|
|
|
{
|
|
|
|
success: false,
|
|
|
|
message: 'Malformed JSON in request body',
|
|
|
|
},
|
|
|
|
400
|
|
|
|
)
|
|
|
|
}
|
2022-12-28 02:25:48 +00:00
|
|
|
break
|
|
|
|
case 'form':
|
2023-08-18 07:25:48 +00:00
|
|
|
value = await c.req.parseBody()
|
2022-12-28 02:25:48 +00:00
|
|
|
break
|
|
|
|
case 'query':
|
2023-03-16 12:49:28 +00:00
|
|
|
value = Object.fromEntries(
|
|
|
|
Object.entries(c.req.queries()).map(([k, v]) => {
|
|
|
|
return v.length === 1 ? [k, v[0]] : [k, v]
|
|
|
|
})
|
|
|
|
)
|
2022-12-28 02:25:48 +00:00
|
|
|
break
|
|
|
|
case 'queries':
|
|
|
|
value = c.req.queries()
|
2023-08-19 08:50:50 +00:00
|
|
|
console.log('Warnings: Validate type `queries` is deprecated. Use `query` instead.')
|
2022-12-28 02:25:48 +00:00
|
|
|
break
|
2023-03-15 13:20:50 +00:00
|
|
|
case 'param':
|
|
|
|
value = c.req.param() as Record<string, string>
|
|
|
|
break
|
2023-08-19 09:23:04 +00:00
|
|
|
case 'header':
|
|
|
|
value = c.req.header()
|
|
|
|
break
|
|
|
|
case 'cookie':
|
|
|
|
value = getCookie(c)
|
|
|
|
break
|
2022-12-28 02:25:48 +00:00
|
|
|
}
|
|
|
|
|
2023-08-07 12:26:53 +00:00
|
|
|
const res = await validationFunc(value as never, c as never)
|
2022-12-28 02:25:48 +00:00
|
|
|
|
2023-08-07 12:26:53 +00:00
|
|
|
if (res instanceof Response) {
|
2022-12-28 02:25:48 +00:00
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2023-02-13 21:21:30 +00:00
|
|
|
c.req.addValidatedData(target, res as never)
|
2022-12-28 02:25:48 +00:00
|
|
|
|
|
|
|
await next()
|
|
|
|
}
|
|
|
|
}
|