/** * Contract interface for schema validation. * * Default implementation: `@veryfront/ext-schema-zod` * * The interface exposes a small DSL (inspired by zod) that lets core modules * declare validation schemas without importing zod directly. Schemas are * constructed lazily via `defineSchema()` so that an extension-provided * implementation can be registered before any schema is materialized. * * @module extensions/schema/schema-validator */ import type { JsonSchema } from "./json-schema.js"; /** * An opaque schema definition that validates and infers type `T`. * * Implementations may use this as a nominal wrapper around a native validator * (e.g. a zod schema). Core code only calls the methods defined here. */ export interface Schema { /** Brand field for nominal typing — not used at runtime. */ readonly _output: T; optional(): Schema; nullable(): Schema; nullish(): Schema; default(value: Exclude | (() => Exclude)): Schema>; describe(description: string): Schema; refine(check: (value: T) => boolean, message?: string | { message?: string; }): Schema; /** * Multi-issue refinement. The callback receives the parsed value and a * `RefinementCtx` it can use to emit one or more issues via `addIssue`. * Mirrors zod's `.superRefine`. */ superRefine(check: (value: T, ctx: RefinementCtx) => void): Schema; transform(fn: (value: T) => U): Schema; strict(): Schema; /** * Strip unknown keys from object inputs (zod's default behavior). Exposed * for parity with `.strict()` / `.passthrough()` so call sites can be * explicit about their intent. */ strip(): Schema; passthrough(): Schema>; partial(): Schema>; extend>>(shape: U): Schema; }>; merge(other: Schema): Schema; /** Drop the listed keys from an object schema. Mirrors zod's `.omit({k: true})`. */ omit(keys: { [P in K]?: true; }): Schema>; /** Keep only the listed keys from an object schema. Mirrors zod's `.pick({k: true})`. */ pick(keys: { [P in K]?: true; }): Schema>; min(value: number, message?: string): Schema; max(value: number, message?: string): Schema; int(message?: string): Schema; positive(message?: string): Schema; nonnegative(message?: string): Schema; regex(pattern: RegExp, message?: string): Schema; email(message?: string): Schema; url(message?: string): Schema; uuid(message?: string): Schema; datetime(message?: string): Schema; /** * Feed parsed output into another schema for further validation/refinement. * Mirrors zod's `.pipe(otherSchema)`. */ pipe(next: Schema): Schema; parse(data: unknown): T; safeParse(data: unknown): ValidationResult; } /** * Context passed to a `superRefine` callback. Provides `addIssue` to emit * one or more validation issues and `path` to locate the current value. * * Mirrors the subset of zod's `RefinementCtx` we actually use. */ export interface RefinementCtx { /** Emit a validation issue against the parsed value. */ addIssue(issue: { code?: string; message: string; path?: (string | number)[]; }): void; /** Path to the current value within its parent — used when emitting issues. */ readonly path: (string | number)[]; } /** Extracts the inferred output type `T` from a `Schema`. */ export type InferSchema = S extends Schema ? T : never; /** * Extracts the inferred *input* type from a `Schema`. * * Today the contract DSL does not formally model input/output divergence * (zod's `.transform()` is the canonical case where they differ), so this * is an alias of `InferSchema`. Reserved as a separate type for forward * compatibility — callers migrating from `z.input` should use * this name. */ export type InferInput = InferSchema; /** Maps a raw object shape to its inferred object type, preserving optionality. */ export type InferShape>> = { [K in keyof S as undefined extends InferSchema ? never : K]: InferSchema; } & { [K in keyof S as undefined extends InferSchema ? K : never]?: InferSchema; }; /** A single validation issue with location context. */ export interface ValidationIssue { /** Dot-path to the offending field (e.g. `"user.email"`). */ path: (string | number)[]; /** Human-readable error message. */ message: string; /** Machine-readable error code. */ code?: string; } /** Successful validation outcome. */ export interface ValidationSuccess { success: true; /** Parsed and validated data. */ data: T; } /** Failed validation outcome. */ export interface ValidationFailure { success: false; /** List of issues found during validation. */ issues: ValidationIssue[]; /** Native error thrown by the underlying validator (if any). */ error?: unknown; } /** Discriminated union of validation outcomes. */ export type ValidationResult = ValidationSuccess | ValidationFailure; /** Stable validation issue copied from a JSON Schema validator result. */ export interface JsonSchemaValidationIssue { /** JSON Pointer to the invalid value. */ instancePath: string; /** JSON Pointer to the failed schema keyword. */ schemaPath: string; /** JSON Schema keyword that failed. */ keyword: string; /** Keyword-specific diagnostic values. */ params: Readonly>; /** Human-readable validator diagnostic, when available. */ message?: string; } /** Successful validation of an input against a compiled JSON Schema. */ export interface JsonSchemaValidationSuccess { success: true; /** Stable, validator-owned JSON snapshot of the accepted input. */ value: T; } /** Failed validation of an input against a compiled JSON Schema. */ export interface JsonSchemaValidationFailure { success: false; /** Validator issues copied before a subsequent validation can replace them. */ errors: readonly JsonSchemaValidationIssue[]; } /** Result returned by a compiled JSON Schema validator. */ export type JsonSchemaValidationResult = JsonSchemaValidationSuccess | JsonSchemaValidationFailure; /** Compiled, reusable JSON Schema validation function. */ export type JsonSchemaValidationFunction = (input: unknown) => JsonSchemaValidationResult | PromiseLike>; /** * Namespace for `coerce.*` constructors — accepts input in any form and * coerces to the target type before validation. */ export interface SchemaValidatorCoerce { string(): Schema; number(): Schema; boolean(): Schema; date(): Schema; } /** * SchemaValidator contract interface. * * Exposes a zod-inspired DSL. The `object(shape)`, `array(schema)`, etc. * constructors produce opaque `Schema` instances that can be further * refined via chainables and finally validated with `.parse` / `.safeParse`. */ export interface SchemaValidator { string(): Schema; number(): Schema; boolean(): Schema; date(): Schema; null(): Schema; unknown(): Schema; bigint(): Schema; any(): Schema; function(): Schema<(...args: unknown[]) => unknown>; object>>(shape: S): Schema>; array(element: Schema): Schema; tuple[]>(items: T): Schema<{ [K in keyof T]: T[K] extends Schema ? U : never; }>; record(keys: Schema, values: Schema): Schema>; union, ...Schema[]]>(schemas: T): Schema>; discriminatedUnion, ...Schema[]]>(discriminator: K, schemas: T): Schema>; literal(value: T): Schema; enum(values: T): Schema; /** * Defer schema construction — used for recursive shapes. The thunk is * called on first access; the result is cached. Mirrors `z.lazy`. */ lazy(factory: () => Schema): Schema; /** * Validates that input is an instance of the given constructor. Mirrors * `z.instanceof`. */ instanceof(ctor: new (...args: never[]) => T): Schema; /** * Loosely-typed escape hatch: accept input when `check` returns `true`. * The runtime contract is the predicate; the type parameter `T` is purely * structural and is trusted from the call site. Mirrors `z.custom`. */ custom(check?: (value: unknown) => boolean, message?: string): Schema; /** Coercing constructors — accept any input and coerce to the target. */ coerce: SchemaValidatorCoerce; /** * Convenience that runs validation on an already-constructed schema. * Equivalent to `schema.safeParse(data)`; kept for ergonomic parity with * earlier revisions of this contract. */ validate(schema: Schema, data: unknown): ValidationResult; /** * Compile a JSON Schema into a reusable, non-mutating validator. * * Implementations must snapshot schemas and inputs through bounded, * descriptor-based data reads before invoking a compiler. An invalid schema * causes compilation to throw. Invalid input returns a validation failure. * Accessors, proxies that cannot be inspected, cycles, and non-JSON object * prototypes are rejected without invoking property getters, setters, * iterators, or serialization hooks. Proxy reflection traps necessarily run * during inspection and may throw before rejection. Successful validation * returns the accepted snapshot rather than caller-owned state. * * This capability is optional so existing third-party `SchemaValidator` * implementations remain source-compatible. Framework features that accept * raw JSON Schema fail clearly when the registered adapter does not provide * it. */ compileJsonSchema?(schema: JsonSchema): JsonSchemaValidationFunction; /** * Convert an opaque `Schema` to a JSON Schema document. * * Used by the tool/MCP layer to expose tool input schemas to AI providers * and MCP clients. Implementations unwrap the contract `Schema` back to * their native validator (e.g. zod) and emit a JSON Schema representation. * * Returns a permissive `{type: "object"}` for kinds the implementation * cannot represent. */ toJsonSchema(schema: Schema): JsonSchema; /** * Returns `true` when the schema permits `undefined` (i.e. was constructed * via `.optional()`/`.nullish()`). Used by tool input-schema introspection * to mark JSON Schema properties as not required. */ isOptional(schema: Schema): boolean; } export type { JsonSchema }; /** Factory type accepted by `defineSchema`. */ export type SchemaFactory = (v: SchemaValidator) => Schema; //# sourceMappingURL=schema-validator.d.ts.map