import type { CompoundCondition, FieldCondition, Comparable, } from "@ucast/core"; import { type translateOpts, type PrismaOperator, Query, } from "./interpreter.js"; export const eq = op("equals"); export const ne = op("not"); export const startswith = op("startsWith"); export const endswith = op("endsWith"); export const contains = op("contains"); export const lt = op("lt"); export const lte = op("lte"); export const gt = op("gt"); export const gte = op("gte"); const in_ = op("in"); export { in_ as in }; export const notIn = op("notIn"); export const and: PrismaOperator = ( condition, query, { interpret } ) => { const and: Record[] = []; for (const cond of condition.value) { const q = query.child(); interpret(cond, q); and.push(q.toJSON()); } if (and.length > 1) { query.addPrimaryCondition({ AND: and }); } else { query.addPrimaryCondition(and[0]); } return query; }; export const or: PrismaOperator = ( condition, query, { interpret } ) => { const or: Record[] = []; for (const cond of condition.value) { const q = query.child(); interpret(cond, q); or.push(q.toJSON()); } if (or.length > 1) { query.addPrimaryCondition({ OR: or }); } else { query.addPrimaryCondition(or[0]); } return query; }; export const not: PrismaOperator = ( condition, query, { interpret } ) => { if (condition.value.length > 1) { throw new Error("NOT condition must have exactly one child"); } const [tbl] = (condition.value[0] as FieldCondition).field.split("."); const not = new Query(tbl); interpret(condition.value[0], not); query.addCondition(tbl, { NOT: not.toJSON() }); return query; }; function op(name: string): PrismaOperator> { return (condition, query, options) => { const translate = (options as translateOpts)?.translate || // NOTE(sr): The 'as' here feels wrong, but I couldn't make it work otherwise. ((...x: string[]) => [x[0], x[1]]); const [tbl, field] = translate(...condition.field.split(".")); return query.addCondition(tbl, { [field]: { [name]: condition.value }, }); }; }