2022-12-28 03:25:48 +01:00
|
|
|
import type { Context } from '../../context'
|
2023-01-16 14:57:47 +01:00
|
|
|
import type { Env, ValidationTypes, MiddlewareHandler } from '../../types'
|
2022-12-28 03:25:48 +01:00
|
|
|
import { mergeObjects } from '../../utils/object'
|
|
|
|
|
2023-01-03 01:09:04 +01:00
|
|
|
type ValidationTypeKeysWithBody = 'form' | 'json'
|
|
|
|
type ValidationTypeByMethod<M> = M extends 'get' | 'head' // GET and HEAD request must not have a body content.
|
|
|
|
? Exclude<keyof ValidationTypes, ValidationTypeKeysWithBody>
|
|
|
|
: keyof ValidationTypes
|
|
|
|
|
2022-12-29 06:59:57 +01:00
|
|
|
export const validator = <
|
|
|
|
T,
|
2023-01-16 14:57:47 +01:00
|
|
|
Path extends string,
|
2023-01-03 01:09:04 +01:00
|
|
|
Method extends string,
|
|
|
|
U extends ValidationTypeByMethod<Method>,
|
2022-12-29 06:59:57 +01:00
|
|
|
V extends { type: U; data: T },
|
|
|
|
V2 = {},
|
2023-01-16 14:57:47 +01:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
E extends Env = any
|
2022-12-29 06:59:57 +01:00
|
|
|
>(
|
2022-12-28 03:25:48 +01:00
|
|
|
type: U,
|
2023-01-02 06:37:17 +01:00
|
|
|
validationFunc: (value: ValidationTypes[U], c: Context<E>) => T | Response | Promise<Response>
|
2023-01-16 14:57:47 +01:00
|
|
|
): MiddlewareHandler<E, Path, V | V2> => {
|
2022-12-29 06:59:57 +01:00
|
|
|
return async (c, next) => {
|
2022-12-28 03:25:48 +01:00
|
|
|
let value = {}
|
|
|
|
|
2022-12-29 06:59:57 +01:00
|
|
|
switch (type) {
|
2022-12-28 03:25:48 +01:00
|
|
|
case 'json':
|
2023-01-03 00:15:23 +01:00
|
|
|
try {
|
|
|
|
value = await c.req.json()
|
|
|
|
} catch {
|
|
|
|
console.error('Error: Malformed JSON in request body')
|
|
|
|
return c.json(
|
|
|
|
{
|
|
|
|
success: false,
|
|
|
|
message: 'Malformed JSON in request body',
|
|
|
|
},
|
|
|
|
400
|
|
|
|
)
|
|
|
|
}
|
2022-12-28 03:25:48 +01:00
|
|
|
break
|
|
|
|
case 'form':
|
|
|
|
value = await c.req.parseBody()
|
|
|
|
break
|
|
|
|
case 'query':
|
|
|
|
value = c.req.query()
|
|
|
|
break
|
|
|
|
case 'queries':
|
|
|
|
value = c.req.queries()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2023-01-03 01:09:04 +01:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
const res = validationFunc(value, c as any)
|
2022-12-28 03:25:48 +01:00
|
|
|
|
2022-12-29 06:59:57 +01:00
|
|
|
if (res instanceof Response || res instanceof Promise) {
|
2022-12-28 03:25:48 +01:00
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
const target = c.req.valid()
|
|
|
|
const newObject = mergeObjects(target, res)
|
|
|
|
|
|
|
|
c.req.valid(newObject)
|
|
|
|
await next()
|
|
|
|
}
|
|
|
|
}
|