OptionalenginesSchema engines to make resolvable from the container, keyed by the name to resolve them under.
import { z } from 'zod'
blueprint.set('stone.validation.engines', { zod: z })
A schema class then takes its engine through its constructor, which is both more elegant and more testable: a test hands it a fake instead of mocking a module.
@ValidationSchema('createUser')
export class CreateUserSchema implements IValidationSchema {
constructor ({ zod }: { zod: typeof z }) { this.z = zod }
rules () { return { body: this.z.object({ email: this.z.string().email() }) } }
}
The application names the engine; this module never imports one. That is what keeps it agnostic: Zod, Valibot and ArkType arrive through Standard Schema, and a native schema needs no engine at all. Binding a specific library here would make every application depend on it.
OptionalschemasNamed rule sets a route can refer to by name, instead of importing the schemas at the route.
blueprint.set('stone.validation.schemas', { createUser: { body: CreateUserSchema } })
// then, on the route: { validation: 'createUser' }
Naming a rule set that is not registered fails loudly at request time rather than validating nothing, because silently accepting anything is the one outcome a validator must never have.
Validation configuration (
stone.validation.*).