Overview
Modern AST-based filter expression builder API that provides a cleaner, type-safe alternative to direct FilterNode construction for creating complex query filters.
Description
This file defines a typed filter expression Abstract Syntax Tree (AST) with four node types: AllExpression (matches everything), ConditionExpression (field + operator + value), AndExpression (logical AND of multiple expressions), and OrExpression (logical OR of multiple expressions). It exports a FilterAST module object with builder functions for creating filters, combining them, serializing/deserializing to JSON, validating structure, simplifying redundancies, and negating conditions.
The ConditionExpression uses a FieldSpec type that supports typed access to columns across three tables (request_response_rmt, sessions_request_response_rmt, users_view) with optional subtypes for property and score filtering, and key/value mode selection for map-type columns.
The file also defines a comprehensive set of FilterOperator values (eq, neq, is, gt, gte, lt, lte, like, ilike, contains, not-contains, in) and a not() function that implements operator negation using De Morgan-style inversion.
Usage
Use FilterAST as the primary API for building filter expressions in the frontend. It replaces direct construction of FilterNode trees with a more ergonomic builder pattern. The exported DEFAULT_FILTER_EXPRESSION and DEFAULT_FILTER_GROUP_EXPRESSION constants provide common starting points.
Code Reference
Source Location
Signature
export const FilterAST = {
all: () => AllExpression,
condition: (column, operator, value) => ConditionExpression,
and: (...expressions) => AndExpression,
or: (...expressions) => OrExpression,
where: condition, // Alias for condition
property: propertyCondition, // Filter on property value
propertyKey: propertyKeyCondition, // Filter on property key name
score: scoreCondition, // Filter on score value
scoreKey: scoreKeyCondition, // Filter on score key name
serializeFilter: (filter) => string,
deserializeFilter: (json) => FilterExpression,
isEmptyFilter: (filter) => boolean,
simplifyFilter: (filter) => FilterExpression,
createDefaultFilter: () => FilterExpression,
createDefaultPropertyFilter: () => FilterExpression,
createDefaultScoreFilter: () => FilterExpression,
combineFilters: (filters) => FilterExpression,
validateFilter: (filter) => boolean,
not: (expr) => AndExpression,
types: { FILTER_OPERATOR_LABELS },
};
export const DEFAULT_FILTER_EXPRESSION: ConditionExpression;
export const DEFAULT_FILTER_GROUP_EXPRESSION: AndExpression;
export const EMPTY_FILTER_GROUP_EXPRESSION: null;
export type {
RequestResponseRMT, FilterOperator, FilterExpression,
AllExpression, FieldSpec, ConditionExpression, AndExpression, OrExpression,
};
Import
import {
FilterAST,
FilterExpression,
ConditionExpression,
DEFAULT_FILTER_EXPRESSION,
} from "@helicone-package/filters/filterExpressions";
AST Node Types
Expression Type Hierarchy
type FilterExpression =
| AllExpression // { type: "all" }
| ConditionExpression // { type: "condition", field, operator, value }
| AndExpression // { type: "and", expressions: FilterExpression[] }
| OrExpression // { type: "or", expressions: FilterExpression[] }
ConditionExpression
interface ConditionExpression {
type: "condition";
field: FieldSpec; // Table, column, optional subtype and key
operator: FilterOperator; // eq, neq, gt, gte, lt, lte, like, ilike, etc.
value: string | number | boolean;
}
FieldSpec
type FieldSpec =
| { table: "request_response_rmt"; column: keyof RequestResponseRMT;
subtype?: FilterSubType; valueMode?: "value" | "key"; key?: string; }
| { table: "sessions_request_response_rmt"; column: keyof Views["session_metrics"]; ... }
| { table: "users_view"; column: keyof Views["users_view"]; ... }
Filter Operators
| Operator |
Label |
Description
|
eq |
equals |
Exact equality
|
neq |
not equals |
Inequality
|
is |
is |
Identity check
|
gt |
greater than |
Strictly greater
|
gte |
greater than or equals |
Greater or equal
|
lt |
less than |
Strictly less
|
lte |
less than or equals |
Less or equal
|
like |
contains (case sensitive) |
Case-sensitive pattern match
|
ilike |
contains (case insensitive) |
Case-insensitive pattern match
|
contains |
contains |
Containment check
|
not-contains |
not contains |
Negative containment
|
in |
in |
Set membership
|
I/O Contract
Inputs (FilterAST.condition)
| Name |
Type |
Required |
Description
|
| column |
string |
Yes |
Column name from request_response_rmt (or other supported table)
|
| operator |
FilterOperator |
Yes |
Comparison operator
|
| value |
string, number, or boolean |
Yes |
Value to compare against
|
Outputs
| Name |
Type |
Description
|
| FilterExpression |
union type |
An AST node representing the filter condition or combination
|
Builder Functions
Core Builders
| Function |
Description |
Returns
|
FilterAST.all() |
Match all records (no filtering) |
AllExpression
|
FilterAST.condition(column, op, value) |
Single column condition |
ConditionExpression
|
FilterAST.and(...exprs) |
Logical AND combination |
AndExpression
|
FilterAST.or(...exprs) |
Logical OR combination |
OrExpression
|
FilterAST.where(column, op, value) |
Alias for condition |
ConditionExpression
|
Specialized Builders
| Function |
Description
|
FilterAST.property(key, op, value) |
Filter on a property key's value (subtype: "property", valueMode: "value")
|
FilterAST.propertyKey(op, value) |
Filter on property key names (subtype: "property", valueMode: "key")
|
FilterAST.score(key, op, value) |
Filter on a score key's value (subtype: "score", valueMode: "value")
|
FilterAST.scoreKey(op, value) |
Filter on score key names (subtype: "score", valueMode: "key")
|
FilterAST.not(expr) |
Negate a condition by inverting its operator
|
Utility Functions
| Function |
Description
|
serializeFilter(filter) |
Convert FilterExpression to JSON string
|
deserializeFilter(json) |
Parse JSON string back to FilterExpression
|
isEmptyFilter(filter) |
Check if filter effectively matches all records
|
simplifyFilter(filter) |
Remove redundant "all" nodes and flatten single-child compounds
|
combineFilters(filters[]) |
Merge multiple filters with AND, skipping empty ones
|
validateFilter(filter) |
Validate structural correctness of a filter expression
|
Usage Examples
import { FilterAST } from "@helicone-package/filters/filterExpressions";
// Simple condition
const statusFilter = FilterAST.condition("status", "eq", 200);
// Combined filter with AND/OR
const complexFilter = FilterAST.and(
FilterAST.where("status", "eq", 200),
FilterAST.or(
FilterAST.where("model", "like", "gpt-3"),
FilterAST.where("model", "like", "gpt-4")
),
FilterAST.property("user_type", "eq", "admin")
);
// Serialize for storage
const json = FilterAST.serializeFilter(complexFilter);
// Check and simplify
if (!FilterAST.isEmptyFilter(complexFilter)) {
const simplified = FilterAST.simplifyFilter(complexFilter);
}
Related Pages