import mongoose from "mongoose"; type MongoFilter = Record; function convertValue(value: string) { if (/^\d{4}-\d{2}-\d{2}$/.test(value)) { return new Date(value); } else if (!isNaN(Number(value))) { return Number(value); } else if (mongoose.Types.ObjectId.isValid(value)) { return new mongoose.Types.ObjectId(value); } else if (value === "true") { return true; } else if (value === "false") { return false; } else if (value === "null") { return null; } return value; } function formulaToMongoFilter(formula: string): MongoFilter { // Check for array syntax first (values in parentheses) const arrayMatch = formula.match(/([^!<>=]+)([!<>=]*)=\(([^)]+)\)/); if (arrayMatch) { const [, field, operator, values] = arrayMatch; const trimmedField = field.trim(); if (trimmedField === "tenantId") return {}; // Split values by comma and trim each value const valueArray = values .split(",") .map((v) => v.trim().replace(/^['"]|['"]$/g, "")); // Convert each value to appropriate type const parsedValues = valueArray.map((value) => convertValue(value)); // If no operator or equals operator, use $in if (!operator || operator === "=") { return { [trimmedField]: { $in: parsedValues } }; } // If not equals operator, use $nin else if (operator === "!") { return { [trimmedField]: { $nin: parsedValues } }; } // Other operators don't make sense with arrays throw new Error(`Unsupported operator with array values: ${operator}`); } // Original single value processing const operatorMatch = formula.match(/([^!<>=]+)([!<>=]+)(.+)/); if (!operatorMatch) { throw new Error(`Invalid formula format: ${formula}`); } const [, field, operator, value] = operatorMatch; const trimmedField = field.trim(); const trimmedValue = value.trim().replace(/^['"]|['"]$/g, ""); if (trimmedField === "tenantId") return {}; // Convert value to appropriate type (date or number if possible) let parsedValue: any = convertValue(trimmedValue); // Convert operator to MongoDB operator switch (operator) { case "=": return { [trimmedField]: { $eq: parsedValue } }; case "!=": return { [trimmedField]: { $ne: parsedValue } }; case ">": return { [trimmedField]: { $gt: parsedValue } }; case "<": return { [trimmedField]: { $lt: parsedValue } }; case ">=": return { [trimmedField]: { $gte: parsedValue } }; case "<=": return { [trimmedField]: { $lte: parsedValue } }; default: throw new Error(`Unsupported operator: ${operator}`); } } export function parse(formulas: string[]): Array { const parsedQuery: Array = formulas.map((formula) => formulaToMongoFilter(formula) ); return parsedQuery; }