/** Primitive and array values in JSON Logic */ export type JsonLogicValue = string | number | boolean | null | JsonLogicValue[]; /** Variable reference */ export interface JsonLogicVar { var: string | number; } /** JSON Logic rule - the input format */ export type JsonLogicRule = { [operator: string]: JsonLogicOperand | JsonLogicOperand[]; } | JsonLogicVar | JsonLogicValue; /** Operand can be a rule, var, or value */ export type JsonLogicOperand = JsonLogicRule | JsonLogicValue; /** The output of compilation */ export interface SqlResult { /** WHERE clause without the WHERE keyword */ sql: string; /** Parameterized values as key-value map */ params: Record; /** Parameterized values as ordered array (for Knex/MySQL style queries) */ paramsArray?: unknown[]; } export interface CompilerConfig { /** Field schema definition */ schema: FilterSchema; /** Maximum nesting depth (default: 5) */ maxDepth?: number; /** Maximum number of conditions (default: 100) */ maxConditions?: number; /** Parameter style (default: 'positional') */ paramStyle?: 'positional' | 'named'; /** Target SQL dialect (default: 'postgresql') */ dialect?: 'postgresql' | 'mysql' | 'mssql' | 'sqlite'; /** * Placeholder style for parameters (default: 'dollar' for postgresql, 'question' for mysql/sqlite) * - 'dollar': $1, $2, $3 (PostgreSQL native) * - 'question': ?, ?, ? (Knex, MySQL, SQLite) * - 'at': @p1, @p2, @p3 (MSSQL) */ placeholderStyle?: 'dollar' | 'question' | 'at'; /** * Parameter key style in params object (default: 'unified') * - 'unified': Always use p1, p2, p3... (consistent across all dialects) * - 'legacy': Use $1, $2 for PostgreSQL, @p1, @p2 for MSSQL, p1, p2 for MySQL/SQLite * * @todo TODO: Implement paramKeyStyle feature * Currently always uses 'unified' style (p1, p2, p3...). * To implement 'legacy' style: * 1. Pass paramKeyStyle from CompilerConfig to CompilerContext * 2. Update BaseDialect.getParamKey() to check context.paramKeyStyle * 3. If 'legacy', return placeholder as key (e.g., '$1', '@p1') * 4. If 'unified' (default), return 'p1', 'p2'... * 5. Update all dialect implementations to use context.paramKeyStyle * * This will allow backward compatibility for code that accesses params['$1'] directly * instead of using paramsArray. */ paramKeyStyle?: 'unified' | 'legacy'; /** Lookup resolvers for remote options */ lookups?: LookupRegistry; } export interface FilterSchema { fields: Record; settings?: SchemaSettings; } export interface SchemaSettings { defaultOperator?: Operator; caseSensitive?: boolean; strict?: boolean; maxDepth?: number; maxConditions?: number; paramStyle?: 'positional' | 'named'; } export interface FieldSchema { type: FieldType; operators: Operator[]; /** Display title for the field (used in UI) */ title: string; /** Localization key for the field label */ labelCode?: string; /** Localization group (namespace) for the field label */ labelGroup?: string; /** Input type for UI rendering */ inputType: string; /** DB column name if different from field name */ column?: string; /** Permissions */ filterable?: boolean; selectable?: boolean; sortable?: boolean; /** Validation */ nullable?: boolean; options?: OptionConfig; constraints?: FieldConstraints; /** SQL transforms */ transform?: FieldTransform; /** JSONB path for nested access */ jsonPath?: string; /** Case sensitivity for string comparisons */ caseSensitive?: boolean; /** * Configuration exposed to the frontend/UI * e.g. placeholder, tooltip, options, etc. */ config?: Record; /** * Internal backend configuration (hidden from frontend) */ internal?: Record; /** * For array types, defines the schema of items */ items?: Partial; } export interface ComputedFieldSchema extends Omit { computed: true; expression: string; } export type FieldType = 'string' | 'text' | 'number' | 'integer' | 'decimal' | 'boolean' | 'date' | 'datetime' | 'timestamp' | 'uuid' | 'array' | 'json' | 'jsonb'; export type Operator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'not_in' | 'contains' | 'contained_by' | 'overlaps' | 'any_of' | 'not_any_of' | 'any_ilike' | 'not_any_ilike' | 'like' | 'ilike' | 'starts_with' | 'ends_with' | 'regex' | 'is_null' | 'is_not_null' | 'between' | 'not_between' | 'json_contains' | 'json_has_key' | 'json_has_any_keys'; export interface OptionConfig { /** Static options */ items?: OptionItem[]; /** Lookup code for remote data */ lookupCode?: string; /** Key to extract value for DB */ valueKey?: string; /** Key for display label */ labelKey?: string; /** Reject if value not in options */ strict?: boolean; } export interface OptionItem { value: string | number; label: string; disabled?: boolean; group?: string; icon?: string; color?: string; [key: string]: unknown; } export type LookupRegistry = Record; export interface LookupConfig { endpoint: string; method?: 'GET' | 'POST'; valueKey: string; labelKey: string; /** Static params to send with request */ params?: Record; /** Search key for filtering */ searchKey?: string; searchMinLength?: number; /** Dependencies for cascading */ dependsOn?: string[]; dependsOnParams?: Record; } export interface FieldConstraints { minLength?: number; maxLength?: number; pattern?: RegExp | string; min?: number; max?: number; minItems?: number; maxItems?: number; dateFormat?: DateFormat | RegExp | string; minDate?: string | Date; maxDate?: string | Date; validate?: (value: unknown) => boolean | string; } export type DateFormat = 'iso' | 'date-only' | 'datetime' | 'YYYY-MM-DD' | 'YYYY/MM/DD' | 'DD-MM-YYYY' | 'DD/MM/YYYY' | 'DD.MM.YYYY' | 'MM-DD-YYYY' | 'MM/DD/YYYY' | 'HH:mm' | 'HH:mm:ss'; export interface FieldTransform { input?: TransformFn | TransformFn[]; output?: TransformFn | TransformFn[]; } export type TransformFn = 'lower' | 'upper' | 'trim' | 'ltrim' | 'rtrim' | 'unaccent' | 'date' | 'year' | 'month' | 'day' | 'toArray' | CustomTransform; export interface CustomTransform { name: string; /** SQL template with {column} placeholder */ sql: string; } export interface CompilerContext { depth: number; conditionCount: number; paramIndex: number; params: Record; /** Current field type being processed (for conditional JSONB casting) */ fieldType?: FieldType; } //# sourceMappingURL=types.d.ts.map