@hoajs/zod
Zod validator middleware for Hoa.
zodValidator reads values from ctx.req using the keys you define in the schema:
{ query: z.object({...}) }→ctx.req.query.{ headers: z.object({...}) }→ctx.req.headers.{ params: z.object({...}) }→ctx.req.params(requires@hoajs/routerto populateparams).{ body: z.object({...}) }→ctx.req.body(requires@hoajs/bodyparserto populatebody).- URL parts (
href,origin,protocol,host,hostname,port,pathname,search,hash,method) → corresponding fields onctx.req.
On success, the validated value is written back to ctx.req[key]. On failure, it throws 400 with a merged error message (deduplicated and joined by ; by default).
Quick Start
js
import { Hoa } from 'hoa'
import { router } from '@hoajs/router'
import { z, zodValidator } from '@hoajs/zod'
const app = new Hoa()
app.extend(router())
app.get(
'/users/:name',
zodValidator({
params: z.object({
name: z.string()
}),
// query: z.object({...}),
// headers: z.object({...}),
// body: z.object({...}),
// ...
}),
async (ctx) => {
const name = ctx.req.params.name
ctx.res.body = `Hello, ${name}!`
}
)
export default appExamples
- Validate query parameters
js
app.get(
'/search',
zodValidator({ query: z.object({ key1: z.string(), key2: z.string() }) }),
(ctx) => { ctx.res.body = { valid: ctx.req.query } }
)- Validate headers (preserve undeclared headers)
js
app.use(zodValidator({
headers: z.object({ 'x-foo': z.literal('bar') }).passthrough()
}))
// ctx.req.headers will keep extra headers, e.g. x-extra- Validate URL parts
js
app.use(zodValidator({
url: z.instanceof(URL),
href: z.string().url(),
origin: z.string(),
protocol: z.literal('http:'),
host: z.literal('example.com:8080'),
hostname: z.literal('example.com'),
port: z.literal('8080'),
pathname: z.literal('/users'),
search: z.literal('?id=1'),
hash: z.literal('#frag'),
method: z.literal('GET')
}))Custom error formatting
By default, error messages are de-duplicated and joined by a semicolon. You can customize them:
js
app.use(zodValidator({
query: z.object({ id: z.number() })
}, {
formatError: (err, ctx, key, value) => `Wrong ${key}, got ${value}`
}))or use ctx.throw:
js
app.use(zodValidator({
query: z.object({ id: z.number() })
}, {
formatError: (err, ctx, key, value) => ctx.throw(412, `Wrong ${key}, got ${value}`)
}))