added array filter option
This commit is contained in:
@@ -1,9 +1,55 @@
|
||||
import mongoose from 'mongoose';
|
||||
import mongoose from "mongoose";
|
||||
|
||||
type MongoFilter = Record<string, any>;
|
||||
|
||||
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 {
|
||||
// Split the formula into parts
|
||||
// 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) {
|
||||
@@ -12,56 +58,35 @@ function formulaToMongoFilter(formula: string): MongoFilter {
|
||||
|
||||
const [, field, operator, value] = operatorMatch;
|
||||
const trimmedField = field.trim();
|
||||
const trimmedValue = value.trim();
|
||||
const trimmedValue = value.trim().replace(/^['"]|['"]$/g, "");
|
||||
|
||||
if (trimmedField === 'tenantId') return {};
|
||||
if (trimmedField === "tenantId") return {};
|
||||
|
||||
// Convert value to appropriate type (date or number if possible)
|
||||
let parsedValue: any = trimmedValue;
|
||||
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(trimmedValue)) {
|
||||
// Check if it's a date (ISO format)
|
||||
parsedValue = new Date(trimmedValue);
|
||||
} else if (!isNaN(Number(trimmedValue))) {
|
||||
// Check if it's a number
|
||||
parsedValue = Number(trimmedValue);
|
||||
} else if (
|
||||
typeof parsedValue === 'string' &&
|
||||
mongoose.Types.ObjectId.isValid(parsedValue)
|
||||
) {
|
||||
parsedValue = new mongoose.Types.ObjectId(parsedValue);
|
||||
} else if (parsedValue === 'true') {
|
||||
parsedValue = true;
|
||||
} else if (parsedValue === 'false') {
|
||||
parsedValue = false;
|
||||
} else if (parsedValue === 'null') {
|
||||
parsedValue = null;
|
||||
}
|
||||
let parsedValue: any = convertValue(trimmedValue);
|
||||
|
||||
// Convert operator to MongoDB operator
|
||||
switch (operator) {
|
||||
case '=':
|
||||
case "=":
|
||||
return { [trimmedField]: { $eq: parsedValue } };
|
||||
case '!=':
|
||||
case "!=":
|
||||
return { [trimmedField]: { $ne: parsedValue } };
|
||||
case '>':
|
||||
case ">":
|
||||
return { [trimmedField]: { $gt: parsedValue } };
|
||||
case '<':
|
||||
case "<":
|
||||
return { [trimmedField]: { $lt: parsedValue } };
|
||||
case '>=':
|
||||
case ">=":
|
||||
return { [trimmedField]: { $gte: parsedValue } };
|
||||
case '<=':
|
||||
case "<=":
|
||||
return { [trimmedField]: { $lte: parsedValue } };
|
||||
default:
|
||||
throw new Error(`Unsupported operator: ${operator}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function parse(formulas: string[]): MongoFilter {
|
||||
const parsedQuery: MongoFilter = formulas.reduce((filter, formula) => {
|
||||
const newFilter = formulaToMongoFilter(formula);
|
||||
return { ...filter, ...newFilter };
|
||||
}, {});
|
||||
|
||||
export function parse(formulas: string[]): Array<MongoFilter> {
|
||||
const parsedQuery: Array<MongoFilter> = formulas.map((formula) =>
|
||||
formulaToMongoFilter(formula)
|
||||
);
|
||||
return parsedQuery;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user