UNPKG

fortify-schema

Version:

TypeScript interface-like schema validation system that's easier to use than Zod

1,591 lines (1,559 loc) 62.6 kB
/** * Constant value wrapper to distinguish from string types */ interface ConstantValue { const: string | number | boolean; } /** * Union value wrapper for proper type inference */ interface UnionValue<T extends readonly string[] = readonly string[]> { union: T; } /** * Optional constant value wrapper */ interface OptionalConstantValue { const: string | number | boolean; optional: true; } /** * Optional schema interface wrapper */ interface OptionalSchemaInterface { optional: true; schema: SchemaInterface; } /** * Schema definition using TypeScript-like interface syntax */ interface SchemaInterface { [key: string]: SchemaFieldType | ConstantValue | OptionalConstantValue | SchemaInterface | SchemaInterface[] | any; } /** * Field type definitions using string literals and objects */ type SchemaFieldType = "string" | "string?" | "number" | "number?" | "boolean" | "boolean?" | "date" | "date?" | "any" | "any?" | "email" | "email?" | "url" | "url?" | "uuid" | "uuid?" | "phone" | "phone?" | "slug" | "slug?" | "username" | "username?" | "int" | "int?" | "positive" | "positive?" | "float" | "float?" | "string[]" | "string[]?" | "number[]" | "number[]?" | "boolean[]" | "boolean[]?" | "int[]" | "int[]?" | "email[]" | "email[]?" | "url[]" | "url[]?" | string | ConstantValue | OptionalConstantValue | UnionValue | SchemaInterface | SchemaInterface[] | OptionalSchemaInterface; /** * Schema validation options for fine-tuning */ interface SchemaOptions { minLength?: number; maxLength?: number; pattern?: RegExp; min?: number; max?: number; precision?: number; minItems?: number; maxItems?: number; unique?: boolean; strict?: boolean; allowUnknown?: boolean; required?: boolean; default?: any; loose?: boolean; } /** * Core types and interfaces for the FortifyJS Schema system */ /** * Schema validation result */ interface SchemaValidationResult<T = any> { success: boolean; data?: T; errors: string[]; warnings: string[]; } /** * Base schema configuration options */ interface BaseSchemaOptions { optional?: boolean; nullable?: boolean; default?: any; } /** * String schema validation options */ interface StringSchemaOptions extends BaseSchemaOptions { minLength?: number; maxLength?: number; pattern?: RegExp; format?: "email" | "url" | "uuid" | "phone" | "slug" | "username"; } /** * Number schema validation options */ interface NumberSchemaOptions extends BaseSchemaOptions { min?: number; max?: number; integer?: boolean; positive?: boolean; precision?: number; } /** * Boolean schema validation options */ interface BooleanSchemaOptions extends BaseSchemaOptions { strict?: boolean; } /** * Array schema validation options */ interface ArraySchemaOptions extends BaseSchemaOptions { minLength?: number; maxLength?: number; unique?: boolean; } /** * Object schema validation options */ interface ObjectSchemaOptions extends BaseSchemaOptions { strict?: boolean; allowUnknown?: boolean; } /** * Schema type definitions */ type SchemaType = "string" | "number" | "boolean" | "array" | "object" | "date" | "any"; /** * Schema definition for object properties */ type SchemaDefinition = { [key: string]: SchemaConfig; }; /** * Complete schema configuration */ interface SchemaConfig { type: SchemaType; options?: BaseSchemaOptions; elementSchema?: SchemaConfig; properties?: SchemaDefinition; validator?: (value: any) => void; } /** * TypeScript Interface-like Schema Definition System * * Allows defining schemas using TypeScript-like syntax with string literals * that feel natural and are much easier to read and write. */ /** * Interface Schema class for TypeScript-like schema definitions */ type AllowUnknownSchema<T> = T & Record<string, any>; declare class InterfaceSchema<T = any> { private definition; private options; constructor(definition: SchemaInterface, options?: SchemaOptions); /** * Validate data against the interface schema */ validate(data: any): SchemaValidationResult<T>; /** * Validate individual field */ private validateField; /** * Validate string-based field types */ private validateStringFieldType; /** * Validate basic types with enhanced constraints */ private validateBasicType; /** * Validate conditional field with full data context */ private validateConditionalFieldWithContext; /** * Evaluate a condition against a field value */ private evaluateCondition; /** * Validate conditional field based on other field values (legacy method) * * Note: This method is used when conditional validation is called without * full data context. It provides a fallback validation approach. */ private validateConditionalField; /** * Helper method to validate a value against a schema type */ private validateSchemaType; /** * Parse and validate (throws on error) */ parse(data: T): T; /** * Safe parse (returns result object) - strictly typed input */ safeParse(data: T): SchemaValidationResult<T>; /** * Safe parse with unknown data (for testing invalid inputs) * Use this when you need to test data that might not match the schema */ safeParseUnknown(data: unknown): SchemaValidationResult<T>; /** * Set schema options */ withOptions(opts: SchemaOptions): InterfaceSchema<T>; /** * Enable strict mode (no unknown properties allowed) */ strict(): InterfaceSchema<T>; /** * Enable loose mode (allow type coercion) */ loose(): InterfaceSchema<T>; /** * Allow unknown properties (not strict about extra fields) * Returns a schema that accepts extra properties beyond the defined interface */ allowUnknown(): InterfaceSchema<AllowUnknownSchema<T>>; /** * Set minimum constraints */ min(value: number): InterfaceSchema<T>; /** * Set maximum constraints */ max(value: number): InterfaceSchema<T>; /** * Require unique array values */ unique(): InterfaceSchema<T>; /** * Set pattern for string validation */ pattern(regex: RegExp): InterfaceSchema<T>; /** * Set default value */ default(value: any): InterfaceSchema<T>; } /** * Enhanced Type Inference System for Schema Definitions * Features: design, better extensibility, performance optimizations */ interface BaseTypeMap { string: string; number: number; int: number; integer: number; float: number; double: number; positive: number; negative: number; boolean: boolean; bool: boolean; date: Date; datetime: Date; timestamp: Date; email: string; url: string; uri: string; uuid: string; guid: string; phone: string; slug: string; username: string; password: string; text: string; json: any; object: object; any: any; unknown: unknown; void: void; null: null; undefined: undefined; } type ParseUnion<T extends string> = T extends `${infer First}|${infer Rest}` ? First extends "" ? ParseUnion<Rest> : Rest extends "" ? First : First | ParseUnion<Rest> : T extends "" ? never : T; type ParseWhenCondition<T extends string> = T extends `${infer Field}.!exists` ? { field: Field; operator: "!exists"; value: true; } : T extends `${infer Field}.exists` ? { field: Field; operator: "exists"; value: true; } : T extends `${infer Field}.!empty` ? { field: Field; operator: "!empty"; value: true; } : T extends `${infer Field}.empty` ? { field: Field; operator: "empty"; value: true; } : T extends `${infer Field}.!null` ? { field: Field; operator: "!null"; value: true; } : T extends `${infer Field}.null` ? { field: Field; operator: "null"; value: true; } : T extends `${infer Field}.!in(${infer Values})` ? { field: Field; operator: "!in"; value: Values; } : T extends `${infer Field}.in(${infer Values})` ? { field: Field; operator: "in"; value: Values; } : T extends `${infer Field}.!contains(${infer Value})` ? { field: Field; operator: "!contains"; value: Value; } : T extends `${infer Field}.contains(${infer Value})` ? { field: Field; operator: "contains"; value: Value; } : T extends `${infer Field}.startsWith(${infer Value})` ? { field: Field; operator: "startsWith"; value: Value; } : T extends `${infer Field}.endsWith(${infer Value})` ? { field: Field; operator: "endsWith"; value: Value; } : T extends `${infer Field}!~${infer Value}` ? { field: Field; operator: "!~"; value: Value; } : T extends `${infer Field}~${infer Value}` ? { field: Field; operator: "~"; value: Value; } : T extends `${infer Field}!=${infer Value}` ? { field: Field; operator: "!="; value: Value; } : T extends `${infer Field}>=${infer Value}` ? { field: Field; operator: ">="; value: Value; } : T extends `${infer Field}<=${infer Value}` ? { field: Field; operator: "<="; value: Value; } : T extends `${infer Field}>${infer Value}` ? { field: Field; operator: ">"; value: Value; } : T extends `${infer Field}<${infer Value}` ? { field: Field; operator: "<"; value: Value; } : T extends `${infer Field}=${infer Value}` ? { field: Field; operator: "="; value: Value; } : never; type InferConstantType<T extends string> = T extends `=${infer ConstValue}` ? ConstValue extends "true" ? true : ConstValue extends "false" ? false : ConstValue extends `${number}` ? number : ConstValue : T extends `=${infer ConstValue}?` ? ConstValue extends "true" ? true | undefined : ConstValue extends "false" ? false | undefined : ConstValue extends `${number}` ? number | undefined : ConstValue | undefined : never; type InferConditionalType<T extends string> = T extends `when ${infer Condition} *? ${infer ThenType} : ${infer ElseType}` ? InferFieldType$1<ThenType> | InferFieldType$1<ElseType> : T extends `when ${infer Condition} *? ${infer ThenType}` ? InferFieldType$1<ThenType> : T extends `when(${infer Condition}) then(${infer ThenType}) else(${infer ElseType})` ? InferFieldType$1<ThenType> | InferFieldType$1<ElseType> : T extends `when(${infer Condition}) then(${infer ThenType})` ? InferFieldType$1<ThenType> : T extends `${infer Condition} ? ${infer ThenType} : ${infer ElseType}` ? InferFieldType$1<ThenType> | InferFieldType$1<ElseType> : T extends `when:${infer Condition}:${infer ThenType}:${infer ElseType}` ? InferFieldType$1<ThenType> | InferFieldType$1<ElseType> : T extends `when:${infer Condition}:${infer ThenType}` ? InferFieldType$1<ThenType> : never; type InferBaseType<T extends string> = T extends keyof BaseTypeMap ? BaseTypeMap[T] : T extends `${infer BaseType}?` ? BaseType extends keyof BaseTypeMap ? BaseTypeMap[BaseType] | undefined : never : never; type InferArrayType<T extends string> = T extends `${infer ElementType}[]` ? ElementType extends keyof BaseTypeMap ? BaseTypeMap[ElementType][] : ElementType extends `${string}|${string}` ? ParseUnion<ElementType>[] : any[] : T extends `${infer ElementType}[]?` ? ElementType extends keyof BaseTypeMap ? BaseTypeMap[ElementType][] | undefined : ElementType extends `${string}|${string}` ? ParseUnion<ElementType>[] | undefined : any[] | undefined : never; type InferRecordType<T extends string> = T extends `record<${infer KeyType},${infer ValueType}>` ? KeyType extends "string" | "number" | "symbol" ? Record<string, InferFieldType$1<ValueType>> : Record<string, InferFieldType$1<ValueType>> : T extends `record<${infer KeyType},${infer ValueType}>?` ? KeyType extends "string" | "number" | "symbol" ? Record<string, InferFieldType$1<ValueType>> | undefined : Record<string, InferFieldType$1<ValueType>> | undefined : T extends `map<${infer KeyType},${infer ValueType}>` ? Record<string, InferFieldType$1<ValueType>> : T extends `map<${infer KeyType},${infer ValueType}>?` ? Record<string, InferFieldType$1<ValueType>> | undefined : never; type InferConstrainedType<T extends string> = T extends `${infer BaseType}(${infer Constraints})` ? BaseType extends keyof BaseTypeMap ? BaseTypeMap[BaseType] : BaseType extends `${infer ArrayType}[]` ? ArrayType extends keyof BaseTypeMap ? BaseTypeMap[ArrayType][] : any[] : any : T extends `${infer BaseType}(${infer Constraints})?` ? BaseType extends keyof BaseTypeMap ? BaseTypeMap[BaseType] | undefined : BaseType extends `${infer ArrayType}[]` ? ArrayType extends keyof BaseTypeMap ? BaseTypeMap[ArrayType][] | undefined : any[] | undefined : any | undefined : never; type InferRegexType<T extends string> = T extends `${infer BaseType}(/${string}/)` ? BaseType extends keyof BaseTypeMap ? BaseTypeMap[BaseType] : string : T extends `${infer BaseType}(/${string}/)?` ? BaseType extends keyof BaseTypeMap ? BaseTypeMap[BaseType] | undefined : string | undefined : never; type InferFieldType$1<T> = T extends string ? InferConstantType<T> extends never ? InferConditionalType<T> extends never ? T extends `${string}|${string}` ? T extends `${infer UnionType}?` ? ParseUnion<UnionType> | undefined : ParseUnion<T> : InferArrayType<T> extends never ? InferRecordType<T> extends never ? InferConstrainedType<T> extends never ? InferRegexType<T> extends never ? InferBaseType<T> extends never ? any : InferBaseType<T> : InferRegexType<T> : InferConstrainedType<T> : InferRecordType<T> : InferArrayType<T> : InferConditionalType<T> : InferConstantType<T> : any; type InferConditionalTypeAdvanced<TCondition extends string, TThenType extends string, TElseType extends string, TSchema extends SchemaInterface> = ParseWhenCondition<TCondition> extends { field: infer Field; operator: infer Op; value: infer Value; } ? Field extends keyof TSchema ? TSchema[Field] extends string ? Op extends "=" ? TSchema[Field] extends `${string}|${string}` ? Value extends ParseUnion<TSchema[Field]> ? InferFieldType$1<TThenType> : InferFieldType$1<TElseType> : TSchema[Field] extends Value ? InferFieldType$1<TThenType> : InferFieldType$1<TElseType> : Op extends "!=" ? TSchema[Field] extends Value ? InferFieldType$1<TElseType> : InferFieldType$1<TThenType> : Op extends "exists" ? InferFieldType$1<TThenType> : Op extends "!exists" ? InferFieldType$1<TElseType> : // For complex operators, use union type InferFieldType$1<TThenType> | InferFieldType$1<TElseType> : InferFieldType$1<TThenType> | InferFieldType$1<TElseType> : InferFieldType$1<TThenType> | InferFieldType$1<TElseType> : InferFieldType$1<TThenType> | InferFieldType$1<TElseType>; type InferSchemaFieldType<T, TSchema extends SchemaInterface = {}> = T extends UnionValue<infer U> ? U[number] : T extends ConstantValue ? T["const"] : T extends OptionalConstantValue ? T["const"] | undefined : T extends { __conditional: true; __inferredType: infer U; } ? U : T extends `when ${infer Condition} *? ${infer ThenType} : ${infer ElseType}` ? InferConditionalTypeAdvanced<Condition, ThenType, ElseType, TSchema> : T extends `when ${infer Condition} *? ${infer ThenType}` ? InferFieldType$1<ThenType> : T extends `when(${infer Condition}) then(${infer ThenType}) else(${infer ElseType})` ? InferConditionalTypeAdvanced<Condition, ThenType, ElseType, TSchema> : T extends `when(${infer Condition}) then(${infer ThenType})` ? InferFieldType$1<ThenType> : T extends `${infer Condition} ? ${infer ThenType} : ${infer ElseType}` ? InferConditionalTypeAdvanced<Condition, ThenType, ElseType, TSchema> : T extends `when:${infer Condition}:${infer ThenType}:${infer ElseType}` ? InferConditionalTypeAdvanced<Condition, ThenType, ElseType, TSchema> : T extends `when:${infer Condition}:${infer ThenType}` ? InferFieldType$1<ThenType> : T extends string ? InferFieldType$1<T> : T extends SchemaInterface ? InferSchemaType<T> : T extends OptionalSchemaInterface ? InferSchemaType<T["schema"]> | undefined : T extends readonly [infer U] ? InferSchemaFieldType<U, TSchema>[] : T extends (infer U)[] ? InferSchemaFieldType<U, TSchema>[] : any; type IsOptionalField<T> = T extends string ? T extends `${string}?` ? true : false : T extends OptionalConstantValue ? true : T extends OptionalSchemaInterface ? true : T extends { __optional: true; } ? true : false; type RequiredFields<T extends SchemaInterface> = { [K in keyof T]: IsOptionalField<T[K]> extends true ? never : K; }[keyof T]; type OptionalFields<T extends SchemaInterface> = { [K in keyof T]: IsOptionalField<T[K]> extends true ? K : never; }[keyof T]; type InferSchemaType<T extends SchemaInterface> = { [K in RequiredFields<T>]: InferSchemaFieldType<T[K], T>; } & { [K in OptionalFields<T>]?: InferSchemaFieldType<T[K], T>; }; /** * Schema modification utilities - transform and combine schemas */ declare class Mod { /** * Merge multiple schemas into a single schema * @example * ```typescript * const UserSchema = Interface({ id: "number", name: "string" }); * const ProfileSchema = Interface({ bio: "string?", avatar: "url?" }); * * const MergedSchema = Mod.merge(UserSchema, ProfileSchema); * // Result: { id: number, name: string, bio?: string, avatar?: string } * ``` */ static merge<T, U>(schema1: InterfaceSchema<T>, schema2: InterfaceSchema<U>): InterfaceSchema<T & U>; /** * Pick specific fields from a schema * @example * ```typescript * const UserSchema = Interface({ * id: "number", * name: "string", * email: "email", * password: "string" * }); * * const PublicUserSchema = Mod.pick(UserSchema, ["id", "name", "email"]); * // Result: { id: number, name: string, email: string } * ``` */ static pick<T, K extends keyof T>(schema: InterfaceSchema<T>, keys: K[]): InterfaceSchema<Pick<T, K>>; /** * Omit specific fields from a schema * @example * ```typescript * const UserSchema = Interface({ * id: "number", * name: "string", * email: "email", * password: "string" * }); * * const SafeUserSchema = Mod.omit(UserSchema, ["password"]); * // Result: { id: number, name: string, email: string } * ``` */ static omit<T, K extends keyof T>(schema: InterfaceSchema<T>, keys: K[]): InterfaceSchema<Omit<T, K>>; /** * Make all fields in a schema optional * @example * ```typescript * const UserSchema = Interface({ id: "number", name: "string" }); * const PartialUserSchema = Mod.partial(UserSchema); * // Result: { id?: number, name?: string } * ``` */ static partial<T>(schema: InterfaceSchema<T>): InterfaceSchema<Partial<T>>; /** * Make all fields in a schema required (remove optional markers) * @example * ```typescript * const UserSchema = Interface({ id: "number", name: "string?" }); * const RequiredUserSchema = Mod.required(UserSchema); * // Result: { id: number, name: string } * ``` */ static required<T>(schema: InterfaceSchema<T>): InterfaceSchema<Required<T>>; /** * Extend a schema with additional fields * @example * ```typescript * const BaseSchema = Interface({ id: "number", name: "string" }); * const ExtendedSchema = Mod.extend(BaseSchema, { * email: "email", * createdAt: "date" * }); * // Result: { id: number, name: string, email: string, createdAt: Date } * ``` */ static extend<T, U extends SchemaInterface>(schema: InterfaceSchema<T>, extension: U): InterfaceSchema<T & InferSchemaType<U>>; } /** * Helper class for creating schema values */ declare class Make { /** * Create a constant value (safer than using raw values) * @example * ```typescript * const schema = Interface({ * status: Make.const("pending"), * version: Make.const(1.0), * enabled: Make.const(true) * }); * ``` */ static const<const T extends string | number | boolean>(value: T): ConstantValue & { const: T; }; /** * Create a union type (multiple allowed values) with proper type inference * @example * ```typescript * const schema = Interface({ * status: Make.union("pending", "accepted", "rejected"), * priority: Make.union("low", "medium", "high") * }); * ``` */ static union<const T extends readonly string[]>(...values: T): UnionValue<T>; /** * Create an optional union type * @example * ```typescript * const schema = Interface({ * status: Make.unionOptional("pending", "accepted", "rejected") * }); * ``` */ static unionOptional(...values: string[]): string; } /** * TypeScript Interface-like Schema System * * The most intuitive way to define schemas - just like TypeScript interfaces! * * @example * ```typescript * import { Interface } from "fortify-schema"; * * // Define schema like a TypeScript interface * const UserSchema = Interface({ * id: "number", * email: "email", * name: "string", * age: "number?", // Optional * isActive: "boolean?", // Optional * tags: "string[]?", // Optional array * role: "admin", // Constant value * profile: { // Nested object * bio: "string?", * avatar: "url?" * } * }); * * // Validate data * const result = UserSchema.safeParse(userData); * ``` */ /** * Create a schema using TypeScript interface-like syntax with full type inference * * @param definition - Schema definition using TypeScript-like syntax * @param options - Optional validation options * @returns InterfaceSchema instance with inferred types * * @example Basic Usage * ```typescript * const UserSchema = Interface({ * id: "number", * email: "email", * name: "string", * age: "number?", * isActive: "boolean?", * tags: "string[]?" * }); * * // result is fully typed as: * // SchemaValidationResult<{ * // id: number; * // email: string; * // name: string; * // age?: number; * // isActive?: boolean; * // tags?: string[]; * // }> * const result = UserSchema.safeParse(data); * ``` * * @example With Constraints * ```typescript * const UserSchema = Interface({ * username: "string(3,20)", // 3-20 characters * age: "number(18,120)", // 18-120 years * tags: "string[](1,10)?", // 1-10 tags, optional * }); * ``` * * @example Nested Objects * ```typescript * const OrderSchema = Interface({ * id: "number", * customer: { * name: "string", * email: "email", * address: { * street: "string", * city: "string", * zipCode: "string" * } * }, * items: [{ * name: "string", * price: "number", * quantity: "int" * }] * }); * ``` */ declare function Interface<const T extends SchemaInterface>(definition: T, options?: SchemaOptions): InterfaceSchema<InferSchemaType<T>>; /** * Type helper for inferring TypeScript types from schema definitions * * @example * ```typescript * const UserSchema = Interface({ * id: "number", * email: "email", * name: "string", * age: "number?", * tags: "string[]?" * }); * * // Infer the TypeScript type * type User = InferType<typeof UserSchema>; * // User = { * // id: number; * // email: string; * // name: string; * // age?: number; * // tags?: string[]; * // } * ``` */ type InferType<T extends InterfaceSchema<any>> = T extends InterfaceSchema<infer U> ? U : never; /** * Available field types for schema definitions */ declare const FieldTypes: { readonly STRING: "string"; readonly STRING_OPTIONAL: "string?"; readonly NUMBER: "number"; readonly NUMBER_OPTIONAL: "number?"; readonly BOOLEAN: "boolean"; readonly BOOLEAN_OPTIONAL: "boolean?"; readonly DATE: "date"; readonly DATE_OPTIONAL: "date?"; readonly ANY: "any"; readonly ANY_OPTIONAL: "any?"; readonly EMAIL: "email"; readonly EMAIL_OPTIONAL: "email?"; readonly URL: "url"; readonly URL_OPTIONAL: "url?"; readonly UUID: "uuid"; readonly UUID_OPTIONAL: "uuid?"; readonly PHONE: "phone"; readonly PHONE_OPTIONAL: "phone?"; readonly SLUG: "slug"; readonly SLUG_OPTIONAL: "slug?"; readonly USERNAME: "username"; readonly USERNAME_OPTIONAL: "username?"; readonly INT: "int"; readonly INT_OPTIONAL: "int?"; readonly POSITIVE: "positive"; readonly POSITIVE_OPTIONAL: "positive?"; readonly FLOAT: "float"; readonly FLOAT_OPTIONAL: "float?"; readonly STRING_ARRAY: "string[]"; readonly STRING_ARRAY_OPTIONAL: "string[]?"; readonly NUMBER_ARRAY: "number[]"; readonly NUMBER_ARRAY_OPTIONAL: "number[]?"; readonly BOOLEAN_ARRAY: "boolean[]"; readonly BOOLEAN_ARRAY_OPTIONAL: "boolean[]?"; readonly INT_ARRAY: "int[]"; readonly INT_ARRAY_OPTIONAL: "int[]?"; readonly EMAIL_ARRAY: "email[]"; readonly EMAIL_ARRAY_OPTIONAL: "email[]?"; readonly URL_ARRAY: "url[]"; readonly URL_ARRAY_OPTIONAL: "url[]?"; readonly RECORD_STRING_ANY: "record<string,any>"; readonly RECORD_STRING_ANY_OPTIONAL: "record<string,any>?"; readonly RECORD_STRING_STRING: "record<string,string>"; readonly RECORD_STRING_STRING_OPTIONAL: "record<string,string>?"; readonly RECORD_STRING_NUMBER: "record<string,number>"; readonly RECORD_STRING_NUMBER_OPTIONAL: "record<string,number>?"; }; /** * Quick schema creation helpers */ declare const QuickSchemas: { /** * User schema with common fields */ User: InterfaceSchema<InferSchemaType<{ readonly id: "number"; readonly email: "email"; readonly name: "string"; readonly createdAt: "date?"; readonly updatedAt: "date?"; }>>; /** * API response schema */ APIResponse: InterfaceSchema<InferSchemaType<{ readonly success: "boolean"; readonly data: "any?"; readonly errors: "string[]?"; readonly timestamp: "date?"; }>>; /** * Pagination schema */ Pagination: InterfaceSchema<InferSchemaType<{ readonly page: "int"; readonly limit: "int"; readonly total: "int"; readonly hasNext: "boolean?"; readonly hasPrev: "boolean?"; }>>; /** * Address schema */ Address: InterfaceSchema<InferSchemaType<{ readonly street: "string"; readonly city: "string"; readonly state: "string?"; readonly zipCode: "string"; readonly country: "string"; }>>; /** * Contact info schema */ Contact: InterfaceSchema<InferSchemaType<{ readonly email: "email?"; readonly phone: "phone?"; readonly website: "url?"; }>>; }; /** * OpenAPI Converter - Convert schemas to OpenAPI specifications * * This module provides utilities to convert Fortify Schema definitions * to OpenAPI 3.0 specifications for API documentation. */ /** * OpenAPI converter for schema definitions */ declare class OpenAPIConverter { /** * Convert a schema to OpenAPI format */ static convertSchema(schema: SchemaInterface): OpenAPISchemaObject; /** * Convert a single field to OpenAPI property */ private static convertField; /** * Convert string-based field definitions */ private static convertStringField; /** * Convert object field definitions */ private static convertObjectField; /** * Parse string constraints from string(min,max) format */ private static parseStringConstraints; /** * Generate complete OpenAPI specification */ static generateOpenAPISpec(schema: SchemaInterface, options: OpenAPISpecOptions): OpenAPISpecification; /** * Generate schema reference for use in OpenAPI paths */ static generateSchemaReference(schemaName: string): OpenAPIReference; /** * Generate request body specification */ static generateRequestBody(schema: SchemaInterface, options?: RequestBodyOptions): OpenAPIRequestBody; /** * Generate response specification */ static generateResponse(schema: SchemaInterface, options?: ResponseOptions): OpenAPIResponse; } /** * Type definitions */ interface OpenAPISchemaObject { type: string; properties?: Record<string, any>; required?: string[]; items?: any; format?: string; pattern?: string; minimum?: number; maximum?: number; exclusiveMinimum?: boolean; exclusiveMaximum?: boolean; minLength?: number; maxLength?: number; minItems?: number; maxItems?: number; } interface OpenAPISpecOptions { title: string; version: string; description?: string; schemaName?: string; servers?: string[]; paths?: Record<string, any>; } interface OpenAPISpecification { openapi: string; info: { title: string; version: string; description?: string; }; servers?: Array<{ url: string; }>; components: { schemas: Record<string, OpenAPISchemaObject>; }; paths: Record<string, any>; } interface OpenAPIReference { $ref: string; } interface RequestBodyOptions { description?: string; required?: boolean; examples?: Record<string, any>; } interface OpenAPIRequestBody { description: string; required: boolean; content: Record<string, { schema: OpenAPISchemaObject; examples?: Record<string, any>; }>; } interface ResponseOptions { description?: string; examples?: Record<string, any>; headers?: Record<string, any>; } interface OpenAPIResponse { description: string; content: Record<string, { schema: OpenAPISchemaObject; examples?: Record<string, any>; }>; headers?: Record<string, any>; } /** * TypeScript Generator - Generate TypeScript type definitions from schemas * * This module provides utilities to convert Fortify Schema definitions * to TypeScript type definitions and interfaces. */ /** * TypeScript code generator for schema definitions */ declare class TypeScriptGenerator$1 { /** * Generate TypeScript interface from schema */ static generateInterface(schema: SchemaInterface, options?: TypeScriptOptions): string; /** * Extract field definitions from schema object */ private static extractFieldDefinitions; /** * Generate interface definition */ private static generateInterfaceDefinition; /** * Generate type alias definition */ private static generateTypeDefinition; /** * Convert schema field to TypeScript type */ private static convertToTypeScript; /** * Convert string-based field to TypeScript type */ private static convertStringToTypeScript; /** * Convert object to TypeScript type */ private static convertObjectToTypeScript; /** * Check if field is optional */ private static isOptionalField; /** * Generate utility types for schema */ static generateUtilityTypes(schema: SchemaInterface, baseName: string): string; /** * Generate validation function types */ static generateValidationTypes(baseName: string): string; /** * Generate complete TypeScript module */ static generateModule(schema: SchemaInterface, options: ModuleOptions): string; /** * Generate JSDoc comments for schema fields */ static generateJSDoc(schema: SchemaInterface): Record<string, string>; /** * Generate JSDoc for a single field */ private static generateFieldJSDoc; } /** * Type definitions */ interface TypeScriptOptions { exportName?: string; namespace?: string; exportType?: "interface" | "type"; } interface ModuleOptions { moduleName?: string; exportName?: string; includeUtilities?: boolean; includeValidation?: boolean; header?: string; } /** * Validation Engine - Core validation logic for schema extensions * * This module provides the core validation engine that powers all schema extensions. * It handles type checking, constraint validation, and error reporting. */ /** * Core validation engine for schema validation */ declare class ValidationEngine { /** * Validate a value against a schema field definition */ static validateField(fieldSchema: any, value: any): ValidationFieldResult; /** * Validate against string-based schema definitions */ private static validateStringSchema; /** * Validate against object schema definitions */ private static validateObjectSchema; /** * Email validation */ private static validateEmail; /** * URL validation */ private static validateUrl; /** * UUID validation */ private static validateUuid; /** * Number validation */ private static validateNumber; /** * Positive number validation */ private static validatePositiveNumber; /** * Integer validation */ private static validateInteger; /** * Boolean validation */ private static validateBoolean; /** * Date validation */ private static validateDate; /** * String validation */ private static validateString; /** * String validation with constraints */ private static validateStringWithConstraints; /** * Array validation */ private static validateArray; /** * Validate entire object against schema */ static validateObject(schema: SchemaInterface, data: any): ValidationResult$1; } /** * Type definitions */ interface ValidationFieldResult { isValid: boolean; errors: string[]; } interface ValidationResult$1 { isValid: boolean; data: any; errors: Record<string, string[]>; timestamp: Date; } /** * Type definitions */ interface DocumentationOptions { title?: string; description?: string; examples?: boolean; interactive?: boolean; } interface InteractiveOptions { title?: string; theme?: "light" | "dark"; showExamples?: boolean; allowTesting?: boolean; } interface Documentation { markdown: string; html: string; openapi: OpenAPISpec; json: any; examples: any[]; } interface InteractiveDocumentation { html: string; css: string; javascript: string; } interface OpenAPISpec { openapi: string; info: { title: string; version: string; }; servers?: Array<{ url: string; }>; components: { schemas: Record<string, any>; }; } /** * Type definitions */ interface ValidationResult { isValid: boolean; data: any; errors: Record<string, string[]>; timestamp: Date; } interface FieldValidationResult { field: string; value: any; isValid: boolean; errors: string[]; } interface ValidationStats { totalValidated: number; validCount: number; invalidCount: number; errorRate: number; startTime: Date; } type InferFieldType<T extends string> = T extends "string" ? string : T extends "string?" ? string | undefined : T extends "number" ? number : T extends "number?" ? number | undefined : T extends "boolean" ? boolean : T extends "boolean?" ? boolean | undefined : T extends "string[]" ? string[] : T extends "string[]?" ? string[] | undefined : T extends "number[]" ? number[] : T extends "number[]?" ? number[] | undefined : T extends "boolean[]" ? boolean[] : T extends "boolean[]?" ? boolean[] | undefined : T extends `${string}|${string}` ? string : any; type ConditionalResult<TThen extends string, TElse extends string> = { __conditional: true; __inferredType: InferFieldType<TThen> | InferFieldType<TElse>; }; /** * Builder for the "else" part of conditional validation with TypeScript inference * This class is returned after calling .then() and provides the .else() method */ declare class ConditionalElse<TThen extends string = string> { private builder; private condition; private thenSchema; constructor(builder: ConditionalBuilder, condition: (value: any) => boolean, thenSchema: TThen); /** * Specify the schema to use when the condition is false */ else<TElse extends string>(elseSchema: TElse): ConditionalResult<TThen, TElse>; /** * Alias for else() - for backward compatibility */ default<TElse extends string>(defaultSchema: TElse): ConditionalResult<TThen, TElse>; /** * Build without else clause (same as calling .else(undefined)) */ build(): any; } /** * Builder for the "then" part of conditional validation with TypeScript inference */ declare class ConditionalThen { private builder; private condition; constructor(builder: ConditionalBuilder, condition: (value: any) => boolean); then<T extends string>(schema: T): ConditionalElse<T>; } /** * Builder for single field conditional validation with TypeScript inference */ declare class ConditionalBuilder { private fieldName; private conditions; private defaultSchema; constructor(fieldName: string); /** * Check if field equals specific value */ is(value: any): ConditionalThen; /** * Check if field does not equal specific value */ isNot(value: any): ConditionalThen; /** * Check if field exists (not null/undefined) */ exists(): ConditionalThen; /** * Check if field matches pattern */ matches(pattern: RegExp): ConditionalThen; /** * Check if field is in array of values */ in(values: any[]): ConditionalThen; /** * Custom condition function */ when(condition: (value: any) => boolean): ConditionalThen; addCondition(condition: (value: any) => boolean, schema: any): this; default(schema: any): any; build(): any; } /** * Builder for multi-field "then" part */ declare class MultiConditionalThen { private builder; private conditions; constructor(builder: MultiConditionalBuilder, conditions: Record<string, any>); then(schema: any): MultiConditionalElse; } /** * Builder for multi-field "else" part */ declare class MultiConditionalElse { private thenSchema; private elseSchema; constructor(thenSchema: any, elseSchema: any); else(schema: any): any; } /** * Custom validator builder */ declare class CustomValidator { private validator; constructor(validator: (data: any) => { valid: true; } | { error: string; }); build(): any; } /** * Builder for multi-field conditional validation */ declare class MultiConditionalBuilder { private fieldNames; private matchConditions; constructor(fieldNames: string[]); match(conditions: Record<string, any>): MultiConditionalThen; } /** * Conditional Validation - Revolutionary dependent field validation * * This module provides powerful conditional validation where fields can depend * on other fields' values, making complex business logic validation simple. */ /** * Conditional validation utilities */ declare const When: { /** * Create conditional validation based on another field's value * * @example * ```typescript * const UserSchema = Interface({ * accountType: Make.union("free", "premium", "enterprise"), * maxProjects: When.field("accountType").is("free").then("int(1,3)") * .is("premium").then("int(1,50)") * .is("enterprise").then("int(1,)") * .default("int(1,1)"), * * paymentMethod: When.field("accountType").isNot("free").then("string").else("string?"), * billingAddress: When.field("paymentMethod").exists().then({ * street: "string", * city: "string", * country: "string(2,2)" * }).else("any?") * }); * ``` */ field(fieldName: string): ConditionalBuilder; /** * Create validation that depends on multiple fields * * @example * ```typescript * const OrderSchema = Interface({ * orderType: Make.union("pickup", "delivery"), * address: "string?", * deliveryFee: "number?", * * // Complex conditional validation * ...When.fields(["orderType", "address"]).match({ * orderType: "delivery", * address: (val) => val && val.length > 0 * }).then({ * deliveryFee: "number(0,)" // Required for delivery with address * }).else({ * deliveryFee: "number?" // Optional otherwise * }) * }); * ``` */ fields(fieldNames: string[]): MultiConditionalBuilder; /** * Create custom validation logic * * @example * ```typescript * const EventSchema = Interface({ * startDate: "date", * endDate: "date", * * // Custom validation: endDate must be after startDate * ...When.custom((data) => { * if (data.endDate <= data.startDate) { * return { error: "End date must be after start date" }; * } * return { valid: true }; * }) * }); * ``` */ custom(validator: (data: any) => { valid: true; } | { error: string; }): CustomValidator; }; /** * Smart Schema Inference - Revolutionary TypeScript type-to-schema conversion * * This module provides automatic schema generation from TypeScript types, * making schema definition even more seamless. */ /** * Smart inference utilities for automatic schema generation */ declare const Smart: { /** * Infer schema from TypeScript interface using runtime reflection * * @example * ```typescript * interface User { * id: number; * email: string; * name?: string; * } * * // Use with sample data that matches your interface * const UserSchema = Smart.fromType<User>({ * id: 1, * email: "user@example.com", * name: "John Doe" * }); * // Generates: Interface({ id: "positive", email: "email", name: "string?" }) * ``` */ fromType<T>(sampleData: T): SchemaInterface; /** * Infer schema from sample data with intelligent type detection * * @example * ```typescript * const sampleUser = { * id: 1, * email: "user@example.com", * name: "John Doe", * tags: ["developer", "typescript"] * }; * * const UserSchema = Smart.fromSample(sampleUser); * // Generates: Interface({ id: "positive", email: "email", name: "string", tags: "string[]" }) * ``` */ fromSample(sample: any): SchemaInterface; /** * Infer field type from value with smart detection */ inferFieldType(value: any): string; /** * Smart format detection utilities */ isEmail(str: string): boolean; isUrl(str: string): boolean; isUuid(str: string): boolean; isPhone(str: string): boolean; /** * Generate schema from JSON Schema (migration helper) * * @example * ```typescript * const jsonSchema = { * type: "object", * properties: { * id: { type: "number" }, * email: { type: "string", format: "email" } * } * }; * * const schema = Smart.fromJsonSchema(jsonSchema); * ``` */ fromJsonSchema(jsonSchema: any): SchemaInterface; convertJsonSchemaProperty(prop: any): string; }; /** * Live validator for real-time validation */ declare class LiveValidator { private schema; private currentData; private currentErrors; private listeners; private fieldListeners; constructor(schema: SchemaInterface); /** * Validate a single field in real-time */ validateField(fieldName: string, value: any): FieldValidationResult; /** * Validate all current data */ validateAll(): ValidationResult; /** * Listen for validation changes */ onValidation(listener: (result: ValidationResult) => void): void; /** * Listen for specific field validation */ onFieldValidation(fieldName: string, listener: (result: FieldValidationResult) => void): void; /** * Get current validation state */ get isValid(): boolean; get errors(): Record<string, string[]>; get data(): any; private notifyListeners; } /** * Form validator with DOM integration */ declare class FormValidator extends LiveValidator { private boundFields; private autoValidationEnabled; private submitListeners; /** * Bind a form field for automatic validation (Node.js compatible) */ bindField(fieldName: string, element: any): void; /** * Enable automatic validation on input changes (Node.js compatible) */ enableAutoValidation(): void; /** * Listen for form submission */ onSubmit(listener: (isValid: boolean, data: any, errors: Record<string, string[]>) => void): void; /** * Trigger form validation (typically on submit) */ submit(): void; private setupFieldListeners; } /** * Stream validator for continuous data validation */ declare class StreamValidator { private schema; private validListeners; private invalidListeners; private statsListeners; private stats; constructor(schema: SchemaInterface); /** * Validate streaming data */ validate(data: any): void; /** * Listen for valid data */ onValid(listener: (data: any) => void): void; /** * Listen for invalid data */ onInvalid(listener: (data: any, errors: Record<string, string[]>) => void): void; /** * Listen for validation statistics */ onStats(listener: (stats: ValidationStats) => void): void; /** * Get current validation statistics */ getStats(): ValidationStats; private updateStats; } /** * Real-time Validation - Revolutionary live validation system * * This module provides real-time validation with reactive updates, * perfect for forms and live data validation. * * Uses modular validation engine for consistent validation logic. */ /** * Real-time validation utilities */ declare const Live: { /** * Create a reactive validator that validates in real-time * * @example * ```typescript * const UserSchema = Interface({ * email: "email", * username: "string(3,20)", * password: "string(8,)" * }); * * const liveValidator = Live.validator(UserSchema); * * // Listen for validation changes * liveValidator.onValidation((result) => { * console.log('Validation result:', result); * updateUI(result); * }); * * // Validate field by field * liveValidator.validateField('email', 'user@example.com'); * liveValidator.validateField('username', 'johndoe'); * * // Get current state * console.log(liveValidator.isValid); // true/false * console.log(liveValidator.errors); // Current errors * ``` */ validator(schema: SchemaInterface): LiveValidator; /** * Create a form validator with field-level validation * * @example * ```typescript * const formValidator = Live.form(UserSchema); * * // Bind to form fields * formValidator.bindField('email', emailInput); * formValidator.bindField('username', usernameInput); * * // Auto-validation on input * formValidator.enableAutoValidation(); * * // Submit validation * formValidator.onSubmit((isValid, data, errors) => { * if (isValid) { * submitForm(data); * } else { * showErrors(errors); * } * }); * ``` */ form(schema: SchemaInterface): FormValidator; /** * Create a stream validator for continuous data validation * * @example * ```typescript * const streamValidator = Live.stream(DataSchema); * * // Validate streaming data * dataStream.subscribe((data) => { * streamValidator.validate(data); * }); * * // Handle validation results * streamValidator.onValid((data) => { * processValidData(data); * }); * * streamValidator.onInvalid((data, errors) => { * logInvalidData(data, errors); * }); * ``` */ stream(schema: SchemaInterface): StreamValidator; }; /** * Auto documentation utilities */ declare const Docs: { /** * Generate comprehensive documentation from schema * * @example * ```typescript * const UserSchema = Interface({ * id: "uuid", * email: "email", * name: "string(2,50)", * age: "int(18,120)?", * role: Make.union("user", "admin", "moderator") * }); * * const documentation = Docs.generate(UserSchema, { * title: "User API", * description: "User management endpoints", * examples: true, * interactive: true * }); * * console.log(documentation.markdown); * console.log(documentation.html); * console.log(documentation.openapi); * ``` */ generate(schema: SchemaInterface, options?: DocumentationOptions): Documentation; /** * Generate OpenAPI specification from schema * * @example * ```typescript * const openApiSpec = Docs.openapi(UserSchema, { * title: "User API", * version: "1.0.0", * servers: ["https://api.example.com"] * }); * ``` */ openapi(schema: Sche