# @codenhub/validation

> Validation of untrusted input for TypeScript: `email()` and `url()` return what the URL parser read, what a failing input costs is bounded, and an issue the package reports never holds a value of the input. Each validator is a standalone function, so a package or app ships only the checks it uses. Works for a single value such as an email or a port, and for whole objects such as forms. The package is experimental.

A validator takes any input and returns `{ ok: true, value }` or `{ ok: false, error: { issues } }`; it never throws for invalid input. Create one by calling a factory, then call it with the value: `email()(input)`, `number({ int: true, min: 0 })(input)`. Every factory takes its own arguments, then options, then checks, which are rules for rarer cases: `string({ min: 3 }, startsWith("a"))`. Every validator that reports an issue takes a `message` option. Ready-made validators cover strings, numbers, bigints, booleans, symbols, dates, functions, literals and enums, and formats such as email, url, domain, ip, cidr, phone, uuid, datetime, time, duration, semver, slug, jwt, creditCard and port. `url` and `email` take validators for their parts (`url({ host: hostname() })`), `searchParams` reads a query string into typed values, and `formData` a `FormData`, whose files `file` checks for size and declared type and `contentType` for what their first bytes hold. Collections (`array`, `tuple`, `record`, `set`, `map`), `union`, `tagged`, `intersection`, `optional` (with an optional default), `nullable`, `transform` and `lazy` combine them. Build objects with `object`, add rules with `check`, and rules across properties that do not wait for the other properties with `checkFields`, build your own with `format` and `guard`, chain with `pipe`, and read the type a validator produces with `Infer` and the type it accepts with `InferInput`. Text input is converted with the `coerce*` validators, and a `codec(input, output, { decode, encode })` reads a value as it is sent into the value a program uses, which `encode(validator, value)` writes back. `standard(validator)` exposes a validator as a Standard Schema, worded in English unless given a message map, and `standardJsonSchema` also carries its JSON Schema, for libraries such as the AI SDK. `describe` returns what a validator is made of, its kind, options, checks and the validators inside it, as plain data to walk, and `toJsonSchema` writes a validator as a JSON Schema, draft 2020-12 or draft-07, with the title, description and examples `meta` gives a part. `pick`, `omit`, `required`, `partial` and `extend` make a new object validator from one `object` made. `audit(validator)` lists every place a schema leaves the size of what it accepts open, such as a collection without a `max`, for a test to assert there is none. Issues carry a code, a path and params, never the input; `formatIssue` and `flatten` turn them into text, in English unless given another message map: `portugueseMessages` for Portuguese, or your own to reword or localize. `brand(validator, name)` marks the type a validator produces, in the types alone, and `readonly(validator)` makes what it produces read-only in its type and freezes the object or array the validator made, never the input itself or a typed array; a `Map` or a `Set` is kept from change by its type alone. A validator with an asynchronous check is an `AsyncValidator` and must be awaited.

## Documentation

- [Documentation overview](docs/index.md): The idea, results, objects, combining validators, and sync versus async.
- [Validator reference](docs/validators.md): Every validator, check and combinator with its options and the issue it reports, and the parts of `url` and `email`.
- [Custom validators](docs/custom-validators.md): Rules with `check`, validators with `format` and `guard`, asynchronous rules and testing.
- [Coercion](docs/coercion.md): `coerceString`, `coerceNumber`, `coerceBoolean`, `coerceBigint` and `coerceDate` for text input such as environment variables and form fields.
- [Standard Schema](docs/standard-schema.md): `standard(validator, messages?)` for libraries that accept a Standard Schema, and `standardJsonSchema` for those that also read its JSON Schema.
- [JSON Schema](docs/json-schema.md): `toJsonSchema(validator, { io, unrepresentable, target })`, what each validator is written as, input against output, `meta`, the two drafts, and what cannot be written.
- [Integrations](docs/integrations.md): react-hook-form, TanStack Form, tRPC, Hono, the AI SDK, the Model Context Protocol and OpenAPI, and a validator as one field of a zod or valibot schema, each example run against the version it names.
- [Issues and messages](docs/errors.md): The shape of an issue, built-in codes and params, message text, the `message` option, localization and form errors.
- [API reference](docs/reference/index.md): Every export with its signature and documentation, generated from the source.
- [Changelog](docs/changelog/index.md): Release notes, and the migrations from 0.1.0 and from 0.0.1.
