UNPKG

@nori-zk/proof-conversion

Version:

Verifying zkVM proofs inside o1js circuits, to generate Mina compatible proof

213 lines (212 loc) 8.27 kB
/** * Type predicate function that validates a value and narrows its type. * * Returns true if the value matches type T, allowing TypeScript to narrow * the type in the calling scope. This is the foundation for all type guard validators. * * @template T - The type to validate and narrow to * @param val - The value to validate * @returns Type predicate indicating whether val is of type T * * @example * const isString: ValidatorFn<string> = (val): val is string => typeof val === 'string'; * if (isString(value)) { * // value is narrowed to type: string * } */ export type ValidatorFn<T = unknown> = (val: unknown) => val is T; /** * Metadata associated with a registered type guard validator. * Includes validator name, optional inner validators for composite types, * and optional constraint data for bounded types. * * @template Options - The constraint type (never if no constraints) */ export type GuardMeta<Options = never> = { /** Display name of the validator (without "is" prefix) */ name: string; /** Optional inner validator for composite types (arrays, objects) */ inner?: ValidatorFn<unknown>; } & ([Options] extends [never] ? { constraint?: never; printConstraint?: never; printDiagnosis?: never; } : { /** Constraint data (e.g., min/max bounds) */ constraint: Options; /** Function to format constraint for display */ printConstraint: (data: Options) => string; /** Function to generate diagnostic message for failed validation */ printDiagnosis: (data: Options, val: unknown) => string; }); /** * Retrieves metadata for a registered validator function. * * @template T - The validator's return type * @template O - The constraint type (defaults to never) * @param fn - The validator function to look up * @returns The validator's metadata, or undefined if not registered */ export declare const getMeta: <T, O = never>(fn: ValidatorFn<T>) => GuardMeta<O> | undefined; /** * Registers a type guard validator function with metadata for diagnostic purposes. * This is the foundation for creating all type guard validators in the system. * * Two overloads: * 1. Simple guards (no constraints) - for primitives and simple structural types * 2. Constrained guards - for bounded types with validation constraints * * The function must be named (not anonymous) so the name can be extracted for diagnostics. * * @template T - The type the guard validates * @param fn - The validator function with type predicate * @param meta - Optional metadata (name, inner validators) * @returns The same validator function, now registered in the guard registry * * @example * // Simple guard * const isString = guard(function isString(val: unknown): val is string { * return typeof val === 'string'; * }); */ export declare function guard<T>(fn: ValidatorFn<T>, meta?: { name?: string; inner?: ValidatorFn<unknown>; }): ValidatorFn<T>; /** * Registers a constrained type guard validator with diagnostic metadata. * * @template T - The type the guard validates * @template Options - The constraint type * @param fn - The validator function with type predicate * @param meta - Metadata including constraint, display, and diagnostic functions * @returns The same validator function, now registered in the guard registry * * @example * // Constrained guard * const isBounded = guard<number, { min: number }>( * function isBounded(val: unknown): val is number { * return typeof val === 'number' && val >= 0; * }, * { * constraint: { min: 0 }, * printConstraint: (c) => `(>=${c.min})`, * printDiagnosis: (c, val) => `got ${val}, expected >= ${c.min}` * } * ); */ export declare function guard<T, Options>(fn: ValidatorFn<T>, meta: { name?: string; inner?: ValidatorFn<unknown>; constraint: Options; printConstraint: (data: Options) => string; printDiagnosis: (data: Options, val: unknown) => string; }): ValidatorFn<T>; /** * Generates a human-readable type name for a validator function. * Includes constraints and nested types in the output. * * @template T - The validator's return type * @param fn - The validator function * @returns A formatted string representing the full type (e.g., "Array<String>", "Number(0..255)") * * @example * getFullTypeName(isString) // "String" * getFullTypeName(isUint8) // "Number(0..255)" * getFullTypeName(isStringArray) // "Array<String>" */ export declare const getFullTypeName: <T>(fn: ValidatorFn<T>) => string; /** * Identifies the runtime type of a value using registered validators. * Returns a human-readable string describing the value's type structure. * * For primitives, tries to match against registered validators. * For arrays and objects, recursively identifies nested structure. * * @param val - The value to identify * @returns A string describing the value's type (e.g., "string", "[number, string]", "{x: string, y: number}") * * @example * identify("hello") // "string" * identify([1, 2, 3]) // "[number, number, number]" * identify({ x: "a", y: 5 }) // "{x: string, y: number}" */ export declare const identify: (val: unknown) => string; /** * Schema definition node - can be a literal, validator, or nested object. * Used to define expected structure for validation. */ export type SchemaNode = string | number | boolean | null | ValidatorFn | { [key: string]: SchemaNode; }; /** * Schema definition for object validation. * Maps property names to their expected types (validators, literals, or nested objects). * This is the object-specific variant of SchemaNode. */ export interface SchemaObject { [key: string]: SchemaNode; } /** * Infers the TypeScript type from a schema definition. * Recursively extracts types from validators and nested objects. * * @template S - The schema to infer from * @returns The inferred TypeScript type * * @example * const schema = { name: isString, age: isNumber }; * type Person = InferSchemaType<typeof schema>; // { name: string; age: number } */ export type InferSchemaType<S> = S extends (val: unknown) => val is infer T ? T : S extends object ? { [K in keyof S]: InferSchemaType<S[K]>; } : S; /** * Human-readable schema description - the output of describeSchema. * Mirrors SchemaNode structure but with validators converted to type names. */ export type SchemaDescription = string | number | boolean | null | { [key: string]: SchemaDescription; }; /** * Recursively converts a schema definition into a human-readable description. * Replaces validator functions with their type names while preserving structure. * * @param schema - The schema definition to describe * @returns A human-readable description of the schema structure * * @example * describeSchema({ x: isString, y: isNumber }) * // Returns: { x: "String", y: "Number" } * * describeSchema({ items: isStringArray }) * // Returns: { items: "Array<String>" } */ export declare const describeSchema: (schema: SchemaNode) => SchemaDescription; /** * Recursively validates a value and collects detailed error messages. * Provides path-aware diagnostics showing exactly where and why validation failed. * * The function: * 1. Validates the value using the provided validator * 2. If validation fails, adds a detailed error message with path * 3. If validation passes but the type has inner validators (array/object elements), * recursively validates nested values * 4. Returns all collected errors with proper indentation and context * * @template T - The expected type * @param fn - The validator function to use * @param val - The value to validate * @param path - The current path for error reporting (default: "value") * @param errors - Accumulated error messages (internal use) * @returns Array of error messages (empty if validation succeeds) * * @example * const validator = isArrayOfLength(isUint8, 3); * const errors = diagnose(validator, [1, 2, 300]); * // Returns: [ * // "value should have type Array[3]<Number(0..255)>", * // " value[2]: expected Number(0..255), got 300 which exceeds maximum 255" * // ] */ export declare const diagnose: <T>(fn: ValidatorFn<T>, val: unknown, path?: string, errors?: string[]) => string[];