import { JSONValue, Value, NumericValue } from "../../values/index.js"; import { convexOrUndefinedToJson } from "../../values/value.js"; import { GenericTableInfo } from "../data_model.js"; import { Expression, ExpressionOrValue, FilterBuilder, } from "../filter_builder.js"; // The `any` type parameter in `Expression` allows us to use this class // in place of any `Expression` type in `filterBuilderImpl`. export class ExpressionImpl extends Expression { private inner: JSONValue; constructor(inner: JSONValue) { super(); this.inner = inner; } serialize(): JSONValue { return this.inner; } } export function serializeExpression( expr: ExpressionOrValue, ): JSONValue { if (expr instanceof ExpressionImpl) { return expr.serialize(); } else { // Assume that the expression is a literal Convex value, which we'll serialize // to its JSON representation. return { $literal: convexOrUndefinedToJson(expr as Value | undefined) }; } } export const filterBuilderImpl: FilterBuilder = { // Comparisons ///////////////////////////////////////////////////////////// eq( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $eq: [serializeExpression(l), serializeExpression(r)], }); }, neq( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $neq: [serializeExpression(l), serializeExpression(r)], }); }, lt( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $lt: [serializeExpression(l), serializeExpression(r)], }); }, lte( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $lte: [serializeExpression(l), serializeExpression(r)], }); }, gt( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $gt: [serializeExpression(l), serializeExpression(r)], }); }, gte( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $gte: [serializeExpression(l), serializeExpression(r)], }); }, // Arithmetic ////////////////////////////////////////////////////////////// add( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $add: [serializeExpression(l), serializeExpression(r)], }); }, sub( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $sub: [serializeExpression(l), serializeExpression(r)], }); }, mul( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $mul: [serializeExpression(l), serializeExpression(r)], }); }, div( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $div: [serializeExpression(l), serializeExpression(r)], }); }, mod( l: ExpressionOrValue, r: ExpressionOrValue, ): Expression { return new ExpressionImpl({ $mod: [serializeExpression(l), serializeExpression(r)], }); }, neg(x: ExpressionOrValue): Expression { return new ExpressionImpl({ $neg: serializeExpression(x) }); }, // Logic /////////////////////////////////////////////////////////////////// and(...exprs: Array>): Expression { return new ExpressionImpl({ $and: exprs.map(serializeExpression) }); }, or(...exprs: Array>): Expression { return new ExpressionImpl({ $or: exprs.map(serializeExpression) }); }, not(x: ExpressionOrValue): Expression { return new ExpressionImpl({ $not: serializeExpression(x) }); }, // Other /////////////////////////////////////////////////////////////////// field(fieldPath: string): Expression { return new ExpressionImpl({ $field: fieldPath }); }, };