Skip to content

Instantly share code, notes, and snippets.

@wobsoriano
Last active April 11, 2025 03:30
Show Gist options
  • Save wobsoriano/11f71ed3d10fc1a3500295ef80e8ce40 to your computer and use it in GitHub Desktop.
Save wobsoriano/11f71ed3d10fc1a3500295ef80e8ce40 to your computer and use it in GitHub Desktop.
Nuxt and Zod validation
import * as z from 'zod'
import { defineEventHandler, CompatibilityEvent, useQuery } from 'h3'
const userSchema = z
.object({
name: z.string().min(4, { message: 'Must be 4 or more characters long' }),
age: z.string().transform((age) => parseInt(age, 10))
})
type UnknownKeysParam = "passthrough" | "strict" | "strip";
export type ZodSchema<U extends UnknownKeysParam = any> =
| z.ZodObject<any, U>
| z.ZodUnion<[ZodSchema<U>, ...ZodSchema<U>[]]>
| z.ZodIntersection<ZodSchema<U>, ZodSchema<U>>
| z.ZodDiscriminatedUnion<string, z.Primitive, z.ZodObject<any, U>>;
type ValidationResult<IN extends ZodSchema> = Promise<z.SafeParseSuccess<z.output<IN>> | z.SafeParseError<z.inferFormattedError<IN>>>
async function validateQuery<Input extends ZodSchema>(event: CompatibilityEvent, schema: Input) {
const query = useQuery(event)
const parsed = schema.safeParseAsync(query);
return parsed as ValidationResult<Input>
}
async function validateBody<Input extends ZodSchema>(event: CompatibilityEvent, schema: Input) {
const body = await useBody(event)
const parsed = schema.safeParseAsync(body);
return parsed as ValidationResult<Input>
}
async function validateParams<Input extends ZodSchema>(event: CompatibilityEvent, schema: Input) {
const { params } = event.context
const parsed = schema.safeParseAsync(params);
return parsed as ValidationResult<Input>
}
async function validateEvent<
QueryInput extends ZodSchema,
BodyInput extends ZodSchema,
ParamsInput extends ZodSchema
>(event: CompatibilityEvent, fields: {
query?: QueryInput
body?: BodyInput
params?: ParamsInput
}) {
const queryResult = fields.query ? await validateQuery(event, fields.query) : null
const bodyResult = fields.body ? await validateBody(event, fields.body) : null
const paramsResult = fields.params ? await validateParams(event, fields.params) : null
return {
query: queryResult,
body: bodyResult,
params: paramsResult
}
}
export default defineEventHandler(async(event) => {
const result = await validateEvent(event, {
query: userSchema
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment