Files
2026-05-27 23:29:53 +01:00

2.9 KiB

Capability Spec: Validation

Package: @suaveplan/validation Version: 0.0.0 (genesis) Status: ADDED


ADDED Requirements

VL-01 — Self-contained schema engine

@suaveplan/validation is its own schema parser — it does NOT depend on Zod. It exposes a Zod-compatible API surface (parse, safeParse, parseAsync, safeParseAsync, refine, transform, optional, nullable) but is implemented independently.

VL-02 — Never-throw contract

.parse() and .parseAsync() MUST throw ValidationError on failure (never raw errors). .safeParse() and .safeParseAsync() MUST return ParseResult<T> and NEVER throw.

VL-03 — ValidationError shape

ValidationError MUST extend SuaveplanError and carry an issues: ValidationIssue[] array. .flatten() MUST return FlattenedErrors with formErrors (top-level issues) and fieldErrors (keyed by path). .format() MUST return a nested error tree. Error codes under VALIDATION.* namespace.

VL-04 — String schema constraints

StringSchema MUST enforce: min, max, length, regex, email, url, uuid, startsWith, endsWith, includes. Transform helpers trim, toLowerCase, toUpperCase MUST mutate the output value, not fail.

VL-05 — Number schema constraints

NumberSchema MUST enforce: min, max, int, positive, negative, multipleOf, finite.

VL-06 — Object schema modes

ObjectSchema MUST support three unknown-key modes: strip (default, drops unknown keys), strict (fails on unknown keys), passthrough (includes unknown keys). .pick(), .omit(), .partial(), .required(), .extend(), .merge() MUST each return a new ObjectSchema without mutating the original.

VL-07 — Union short-circuit

UnionSchema MUST attempt each arm in order and return the result of the first successful parse. If no arm matches, it MUST return ParseFailure with all arm errors listed as issues.

VL-08 — Async refinements

.refine(fn) MUST accept both synchronous and async predicate functions. Async refinements are only awaited via .parseAsync() / .safeParseAsync().

VL-09 — Coerce utilities

coerce(schema) MUST coerce string inputs to the target type before parsing. coerceString, coerceNumber, coerceBoolean, coerceDate are pure functions; a failed coercion returns ParseFailure rather than throwing.

VL-10 — Hooks

Schemas MUST support optional lifecycle hooks { beforeValidate, afterValidate, onError } settable via a .withHooks(hooks) method. Hooks are called synchronously (or awaited in async paths).

VL-11 — OTel instrumentation

validation.parse.success, validation.parse.failure counters and validation.parse.duration_ms histogram MUST be emitted via @opentelemetry/api. All are no-ops without an exporter.

VL-12 — sideEffects: false + coverage 100%

"sideEffects": false with tree-shake test. Vitest thresholds at 100/100/100/100. No .skip / .only in src/.