import { zValidator } from "@hono/zod-validator"; import type { MiddlewareHandler } from "@hono/hono"; import { z } from "zod"; import type { HonoEnv } from "./types.ts"; import { ZodSchema } from "zod/v4"; import { HTTPStatus } from "@oneday/http-status"; import Logging from "@proxnet/undead-logging"; const log = new Logging("Validation"); // thanks claude, this hurt my brain! export const typedZValidator = < T extends 'query' | 'json' | 'form' | 'header' | 'param' | 'cookie', S extends ZodSchema >( target: T, schema: S, httpOk?: boolean, recNetError?: string ) => { return zValidator(target, schema, (result, c) => { if (!result.success) { log.w(`Validation failed: ${JSON.stringify(result.error)}`); if (recNetError) return c.json({ success: false, error: recNetError }, httpOk == true ? HTTPStatus.OK : HTTPStatus.BadRequest); else return c.json({ success: false, error: "Request validation failed" }, httpOk == true ? HTTPStatus.OK : HTTPStatus.BadRequest); } }) as MiddlewareHandler< HonoEnv, string, { in: { [K in T]: z.input }; out: { [K in T]: z.output }; } >; }; /** * @deprecated Use transformCheckEnum after #.coerce.number() (optionally) */ export const transformStringToEnum = (anEnum: { [s: string]: string | number }, str?: boolean) => { return (arg: string, ctx: z.RefinementCtx) => { if (!str) { const int = parseInt(arg); if (isNaN(int) || !Number.isSafeInteger(int)) ctx.addIssue("number was not valid"); else if (anEnum[int]) return int as T; else ctx.addIssue("number was not a valid enum member"); } else { const vals = Object.values(anEnum); if (vals.includes(arg)) return arg as T; else ctx.addIssue("string was not a valid enum member"); } } } export const transformCheckEnum = (anEnum: { [s: string]: string | number }) => { return (arg: number | string, ctx: z.RefinementCtx) => { function invalid() { ctx.addIssue("Invalid enum member"); } if (typeof arg == 'string') { if (typeof anEnum[arg] == 'number') return anEnum[arg] as T; else { invalid(); return null; } } else if (typeof arg == 'number') { if (typeof anEnum[arg] == 'string') return arg as T; else { invalid(); return null; } } else { invalid(); return null; } } }