# 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 `ValidationReportItem` rows with stable codes (`INVALID_TYPE`, `OUT_OF_RANGE`, `MISSING_FIELD`, `EXTRA_FIELD`, `ARRAY_TOO_LONG`, …) - Honours `maxErrors` to short-circuit on heavily-malformed input - Honours `checkExtraFields` to opt into / out of extra-field detection - Composes with `findExtraFields` and `findArrayLengthErrors` for the per-rule detail checks - Path-aware reporting via dot-separated `path` field on each row ## Usage: Basic Example ```ts 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 ```ts 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. - **`maxErrors` short-circuit.** Once `ctx.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. - **`strictMode` promotes warnings.** When `strictMode === true`, the function pushes warnings into `ctx.errors` instead of `ctx.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.