3.8 KiB
validateData
Purpose
The recursive workhorse that drives every validator entry point in @suaveplan/bitpacker-validation. validateData(schema, data, path, options) walks schema and data in lockstep, accumulating ValidationReportItem rows into a passed-in collector array as it descends. Every other validation entry point — validateSchema, BitPackerValidator.validate, validateDataReport — ultimately delegates here.
The function is structured around the schema's discriminated union: the top-level switch/if-ladder dispatches by schema kind (object / array / _optional / _oneOf / _enum / etc.) and recurses into the matching branch. Each branch reports a stable code from ErrorCodes so consumers can switch on the failure mode without pattern-matching the message text.
Features
- Single recursive entry point for all validators
- Produces
ValidationReportItemrows with stable codes (INVALID_TYPE,OUT_OF_RANGE,MISSING_FIELD,EXTRA_FIELD,ARRAY_TOO_LONG, …) - Honours
maxErrorsto short-circuit on heavily-malformed input - Honours
checkExtraFieldsto opt into / out of extra-field detection - Composes with
findExtraFieldsandfindArrayLengthErrorsfor the per-rule detail checks - Path-aware reporting via dot-separated
pathfield on each row
Usage: Basic Example
import { validateData, type ValidationReportItem } from "@suaveplan/bitpacker-validation";
const errors: ValidationReportItem[] = [];
validateData(
{ x: 255, name: "-32" },
{ x: 100, name: "ok" },
"",
{ errors, warnings: [], maxErrors: 10, checkExtraFields: true, strictMode: false }
);
console.log(errors); // []
Usage: Advanced Example
import {
validateData,
ErrorCodes,
type ValidationReportItem,
} from "@suaveplan/bitpacker-validation";
function describeViolations(schema: unknown, data: unknown) {
const errors: ValidationReportItem[] = [];
const warnings: ValidationReportItem[] = [];
validateData(schema, data, "$", {
errors,
warnings,
maxErrors: 50,
checkExtraFields: true,
strictMode: true,
});
return errors
.filter((row) => row.code === ErrorCodes.OUT_OF_RANGE)
.map((row) => `${row.path}: ${row.message}`);
}
API Reference
validateData(schema: BitPackerSchema, data: unknown, path: string, ctx: ValidationContext): void
Walks schema and data in lockstep, appending error/warning rows into ctx.errors / ctx.warnings. path is the dot-separated path to the current field ("" at root). ctx carries per-call options and the running accumulators.
The function returns void; results flow through the mutable arrays in ctx. This is hot-path machinery and is structured for minimal allocation per recursion frame.
Implementation Notes
- Mutable accumulators. The function takes the error/warning arrays by reference and pushes into them. This is the cheapest pattern for hot-path validation — allocating a fresh array per recursion frame would dominate the cost.
maxErrorsshort-circuit. Oncectx.errors.length >= ctx.maxErrors, the function stops accumulating and returns immediately. This caps the cost of validating heavily-malformed input. The data is NOT fully traversed in this case.strictModepromotes warnings. WhenstrictMode === true, the function pushes warnings intoctx.errorsinstead ofctx.warnings. Downstream consumers see all rows as errors.- No throwing. The function never throws — it accumulates. The decision to throw is made by the caller based on
throwOnError. This keeps the recursion stack-safe and lets callers decide their failure semantics. - Path format.
path: ""for root,path: "x"for a top-level field,path: "users.3.email"for nested array element with dot+index notation.