/** * ObjectQL * Copyright (c) 2026-present ObjectStack Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * Validation system types based on the validation metadata specification. * These types define the structure for metadata-driven validation rules. */ import { ObjectDoc } from './object'; /** * Types of validation rules supported by ObjectQL. */ export type ValidationRuleType = 'field' | 'cross_field' | 'business_rule' | 'state_machine' | 'unique' | 'dependency' | 'custom'; /** * Severity levels for validation errors. */ export type ValidationSeverity = 'error' | 'warning' | 'info'; /** * Operations that can trigger validation. */ export type ValidationTrigger = 'create' | 'update' | 'delete'; /** * Comparison operators for validation rules. */ export type ValidationOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'in' | 'not_in' | 'contains' | 'not_contains' | 'starts_with' | 'ends_with'; /** * AI context for validation rules. * Provides semantic information for AI tools to understand validation intent. */ export interface ValidationAiContext { /** Business intent behind the validation rule */ intent?: string; /** Business rule description in natural language */ business_rule?: string; /** Impact level if validation fails */ error_impact?: 'high' | 'medium' | 'low'; /** External dependencies required for validation */ data_dependency?: string; /** External system dependencies */ external_dependency?: string; /** Examples of valid/invalid data */ examples?: { valid?: unknown[]; invalid?: unknown[]; }; /** Algorithm description for complex validation */ algorithm?: string; /** Visualization of the validation logic */ visualization?: string; /** Rationale for the rule */ rationale?: string; /** Decision logic in natural language */ decision_logic?: string; /** Compliance requirements */ compliance?: string; } /** * Condition for applying validation rules. */ export interface ValidationCondition { /** Field to check */ field?: string; /** Comparison operator */ operator?: ValidationOperator; /** Value to compare against */ value?: unknown; /** Field name to compare against (for cross-field validation) */ compare_to?: string; /** Expression to evaluate */ expression?: string; /** Logical AND conditions */ all_of?: ValidationCondition[]; /** Logical OR conditions */ any_of?: ValidationCondition[]; } /** * State transition definition for state machine validation. */ export interface StateTransition { /** States that can transition to this state */ allowed_next?: string[]; /** Whether this is a terminal state */ is_terminal?: boolean; /** AI context for the transition */ ai_context?: ValidationAiContext; } /** * Relationship lookup for business rule validation. */ export interface ValidationRelationship { /** Related object name */ object?: string; /** Field that links to the related object */ via?: string; /** Field(s) to fetch from related object */ field?: string; fields?: string[]; /** Validation to apply on related record */ validate?: ValidationCondition; } /** * Business rule constraint definition. */ export interface BusinessRuleConstraint { /** Expression to evaluate */ expression?: string; /** Relationships needed for the rule */ relationships?: Record; /** * Logical AND conditions (all must be true). * Can be an array of field names (checks if fields are present and non-empty) * or ValidationCondition objects for more complex validations. */ all_of?: (string | ValidationCondition)[]; /** * Logical OR conditions (at least one must be true). * Can be an array of field names (checks if at least one field is present and non-empty) * or ValidationCondition objects for more complex validations. */ any_of?: (string | ValidationCondition)[]; /** Conditional field check - if this field is truthy, then_require fields must be present */ if_field?: string; /** * Required fields when if_field condition is met. * Can be an array of field names (checks if fields are present and non-empty) * or ValidationCondition objects for more complex validations. */ then_require?: (string | ValidationCondition)[]; } /** * Field validation configuration (built into FieldConfig). */ export interface FieldValidation { /** Format validation (email, url, etc.) */ format?: 'email' | 'url' | 'phone' | 'date' | 'datetime'; /** Allowed protocols for URL validation */ protocols?: string[]; /** Minimum value for numbers */ min?: number; /** Maximum value for numbers */ max?: number; /** Minimum length for strings */ min_length?: number; /** Maximum length for strings */ max_length?: number; /** Regular expression pattern for validation */ pattern?: string; /** @deprecated Use pattern instead */ regex?: string; /** Custom validation message */ message?: string; } /** * Base validation rule definition. */ export interface ValidationRule { /** Unique name of the rule */ name: string; /** Type of validation rule */ type: ValidationRuleType; /** Human-readable error message */ message: string | Record; /** Error code for programmatic handling */ error_code?: string; /** Severity level */ severity?: ValidationSeverity; /** Operations that trigger this rule */ trigger?: ValidationTrigger[]; /** Fields that trigger this rule when changed */ fields?: string[]; /** Contexts where this rule applies */ context?: string[]; /** Skip in bulk operations */ skip_bulk?: boolean; /** AI context for understanding the rule */ ai_context?: ValidationAiContext; /** Condition for applying the rule */ apply_when?: ValidationCondition; /** Whether this is an async validation */ async?: boolean; /** Timeout for async validation (ms) */ timeout?: number; } /** * Cross-field validation rule. * Supports two formats: * 1. Using the 'rule' property with a ValidationCondition object * 2. Shorthand format with field, operator, and value/compare_to properties directly on the rule */ export interface CrossFieldValidationRule extends ValidationRule { type: 'cross_field'; /** The validation rule to apply */ rule?: ValidationCondition; /** Shorthand: Field to check (alternative to using rule property) */ field?: string; /** Shorthand: Comparison operator (alternative to using rule property) */ operator?: ValidationOperator; /** Shorthand: Value to compare against (mutually exclusive with compare_to) */ value?: unknown; /** Shorthand: Field name to compare against for cross-field validation (mutually exclusive with value) */ compare_to?: string; } /** * Business rule validation. */ export interface BusinessRuleValidationRule extends ValidationRule { type: 'business_rule'; /** The business rule constraint */ constraint?: BusinessRuleConstraint; } /** * State machine validation rule. */ export interface StateMachineValidationRule extends ValidationRule { type: 'state_machine'; /** Field containing the state */ field: string; /** Valid state transitions */ transitions?: Record; /** Initial states */ initial_states?: string[]; /** Transition conditions */ transition_conditions?: Record; } /** * Uniqueness validation rule. */ export interface UniquenessValidationRule extends ValidationRule { type: 'unique'; /** Field to check for uniqueness */ field?: string; /** Multiple fields for composite uniqueness */ fields?: string[]; /** Case sensitivity for string comparison */ case_sensitive?: boolean; /** Scope constraint for conditional uniqueness */ scope?: ValidationCondition; } /** * Dependency validation rule. */ export interface DependencyValidationRule extends ValidationRule { type: 'dependency'; /** Validation condition */ condition?: { /** Lookup validation */ lookup?: ValidationRelationship; /** Related records check */ has_related?: { object: string; relation_field: string; filter?: ValidationCondition[]; }; }; } /** * Custom validation rule with validator function. */ export interface CustomValidationRule extends ValidationRule { type: 'custom'; /** Validator function as string */ validator?: string; /** Error message template */ error_message_template?: string; /** Message parameters */ message_params?: Record; } /** * Union type for all validation rules. */ export type AnyValidationRule = ValidationRule | CrossFieldValidationRule | BusinessRuleValidationRule | StateMachineValidationRule | UniquenessValidationRule | DependencyValidationRule | CustomValidationRule; /** * Validation group definition. */ export interface ValidationGroup { /** Group name */ name: string; /** Group description */ description?: string; /** Rules in this group */ rules: string[]; /** Whether group runs asynchronously */ async?: boolean; /** Whether this group is required */ required?: boolean; } /** * Complete validation configuration for an object. */ export interface ValidationConfig { /** Name of the validation configuration */ name: string; /** Object this validation applies to */ object: string; /** Description */ description?: string; /** AI context for the overall validation strategy */ ai_context?: ValidationAiContext; /** Validation rules */ rules: AnyValidationRule[]; /** Validation groups */ validation_groups?: ValidationGroup[]; } /** * Context provided to validation functions. */ export interface ValidationContext { /** Current record data */ record: ObjectDoc; /** Previous record data (for updates) */ previousRecord?: ObjectDoc; /** Current user */ user?: unknown; /** API access for queries */ api?: unknown; /** HTTP client for external calls */ http?: unknown; /** Operation type */ operation: ValidationTrigger; /** Additional metadata */ metadata?: { objectName: string; ruleName: string; [key: string]: unknown; }; /** Changed fields (for updates) */ changedFields?: string[]; } /** * Result of a single validation rule. */ export interface ValidationRuleResult { /** Rule name */ rule: string; /** Whether validation passed */ valid: boolean; /** Error message if validation failed */ message?: string; /** Error code */ error_code?: string; /** Severity level */ severity?: ValidationSeverity; /** Field(s) that failed validation */ fields?: string[]; /** Additional context */ context?: unknown; } /** * Overall validation result for a record. */ export interface ValidationResult { /** Whether all validations passed */ valid: boolean; /** Individual rule results */ results: ValidationRuleResult[]; /** Errors (severity: error) */ errors: ValidationRuleResult[]; /** Warnings (severity: warning) */ warnings: ValidationRuleResult[]; /** Info messages (severity: info) */ info: ValidationRuleResult[]; } /** * Validation error class. */ export declare class ValidationError extends Error { results: ValidationRuleResult[]; code?: string | undefined; constructor(message: string, results: ValidationRuleResult[], code?: string | undefined); }