/** * SCIM 2.0 Query Builder * * Type-safe query builder for SCIM 2.0 filtering. * * @example * ```typescript * // Array-based (recommended for UI) * const filters: QueryConditions = [ * { field: 'first_name', op: 'eq', value: 'John' }, * { field: 'age', op: 'gt', value: 18, connector: 'and' }, * ] * buildQuery(filters) // → 'first_name eq "John" and age gt 18' * * // Range query (same field twice) * const rangeFilters: QueryConditions = [ * { field: 'amount', op: 'ge', value: 100 }, * { field: 'amount', op: 'le', value: 500, connector: 'and' }, * ] * buildQuery(rangeFilters) // → 'amount ge 100 and amount le 500' * ``` */ type Primitive = string | number | boolean | null; type DeepKeyOf = T extends Primitive ? never : { [K in keyof T & string]: K | `${K}.${DeepKeyOf}`; }[keyof T & string]; /** * SCIM 2.0 comparison operators */ export type ComparisonOperator = 'eq' | 'ne' | 'gt' | 'ge' | 'lt' | 'le' | 'co' | 'sw' | 'ew' | 'pr' | 'in' | 'nin'; /** * SCIM 2.0 logical operators */ export type LogicalOperator = 'and' | 'or'; /** * A single filter condition */ export interface FilterCondition = Record> { field: DeepKeyOf | string; op: ComparisonOperator; value?: Primitive | Primitive[]; connector?: LogicalOperator; } /** * Array of filter conditions - the primary way to define queries */ export type QueryConditions = Record> = FilterCondition[]; /** * Build a SCIM 2.0 query string from conditions array * * @example * ```typescript * buildQuery([ * { field: 'name', op: 'eq', value: 'John' }, * { field: 'age', op: 'gt', value: 18, connector: 'and' }, * ]) * // → 'name eq "John" and age gt 18' * ``` */ export declare function buildQuery>(conditions?: QueryConditions): string; /** * Query Builder for SCIM 2.0 filtering */ export declare class QueryFilter> { private parts; /** * Equal comparison */ eq>(field: K, value: Primitive): this; /** * Not equal comparison */ ne>(field: K, value: Primitive): this; /** * Greater than comparison */ gt>(field: K, value: number | string): this; /** * Greater than or equal comparison */ ge>(field: K, value: number | string): this; /** * Less than comparison */ lt>(field: K, value: number | string): this; /** * Less than or equal comparison */ le>(field: K, value: number | string): this; /** * Contains comparison (for strings) */ co>(field: K, value: string): this; /** * Starts with comparison (for strings) */ sw>(field: K, value: string): this; /** * Ends with comparison (for strings) */ ew>(field: K, value: string): this; /** * Present check (field has a value) */ pr>(field: K): this; /** * AND logical operator */ and(): this; /** * OR logical operator */ or(): this; /** * NOT logical operator */ not(): this; /** * Group expressions with parentheses */ group(builderFn: (qb: QueryFilter) => QueryFilter): this; /** * Add raw query string (use with caution) */ raw(query: string): this; /** * Clear the query */ clear(): this; /** * Build the final query string */ build(): string; /** * Convert to string automatically (allows using builder without .build()) */ toString(): string; /** * Allow implicit string conversion */ [Symbol.toPrimitive](hint: string): string | number; /** * Format value for SCIM 2.0 query */ private static formatValue; } /** * Build a query string from conditions or create a chainable query builder * * @example * ```typescript * // From conditions array * queryFilter([ * { field: 'first_name', op: 'eq', value: 'John' }, * { field: 'age', op: 'gt', value: 18, connector: 'and' }, * ]).build() * // → 'first_name eq "John" and age gt 18' * * // Chainable builder * queryFilter().eq('first_name', 'John').and().gt('age', 18).build() * // → 'first_name eq "John" and age gt 18' * * // Empty returns empty builder * queryFilter() // → QueryFilter instance * ``` */ export declare function queryFilter>(conditions?: QueryConditions): QueryFilter; /** * Create a query that checks if any of the fields match the value */ export declare function anyOf>(fields: Array | string>, value: Primitive): string; /** * Create a range query (field >= min and field <= max) */ export declare function range>(field: DeepKeyOf | string, min: number | string, max: number | string): string; /** * Create a search query across multiple string fields (OR) */ export declare function search>(fields: Array | string>, searchTerm: string): string; /** * Evaluate a SCIM 2.0 query string against a data object. * Returns true if the data matches, or if the query is empty/invalid. * * @example * ```typescript * evaluateQuery('status eq "active" and age gt 18', { status: 'active', age: 25 }) // → true * evaluateQuery('status eq "active" and age gt 18', { status: 'inactive', age: 25 }) // → false * ``` */ export declare function evaluateQuery(query: string, data: Record): boolean; /** * Parse a SCIM 2.0 query string into conditions array * Supports grouping with parentheses: (a eq 1 or b eq 2) and c eq 3 * * @example * ```typescript * parseQuery('first_name eq "John" and age gt 18') * // → [ * // { field: 'first_name', op: 'eq', value: 'John' }, * // { field: 'age', op: 'gt', value: 18, connector: 'and' }, * // ] * * parseQuery('(item eq "A" or item eq "B") and status eq "active"') * // → [ * // { field: 'item', op: 'eq', value: 'A' }, * // { field: 'item', op: 'eq', value: 'B', connector: 'or' }, * // { field: 'status', op: 'eq', value: 'active', connector: 'and' }, * // ] * ``` */ export declare function parseQuery = Record>(queryString?: string): QueryConditions; export {}; //# sourceMappingURL=queryFilter.d.ts.map