diff --git a/apps/backend/src/utils/requestValidator.ts b/apps/backend/src/utils/requestValidator.ts index 4e2b4fd..7a99648 100644 --- a/apps/backend/src/utils/requestValidator.ts +++ b/apps/backend/src/utils/requestValidator.ts @@ -1,7 +1,33 @@ import { zValidator } from "@hono/zod-validator"; import DashboardError from "../errors/DashboardError"; - -type ValidatorParameters = Parameters; +import type { + Context, + MiddlewareHandler, + Env, + ValidationTargets, + TypedResponse, + Input, +} from "hono"; +import type { z, ZodError } from "zod"; +export type Hook = ( + result: + | { + success: true; + data: T; + } + | { + success: false; + error: ZodError; + data: T; + }, + c: Context +) => + | Response + | Promise + | void + | Promise + | TypedResponse; +type HasUndefined = undefined extends T ? true : false; /** * Creates a request validator using the Zod schema. @@ -12,11 +38,60 @@ type ValidatorParameters = Parameters; * the second is options for the Zod validator, and the third is a custom error handler. * @returns A middleware function that validates the request against the provided schema. */ -const requestValidator = (...parameters: ValidatorParameters) => { +function requestValidator< + T extends z.ZodType, + Target extends keyof ValidationTargets, + E extends Env, + P extends string, + In = z.input, + Out = z.output, + I extends Input = { + in: HasUndefined extends true + ? { + [K in Target]?: + | (K extends "json" + ? In + : HasUndefined< + keyof ValidationTargets[K] + > extends true + ? { + [K2 in keyof In]?: + | ValidationTargets[K][K2] + | undefined; + } + : { + [K2_1 in keyof In]: ValidationTargets[K][K2_1]; + }) + | undefined; + } + : { + [K_1 in Target]: K_1 extends "json" + ? In + : HasUndefined< + keyof ValidationTargets[K_1] + > extends true + ? { + [K2_2 in keyof In]?: + | ValidationTargets[K_1][K2_2] + | undefined; + } + : { + [K2_3 in keyof In]: ValidationTargets[K_1][K2_3]; + }; + }; + out: { [K_2 in Target]: Out }; + }, + V extends I = I, +>( + target: Target, + schema: T, + hook?: Hook, E, P, {}> | undefined +): MiddlewareHandler { + //@ts-ignore return zValidator( - parameters[0], - parameters[1], - parameters[2] ?? + target, + schema, + hook ?? ((result) => { if (!result.success) { let errors = result.error.flatten().fieldErrors as Record< @@ -38,6 +113,6 @@ const requestValidator = (...parameters: ValidatorParameters) => { } }) ); -}; +} export default requestValidator;