Standard Schema result mapping
SQLBraid depends on the Standard Schema protocol, not on a particular validator. A schema can be bound to a query:
import * as v from "valibot";import { sql } from "sqlbraid/postgres";
const EventSchema = v.object({ id: v.pipe(v.string(), v.transform(Number)), payload: v.string(),});
const events = sql.rows(EventSchema)` SELECT id, payload FROM events`;const rows = await db.all(events);The schema output becomes the query row type. Mapping applies consistently to all, one, maybeOne, batch, prepared queries, streams, and transaction-scoped operations. An execution-level schema is additive:
await db.all(events, { schema: ExtraSchema });Exact database numerics arrive as strings; approximate IEEE values arrive as numbers. Choose application semantics in the schema rather than changing the driver profile:
const Account = v.object({ id: v.pipe(v.string(), v.transform(BigInt)), amount: v.string(), // or v.transform(value => new Decimal(value))});Decimal/Money objects are application choices and are not SQLBraid
dependencies. A schema cannot recover precision already lost by a parsed JSON
number or a native temporal Date. For JSON nested numerics, use a
lossless-text profile and an application-selected parser; for fractional or
offset temporal fidelity, use a tested text profile or an authored SQL
conversion.
Routine contracts map their channels independently. sql.call({ output, resultSets: [UserSchema, PaymentSchema] as const, returnValue }) applies the
output schema to the scalar object, each tuple schema to rows in its matching
result set, and the return schema to the actual return/status value. When a
returnValue schema is declared, successful db.call() results have a required
returnValue property with that schema’s output type; a missing driver channel
fails with BRAID_CALL_RETURN_UNSUPPORTED. Bare and no-return-schema contracts
keep the property optional. Cursor
outputs are removed from scalar output; adapters consume and close their
resources before asynchronous mapping begins. A result-set count mismatch is
BRAID_CALL_RESULT_SETS, and a failed routine location is reported by
BRAID_CALL_MAP.
The pipeline is:
driver row -> dialect TypePolicy normalization -> plain row -> query schema -> execution schema -> application modelDatabaseResultValidationError uses code BRAID_RESULT_VALIDATION, reports the query or execution stage and row index, and does not dump raw rows or binds. Mapping is one row to one row: SQLBraid does not hydrate relations, maintain identity maps, or assemble object graphs.
The input side is deliberately smaller in 0.1.0. Ordinary value interpolation
remains a driver-bound value; there is no universal application input codec
framework yet. Exact numeric bind fidelity is a separate driver capability, and
undefined ordinary IN values fail before acquisition while null means SQL
NULL. Driver-specific JSON, temporal, and binary conventions remain the
driver’s responsibility.