# Filtron API reference Generated from the exported types and JSDoc of each package. ## @filtron/core Filtron parses human-friendly filter strings into structured queries you can use anywhere — SQL databases, in-memory arrays, or your own custom backend. ### parse Kind: function ```typescript function parse(query: string, options?: ParseOptions): ParseResult; ``` Parses a Filtron query string into an Abstract Syntax Tree (AST). Parameters: - `query`: The Filtron query string to parse - `options`: Optional parse limits, see ParseOptions Returns: A ParseResult containing either the AST or an error Example: ```typescript const result = parse('age > 18 AND status = "active"'); if (result.success) { console.log(result.ast); } else { console.error(result.message); } ``` ### parseOrThrow Kind: function ```typescript function parseOrThrow(query: string, options?: ParseOptions): ASTNode; ``` Parses a Filtron query string and throws an error if parsing fails. Use this when you want to handle errors with try/catch instead of checking the result. Parameters: - `query`: The Filtron query string to parse - `options`: Optional parse limits, see ParseOptions Returns: The parsed AST Throws: FiltronParseError if parsing fails, with position information Example: ```typescript try { const ast = parseOrThrow("age > 18"); console.log(ast); } catch (error) { if (error instanceof FiltronParseError) { console.error("Parse failed at position", error.position, ":", error.message); } } ``` ### FiltronParseError Kind: class ```typescript class FiltronParseError extends Error { constructor(message: string, position?: number); position: number | undefined; } ``` Error thrown when parsing a Filtron query fails. Includes the position in the query where the error occurred. ### ParseOptions Kind: interface ```typescript interface ParseOptions { maxLength?: number; maxDepth?: number; } ``` Limits applied while parsing a query. Both values are upper bounds; pass larger numbers to raise them. ### ParseResult Kind: type ```typescript type ParseResult = ParseSuccess | ParseFailure; ``` The generic parse result ### ParseSuccess Kind: interface ```typescript interface ParseSuccess { success: true; ast: ASTNode; } ``` Result of a successful parse operation ### ParseFailure Kind: interface ```typescript interface ParseFailure { success: false; message: string; position?: number; } ``` Result of a failed parse operation ### walk Kind: function ```typescript function walk(node: ASTNode, visitor: (node: ASTNode) => boolean | undefined): void; ``` Walks an AST in pre-order depth-first order, calling the visitor on each node The visitor is called on a node before its children. Returning false from the visitor skips that node's children; any other return value (including undefined) descends. Children of "or" and "and" nodes are visited in order; "not" nodes descend through their expression. All other nodes are leaves. Parameters: - `node`: The AST node to walk - `visitor`: Called once per visited node; return false to skip children Example: ```typescript import { parseOrThrow, walk } from "@filtron/core"; const ast = parseOrThrow('age > 18 AND status = "active"'); const fields: string[] = []; walk(ast, (node) => { if ("field" in node) { fields.push(node.field); } }); // fields: ["age", "status"] ``` ### print Kind: function ```typescript function print(node: ASTNode): string; ``` Prints an AST as canonical Filtron query text Parsing the output reproduces the AST: parseOrThrow(print(ast)) is deeply equal to ast for any parser-produced tree. Parentheses appear only where a child binds looser than its parent, strings are double-quoted with escapes, and temporal values print behind @. Useful for canonicalizing queries (cache keys, logs) and roundtrip testing. Parameters: - `node`: The AST node to print Returns: The canonical query text Example: ```typescript import { parseOrThrow, print } from "@filtron/core"; print(parseOrThrow("(a AND (b OR c))")); // "a AND (b OR c)" ``` ### validateFields Kind: function ```typescript function validateFields(node: ASTNode, allowedFields: readonly string[]): void; ``` Validates that every field referenced in an AST is in the allowlist Walks the AST in pre-order and throws on the first field that is not in `allowedFields`. Useful for guarding hand-built ASTs and untrusted queries before generating filters or SQL. Parameters: - `node`: The AST node to validate - `allowedFields`: Field names that are allowed to appear in the AST Throws: Error if a field is not in the allowlist Example: ```typescript import { parseOrThrow, validateFields } from "@filtron/core"; const ast = parseOrThrow('password = "hunter2"'); validateFields(ast, ["name", "age"]); // Error: Field "password" is not allowed. Allowed fields: name, age ``` ### Lexer Kind: class ```typescript class Lexer { constructor(input: string); next(): Token; } ``` Lexer for tokenizing Filtron query strings ### Token Kind: type ```typescript type Token = StringToken | NumberToken | BooleanToken | TemporalToken | SymbolToken; ``` Discriminated union of all token types for proper type narrowing ### TokenType Kind: type ```typescript type TokenType = | "LPAREN" | "RPAREN" | "LBRACKET" | "RBRACKET" | "COMMA" | "QUESTION" | "DOT" | "DOTDOT" | "MINUS" | "AND" | "OR" | "NOT" | "TRUE" | "FALSE" | "EQ" | "NEQ" | "GT" | "GTE" | "LT" | "LTE" | "LIKE" | "COLON" | "NOT_COLON" | "STRING" | "NUMBER" | "IDENT" | "TEMPORAL" | "EOF"; ``` Token types produced by the lexer ### StringToken Kind: interface ```typescript interface StringToken extends TokenBase { type: "STRING" | "IDENT"; value: string; } ``` Tokens with string values (string literals and identifiers) ### NumberToken Kind: interface ```typescript interface NumberToken extends TokenBase { type: "NUMBER"; value: number; } ``` Tokens with number values ### BooleanToken Kind: interface ```typescript interface BooleanToken extends TokenBase { type: "TRUE" | "FALSE"; value: boolean; } ``` Tokens with boolean values ### SymbolToken Kind: interface ```typescript interface SymbolToken extends TokenBase { type: | "LPAREN" | "RPAREN" | "LBRACKET" | "RBRACKET" | "COMMA" | "QUESTION" | "DOT" | "DOTDOT" | "MINUS" | "AND" | "OR" | "NOT" | "EQ" | "NEQ" | "GT" | "GTE" | "LT" | "LTE" | "LIKE" | "COLON" | "NOT_COLON" | "EOF"; } ``` Tokens without values (operators, punctuation, keywords, EOF) ### ASTNode Kind: type ```typescript type ASTNode = | OrExpression | AndExpression | NotExpression | ComparisonExpression | OneOfExpression | ExistsExpression | BooleanFieldExpression; ``` Root AST node type - represents any valid Filtron expression ### Value Kind: type ```typescript type Value = | StringValue | NumberValue | BooleanValue | IdentifierValue | RangeValue | DateValue | NowValue; ``` Value type - represents literal values in expressions ### ComparisonOperator Kind: type ```typescript type ComparisonOperator = "=" | "!=" | "~" | ">" | ">=" | "<" | "<=" | ":"; ``` Comparison operators supported ### OrExpression Kind: interface ```typescript interface OrExpression { type: "or"; children: ASTNode[]; } ``` Logical OR expression - combines two or more expressions with OR Chains are flat: children always has at least two entries and never contains another OrExpression. The parser splices nested OR chains (including parenthesized ones) into a single node. ### AndExpression Kind: interface ```typescript interface AndExpression { type: "and"; children: ASTNode[]; } ``` Logical AND expression - combines two or more expressions with AND Chains are flat: children always has at least two entries and never contains another AndExpression. The parser splices nested AND chains (including parenthesized ones) into a single node. ### NotExpression Kind: interface ```typescript interface NotExpression { type: "not"; expression: ASTNode; } ``` Logical NOT expression - negates an expression ### ComparisonExpression Kind: interface ```typescript interface ComparisonExpression { type: "comparison"; field: string; operator: ComparisonOperator; value: Value; } ``` Comparison expression - compares a field to a value using an operator Example: age > 18, status = "active" ### OneOfExpression Kind: interface ```typescript interface OneOfExpression { type: "oneOf"; field: string; values: Value[]; negated: boolean; } ``` Membership expression - checks whether a field matches any value in a list Example: status : ["pending", "approved"], status !: ["deleted"] (negated) ### ExistsExpression Kind: interface ```typescript interface ExistsExpression { type: "exists"; field: string; negated: boolean; } ``` Exists expression - checks whether a field exists (is not null/undefined) Example: email?, -email (negated) ### BooleanFieldExpression Kind: interface ```typescript interface BooleanFieldExpression { type: "booleanField"; field: string; } ``` Boolean field expression - shorthand for checking if a boolean field is true Example: verified, premium ### StringValue Kind: interface ```typescript interface StringValue { type: "string"; value: string; } ``` String value - a quoted string literal ### NumberValue Kind: interface ```typescript interface NumberValue { type: "number"; value: number; } ``` Number value - an integer or floating-point number ### BooleanValue Kind: interface ```typescript interface BooleanValue { type: "boolean"; value: boolean; } ``` Boolean value - true or false ### IdentifierValue Kind: interface ```typescript interface IdentifierValue { type: "identifier"; value: string; } ``` Identifier value - an unquoted identifier used as a value ### RangeValue Kind: type ```typescript type RangeValue = NumberRangeValue | TemporalRangeValue; ``` Range value - an inclusive interval over numbers or points in time ### NumberRangeValue Kind: interface ```typescript interface NumberRangeValue { type: "range"; kind: "number"; min: number; max: number; } ``` Range value over numbers - an inclusive interval Valid with the =, : and != operators only Example: age = 18..65, price != 0..100 ### TemporalRangeValue Kind: interface ```typescript interface TemporalRangeValue { type: "range"; kind: "temporal"; min: TemporalPoint; max: TemporalPoint; } ``` Range value over points in time - an inclusive interval Valid with the =, : and != operators only Example: deployed = @2024-06-01..2024-06-30, created = ### DateValue Kind: interface ```typescript interface DateValue { type: "date"; value: string; } ``` Date value - an absolute point in time, written as @ Example: @2024-06-01, @2024-06-30T14:00:00Z ### NowValue Kind: interface ```typescript interface NowValue { type: "now"; offset: { amount: number; unit: DurationUnit; } | null; } ``` Now value - a point in time relative to evaluation, written as ### TemporalPoint Kind: type ```typescript type TemporalPoint = DateValue | NowValue; ``` A temporal range bound: an absolute date or a now-relative point ### DurationUnit Kind: type ```typescript type DurationUnit = "s" | "m" | "h" | "d" | "w" | "M" | "y"; ``` Units for now-relative offsets Case-sensitive: m is minutes, M is months ## @filtron/js Filtron helper: transform filter expressions into JavaScript predicates for Array.filter() ### toFilter Kind: function ```typescript function toFilter = Record>( ast: ASTNode, options?: FilterOptions, ): FilterPredicate; ``` Converts a Filtron AST to a predicate function for filtering arrays Parameters: - `ast`: The Filtron AST node to convert - `options`: Filter generation options Returns: A predicate function that can be used with Array.filter() Example: ```typescript import { parse } from "@filtron/core"; import { toFilter } from "@filtron/js"; const result = parse('age > 18 AND status = "active"'); if (result.success) { const filter = toFilter(result.ast); const users = [ { name: "Alice", age: 25, status: "active" }, { name: "Bob", age: 16, status: "active" }, { name: "Charlie", age: 30, status: "inactive" }, ]; const filtered = users.filter(filter); // [{ name: 'Alice', age: 25, status: 'active' }] } ``` ### nestedAccessor Kind: function ```typescript function nestedAccessor( separator?: string, ): (obj: Record, field: string) => unknown; ``` Creates a field accessor for nested properties using dot notation Parameters: - `separator`: The separator used in field names (default: ".") Returns: A field accessor function Example: ```typescript const filter = toFilter(ast, { fieldAccessor: nestedAccessor(), }); // Now you can query nested fields like "user.address.city" const items = data.filter(filter); ``` ### FilterPredicate Kind: type ```typescript type FilterPredicate> = (item: T) => boolean; ``` Predicate function type that filters objects ### FilterOptions Kind: interface ```typescript interface FilterOptions { allowedFields?: string[]; fieldAccessor?: (obj: Record, field: string) => unknown; caseInsensitive?: boolean; fieldMapping?: Record; } ``` Filter generation options ## @filtron/sql Filtron helper: generate safe, parameterized SQL WHERE clauses from filter expressions ### toSQL Kind: function ```typescript function toSQL(ast: ASTNode, options?: SQLOptions): SQLResult; ``` Converts a Filtron AST to a parameterized SQL WHERE clause Parameters: - `ast`: The Filtron AST node to convert - `options`: SQL generation options Returns: SQL result with WHERE clause and parameters Example: ```typescript import { parse } from "@filtron/core"; import { toSQL } from "@filtron/sql"; const ast = parse('age > 18 AND status = "active"'); if (ast.success) { const { sql, params } = toSQL(ast.ast); console.log(sql); // "age > $1 AND status = $2" console.log(params); // [18, "active"] } ``` ### escapeLike Kind: function ```typescript function escapeLike(value: string): string; ``` Escapes special LIKE characters (%, _, \) in a string value Use this to prevent LIKE injection when user input is used in LIKE patterns Parameters: - `value`: The value to escape Returns: Escaped string safe for use in LIKE patterns Example: ```typescript escapeLike("admin%"); // "admin\\%" escapeLike("test_user"); // "test\\_user" ``` ### contains Kind: function ```typescript function contains(value: string | number | boolean): string; ``` Wraps a value with wildcards for "contains" matching Automatically escapes special LIKE characters This is the default `~` value transform (likeMode 'contains') Parameters: - `value`: The value to wrap Returns: Value wrapped with % wildcards Example: ```typescript contains("foo"); // "%foo%" ``` ### prefix Kind: function ```typescript function prefix(value: string | number | boolean): string; ``` Adds trailing wildcard for "starts with" matching Automatically escapes special LIKE characters Parameters: - `value`: The value to wrap Returns: Value with % wildcard at the end Example: ```typescript toSQL(ast, { valueMapper: prefix }); // "admin" becomes "admin%" ``` ### suffix Kind: function ```typescript function suffix(value: string | number | boolean): string; ``` Adds leading wildcard for "ends with" matching Automatically escapes special LIKE characters Parameters: - `value`: The value to wrap Returns: Value with % wildcard at the beginning Example: ```typescript toSQL(ast, { valueMapper: suffix }); // ".pdf" becomes "%.pdf" ``` ### SQLResult Kind: interface ```typescript interface SQLResult { sql: string; params: unknown[]; } ``` SQL generation result ### SQLOptions Kind: interface ```typescript interface SQLOptions { dialect?: "postgres" | "mysql" | "sqlite"; parameterStyle?: "numbered" | "question"; fieldMapper?: (field: string) => string; valueMapper?: (value: string | number | boolean) => string | number | boolean; likeMode?: "contains" | "raw"; startIndex?: number; allowedFields?: string[]; } ``` SQL generation options ## @filtron/time-resolver Filtron helper: resolve now-relative temporal values into absolute dates ### resolveTemporal Kind: function ```typescript function resolveTemporal(node: ASTNode, options?: ResolveTemporalOptions): ASTNode; ``` Resolves every now-relative temporal value in an AST to an absolute date, returning a new AST Nodes without relative values are returned by reference, so an AST without any `@now` usage comes back unchanged and identity-equal. Fixed-length units (s, m, h, d, w) offset by exact milliseconds; months and years move the calendar in UTC and clamp to the last day of the target month (Jan 31 minus one month is Feb 28 or 29). Resolved dates are full ISO 8601 UTC instants. Parameters: - `node`: The AST to resolve - `options`: Resolution options Returns: An AST in which every temporal value is absolute Throws: Error if the reference time is invalid or a resolved range ends up inverted Example: ```typescript import { parseOrThrow } from "@filtron/core"; import { resolveTemporal } from "@filtron/time-resolver"; const ast = resolveTemporal(parseOrThrow("created > @now-7d"), { now: new Date("2026-07-17T12:00:00Z"), }); // comparison value: { type: "date", value: "2026-07-10T12:00:00.000Z" } ``` ### ResolveTemporalOptions Kind: interface ```typescript interface ResolveTemporalOptions { now?: Date; } ``` Options for resolveTemporal