import { Value, NumericValue } from "../values/index.js"; import { DocumentByInfo, FieldPaths, FieldTypeFromFieldPath, GenericTableInfo, } from "./data_model.js"; /** * Expressions are evaluated to produce a {@link values.Value} in the course of executing a query. * * To construct an expression, use the {@link FilterBuilder} provided within * {@link OrderedQuery.filter}. * * @typeParam T - The type that this expression evaluates to. * @public */ export abstract class Expression { // Property for nominal type support. private _isExpression: undefined; // Property to distinguish expressions by the type they resolve to. private _value!: T; /** * @internal */ constructor() { // only defining the constructor so we can mark it as internal and keep // it out of the docs. } } /** * An {@link Expression} or a constant {@link values.Value} * * @public */ export type ExpressionOrValue = Expression | T; /** * An interface for defining filters in queries. * * `FilterBuilder` has various methods that produce {@link Expression}s. * These expressions can be nested together along with constants to express * a filter predicate. * * `FilterBuilder` is used within {@link OrderedQuery.filter} to create query * filters. * * Here are the available methods: * * | | | * |-------------------------------|-----------------------------------------------| * | **Comparisons** | Error when `l` and `r` are not the same type. | * | [`eq(l, r)`](#eq) | `l === r` | * | [`neq(l, r)`](#neq) | `l !== r` | * | [`lt(l, r)`](#lt) | `l < r` | * | [`lte(l, r)`](#lte) | `l <= r` | * | [`gt(l, r)`](#gt) | `l > r` | * | [`gte(l, r)`](#gte) | `l >= r` | * | | | * | **Arithmetic** | Error when `l` and `r` are not the same type. | * | [`add(l, r)`](#add) | `l + r` | * | [`sub(l, r)`](#sub) | `l - r` | * | [`mul(l, r)`](#mul) | `l * r` | * | [`div(l, r)`](#div) | `l / r` | * | [`mod(l, r)`](#mod) | `l % r` | * | [`neg(x)`](#neg) | `-x` | * | | | * | **Logic** | Error if any param is not a `bool`. | * | [`not(x)`](#not) | `!x` | * | [`and(a, b, ..., z)`](#and) | `a && b && ... && z` | * | [`or(a, b, ..., z)`](#or) | a || b || ... || z | * | | | * | **Other** | | * | [`field(fieldPath)`](#field) | Evaluates to the field at `fieldPath`. | * @public */ export interface FilterBuilder { // Comparisons ///////////////////////////////////////////////////////////// /** * `l === r` * * @public * */ eq( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l !== r` * * @public * */ neq( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l < r` * * @public */ lt( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l <= r` * * @public */ lte( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l > r` * * @public */ gt( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l >= r` * * @public */ gte( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; // Arithmetic ////////////////////////////////////////////////////////////// /** * `l + r` * * @public */ add( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l - r` * * @public */ sub( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l * r` * * @public */ mul( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l / r` * * @public */ div( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `l % r` * * @public */ mod( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression; /** * `-x` * * @public */ neg(x: ExpressionOrValue): Expression; // Logic /////////////////////////////////////////////////////////////////// /** * `exprs[0] && exprs[1] && ... && exprs[n]` * * @public */ and(...exprs: Array>): Expression; /** * `exprs[0] || exprs[1] || ... || exprs[n]` * * @public */ or(...exprs: Array>): Expression; /** * `!x` * * @public */ not(x: ExpressionOrValue): Expression; // Other /////////////////////////////////////////////////////////////////// /** * Evaluates to the field at the given `fieldPath`. * * For example, in {@link OrderedQuery.filter} this can be used to examine the values being filtered. * * #### Example * * On this object: * ``` * { * "user": { * "isActive": true * } * } * ``` * * `field("user.isActive")` evaluates to `true`. * * @public */ field>( fieldPath: FieldPath, ): Expression, FieldPath>>; }