Files
skills/docs/foundation/data/validation/README.md
2026-05-29 08:20:56 +01:00

122 lines
22 KiB
Markdown

# @suaveplan/validation - Runtime schema validation with Zod-compatible API — self-contained parse engine, exhaustive schema types, async refinements, hooks, structured errors
## Summary
Runtime schema validation with a Zod-compatible API. This package is a self-contained parse engine — it does not import Zod or any other validation library — so it is safe to use in environments where Zod is absent or where bundle size is a constraint. It covers the full schema surface expected from a production validator: all primitive and composite types, `parse`/`safeParse`/`parseAsync`, `refine` (sync + async), `transform`, `describe`, object shape builders (`pick`, `omit`, `partial`, `extend`, `merge`), three unknown-key modes, async lifecycle hooks, and composable helpers (`pipe`, `mergeResults`). Structured errors surface via `@suaveplan/error` with stable `VALIDATION.*` codes. When Zod is already a project dependency and you need its ecosystem (inference helpers, plugins), use Zod directly; use this package for internal platform code and zero-dep environments.
<!-- begin:auto-docs -->
## Documentation tree
- [schema](./src/core/schema/schema.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [schema](./src/core/schema/schema.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [validation-otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [common](./src/types/common.md) — `common.ts` defines the core type contracts shared across the entire `@suaveplan/validation` package: validation codes,…
- [validation-hooks](./src/types/validation-hooks.md) — `validation-hooks.ts` defines the lifecycle hook types for schema validation observability. These hooks allow consumers…
- [coerce](./src/utils/coerce.md) — The coerce utilities allow schemas to accept a broader range of input types by converting them before validation. They…
- [compose](./src/utils/compose.md) — The compose utilities provide functional combinators for working with validation results and schemas. `mergeResults` ag…
<!-- end:auto-docs --> - [schema](./src/core/schema/schema.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation-otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_- [common](./src/types/common.md) — `common.ts` defines the core type contracts shared across the entire `@suaveplan/validation` package: validation codes,…
- [validation-hooks](./src/types/validation-hooks.md) — `validation-hooks.ts` defines the lifecycle hook types for schema validation observability. These hooks allow consumers…
- [coerce](./src/utils/coerce.md) — The coerce utilities allow schemas to accept a broader range of input types by converting them before validation. They…
- [compose](./src/utils/compose.md) — The compose utilities provide functional combinators for working with validation results and schemas. `mergeResults` ag…
- [schema](./src/core/schema/schema.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation-otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_- [common](./src/types/common.md) — `common.ts` defines the core type contracts shared across the entire `@suaveplan/validation` package: validation codes,…
- [validation-hooks](./src/types/validation-hooks.md) — `validation-hooks.ts` defines the lifecycle hook types for schema validation observability. These hooks allow consumers…
- [coerce](./src/utils/coerce.md) — The coerce utilities allow schemas to accept a broader range of input types by converting them before validation. They…
- [compose](./src/utils/compose.md) — The compose utilities provide functional combinators for working with validation results and schemas. `mergeResults` ag…
- [schema](./src/core/schema/schema.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [validation-otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_- [common](./src/types/common.md) — `common.ts` defines the core type contracts shared across the entire `@suaveplan/validation` package: validation codes,…
- [validation-hooks](./src/types/validation-hooks.md) — `validation-hooks.ts` defines the lifecycle hook types for schema validation observability. These hooks allow consumers…
- [coerce](./src/utils/coerce.md) — The coerce utilities allow schemas to accept a broader range of input types by converting them before validation. They…
- [compose](./src/utils/compose.md) — The compose utilities provide functional combinators for working with validation results and schemas. `mergeResults` ag…
- [schema](./src/core/schema/schema.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ - [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [validation-otel](./src/otel/validation-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_ - [array](./src/schemas/array/array.md) — <!-- begin:auto-docs --> _(no submodules)_- [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_ - [boolean](./src/schemas/boolean/boolean.md) — <!-- begin:auto-docs --> _(no submodules)_- [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_ - [date](./src/schemas/date/date.md) — <!-- begin:auto-docs --> _(no submodules)_- [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_ - [enum](./src/schemas/enum/enum.md) — <!-- begin:auto-docs --> _(no submodules)_- [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_ - [intersection](./src/schemas/intersection/intersection.md) — <!-- begin:auto-docs --> _(no submodules)_- [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_ - [literal](./src/schemas/literal/literal.md) — <!-- begin:auto-docs --> _(no submodules)_- [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_ - [nullable](./src/schemas/nullable/nullable.md) — <!-- begin:auto-docs --> _(no submodules)_- [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_ - [number](./src/schemas/number/number.md) — <!-- begin:auto-docs --> _(no submodules)_- [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_ - [object](./src/schemas/object/object.md) — <!-- begin:auto-docs --> _(no submodules)_- [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_ - [optional](./src/schemas/optional/optional.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_ - [record](./src/schemas/record/record.md) — <!-- begin:auto-docs --> _(no submodules)_- [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_ - [string](./src/schemas/string/string.md) — <!-- begin:auto-docs --> _(no submodules)_- [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_ - [tuple](./src/schemas/tuple/tuple.md) — <!-- begin:auto-docs --> _(no submodules)_- [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_ - [union](./src/schemas/union/union.md) — <!-- begin:auto-docs --> _(no submodules)_- [common](./src/types/common.md) — `common.ts` defines the core type contracts shared across the entire `@suaveplan/validation` package: validation codes,…
- [validation-hooks](./src/types/validation-hooks.md) — `validation-hooks.ts` defines the lifecycle hook types for schema validation observability. These hooks allow consumers…
- [coerce](./src/utils/coerce.md) — The coerce utilities allow schemas to accept a broader range of input types by converting them before validation. They…
- [compose](./src/utils/compose.md) — The compose utilities provide functional combinators for working with validation results and schemas. `mergeResults` ag…
## Features
- Exhaustive schema types: `string`, `number`, `boolean`, `date`, `array`, `object`, `record`, `tuple`, `literal`, `enum`, `union`, `intersection`, `optional`, `nullable`
- `parse()` / `safeParse()` / `parseAsync()` / `safeParseAsync()` — `parse()` and `safeParse()` throw `VALIDATION.ASYNC_REFINEMENT_REQUIRES_PARSEASYNC` when the schema carries any async refinement (no silent skip; use `parseAsync()` for async-refined schemas)
- `refine()` (sync and async), `transform()`, `describe()`
- Object shape builders: `pick`, `omit`, `partial`, `extend`, `merge`, three unknown-key modes
- Input coercion utilities: `coerce`, `coerceString`, `coerceNumber`, `coerceBoolean`, `coerceDate`
- Functional combinators: `mergeResults`, `pipe`
- Structured errors: `ValidationError` with `flatten()` and `format()`, 21 typed codes
- OTel instrumentation: success/failure counters and duration histogram
- `Infer<S>` type helper for extracting output types
## Quick Start
```typescript
import { object, string, number, array, Infer } from "@suaveplan/validation";
const UserSchema = object({
id: string().uuid(),
name: string().min(1).max(100),
age: number().int().min(0),
tags: array(string()).max(10),
});
type User = Infer<typeof UserSchema>;
const result = UserSchema.safeParse({ id: "550e8400-e29b-41d4-a716-446655440000", name: "Alice", age: 30, tags: [] });
if (result.success) {
console.log(result.data);
} else {
const { formErrors, fieldErrors } = result.error.flatten();
console.error(formErrors, fieldErrors);
}
```
## Module Docs
- [Core engine](src/core/schema/schema.md)
- [Errors](src/errors/errors.md)
- [StringSchema](src/schemas/string/string.md)
- [NumberSchema](src/schemas/number/number.md)
- [BooleanSchema](src/schemas/boolean/boolean.md)
- [DateSchema](src/schemas/date/date.md)
- [ArraySchema](src/schemas/array/array.md)
- [ObjectSchema](src/schemas/object/object.md)
- [RecordSchema](src/schemas/record/record.md)
- [TupleSchema](src/schemas/tuple/tuple.md)
- [OptionalSchema](src/schemas/optional/optional.md)
- [NullableSchema](src/schemas/nullable/nullable.md)
- [LiteralSchema](src/schemas/literal/literal.md)
- [EnumSchema](src/schemas/enum/enum.md)
- [UnionSchema](src/schemas/union/union.md)
- [IntersectionSchema](src/schemas/intersection/intersection.md)
- [Coerce utilities](src/utils/coerce.md)
- [Compose utilities](src/utils/compose.md)
- [OTel instrumentation](src/otel/validation-otel.md)