# `validate` _(no submodules)_ ## Purpose Owns the default tenant-id validator regex and the validator / registry function signatures consumed by `createHeaderTenantResolver`. Splitting the validator surface out of `resolver.ts` keeps the resolver implementation a pure orchestrator (regex check → registry probe → trust check → return) and lets hosts substitute alternative validators without monkey-patching the factory. The default validator (`^[a-z0-9-]{1,64}$`) is deliberately conservative — it admits the shape of a typical slug-style identifier and rejects everything else. Hosts whose tenant ids are UUIDs, prefixed strings, or arbitrary unicode must pass an explicit `validate` option. ## Features - `DEFAULT_TENANT_ID_PATTERN` exported as a `RegExp` so hosts can extend rather than re-derive (`new RegExp(...|extra-form)`). - `defaultTenantIdValidator` — boolean function backed by the pattern. - `TenantIdValidator` and `TenantRegistryProbe` type aliases so host wiring is explicit. ## Usage: Basic ```ts import { defaultTenantIdValidator } from "@suaveplan/api-tenant-resolver-header/validate"; defaultTenantIdValidator("acme"); // true defaultTenantIdValidator("ACME"); // false (uppercase rejected) defaultTenantIdValidator(""); // false (zero-length rejected) ``` ## Usage: Advanced ```ts import type { TenantIdValidator, TenantRegistryProbe, } from "@suaveplan/api-tenant-resolver-header/validate"; const uuidValidator: TenantIdValidator = (v) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(v); const registry: TenantRegistryProbe = async (tid) => (await tenantProvider.lookup(tid as never)) !== null; ``` ## API Reference - `const DEFAULT_TENANT_ID_PATTERN: RegExp` — `^[a-z0-9-]{1,64}$`. - `const defaultTenantIdValidator: TenantIdValidator` — applies the default pattern; returns boolean. - `type TenantIdValidator = (value: string) => boolean` — synchronous validator contract. - `type TenantRegistryProbe = (tenantId: string) => boolean | Promise` — sync-or-async registry membership probe. ## Implementation Notes The validator is intentionally synchronous: the regex check is the zero-I/O happy path, and a synchronous boolean lets the resolver avoid an `await` micro-task in the common-case good-tenant path. Registry probes can be async because the host may back them with a real `TenantProvider.lookup` that hits a database; the resolver awaits the probe only after the regex check has already passed so a bad value never leaks into the registry call. The default pattern's 64-character cap is the same maximum used by `api-tenant-provider`'s seed schema; widening it here without widening it there would produce values the resolver accepts but the registry refuses.