export type FilterFieldType = 'text' | 'number' | 'date' | 'date-range' | 'enum' | 'multi-enum' | 'boolean'; /** REQ-SURF-84: the type parameter keeps the literal field type, so a schema declared `as const` narrows each field's operator set. */ export interface FilterField { id: string; label: string; type: T; options?: readonly { value: string; label: string; }[] | undefined; operators?: readonly string[] | undefined; } export declare const DEFAULT_OPERATORS: Record; /** Operators valid for a field type (REQ-SURF-84 matrix). */ export type Ops = T extends 'text' ? 'contains' | 'equals' | 'starts-with' | 'is-empty' : T extends 'number' ? '=' | '!=' | '<' | '<=' | '>' | '>=' | 'between' : T extends 'date' ? 'on' | 'before' | 'after' | 'between' : T extends 'date-range' ? 'between' | 'before' | 'after' : T extends 'enum' ? 'is' | 'is-not' : T extends 'multi-enum' ? 'any-of' | 'none-of' : 'is'; /** An inclusive range: number fields use numbers, date fields ISO strings. */ export interface FilterRange { start: T; end: T; } /** REQ-SURF-86: every value shape a rule can carry. 'between' on number is a numeric range, on date/date-range a string range; boolean is a real boolean (never the string 'true'). */ export type FilterValue = string | number | boolean | readonly string[] | FilterRange | FilterRange; export interface FilterRule { kind: 'rule'; id: string; fieldId: string; operator: Ops; value?: FilterValue | undefined; } /** Operators that take no value. */ export declare const VALUELESS_OPERATORS: readonly string[]; /** REQ-SURF-86: is `value` a legal value for `field` under `operator`? `undefined` (no value yet) is always legal; valueless operators accept nothing else. Used by parse to reject tampered or mistyped URLs. */ export declare function isValidRuleValue(field: FilterField, operator: string, value: unknown): boolean; export interface FilterGroup { kind: 'group'; id: string; combinator: 'and' | 'or'; children: readonly (FilterRule | FilterGroup)[]; } export type FilterNode = FilterRule | FilterGroup; export declare function isGroup(n: FilterNode): n is FilterGroup; export declare function emptyGroup(combinator?: 'and' | 'or'): FilterGroup; export declare function makeRule(field: F, operator: Ops, value?: FilterRule['value']): FilterRule; export interface FilterModel { value: FilterGroup; addRule: (rule: FilterRule, groupId?: string) => void; updateRule: (ruleId: string, patch: Partial>) => void; removeRule: (ruleId: string) => void; addGroup: (group?: FilterGroup, parentId?: string) => void; removeGroup: (groupId: string) => void; setCombinator: (groupId: string, combinator: 'and' | 'or') => void; clear: () => void; } /** Test/dev helper: recursively freeze a tree. */ export declare function deepFreeze(o: T): T; //# sourceMappingURL=filter-model.d.ts.map