updated filtering code
This commit is contained in:
@@ -1,111 +1,67 @@
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
type ParsedQuery = Array<
|
||||
Record<string, Record<'$eq' | '$ne' | '$in' | '$nin', string | Date | Object>>
|
||||
>;
|
||||
type MongoFilter = Record<string, any>;
|
||||
|
||||
function convertValue(value: any) {
|
||||
if (mongoose.Types.ObjectId.isValid(value)) {
|
||||
return mongoose.Types.ObjectId.createFromHexString(value);
|
||||
function formulaToMongoFilter(formula: string): MongoFilter {
|
||||
// Split the formula into parts
|
||||
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();
|
||||
|
||||
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 (
|
||||
!isNaN(parseInt(value)) &&
|
||||
parseInt(value).toString().length == value.toString().length
|
||||
typeof parsedValue === 'string' &&
|
||||
mongoose.Types.ObjectId.isValid(parsedValue)
|
||||
) {
|
||||
return parseInt(value);
|
||||
} else if (!isNaN(Date.parse(value))) {
|
||||
return new Date(value);
|
||||
} else if (value === 'true') {
|
||||
return true;
|
||||
} else if (value === 'false') {
|
||||
return false;
|
||||
} else {
|
||||
return value;
|
||||
parsedValue = new mongoose.Types.ObjectId(parsedValue);
|
||||
} else if (parsedValue === 'true') {
|
||||
parsedValue = true;
|
||||
} else if (parsedValue === 'false') {
|
||||
parsedValue = false;
|
||||
} else if (parsedValue === 'null') {
|
||||
parsedValue = null;
|
||||
}
|
||||
|
||||
// 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(query: string, validFields: Array<string>): ParsedQuery {
|
||||
const result = [];
|
||||
export function parse(formulas: string[]): MongoFilter {
|
||||
const parsedQuery: MongoFilter = formulas.reduce((filter, formula) => {
|
||||
const newFilter = formulaToMongoFilter(formula);
|
||||
return { ...filter, ...newFilter };
|
||||
}, {});
|
||||
|
||||
let currentStage = 'field';
|
||||
let token = '';
|
||||
let field = '';
|
||||
let op = '';
|
||||
let value = '';
|
||||
let valueArr = [];
|
||||
for (let i = 0; i < query.length; i++) {
|
||||
let char = query[i];
|
||||
|
||||
if (currentStage === 'field') {
|
||||
if (char === '=' || char === '!') {
|
||||
field = token;
|
||||
token = '';
|
||||
currentStage = 'value';
|
||||
|
||||
if (char === '=') {
|
||||
op = '$eq';
|
||||
} else {
|
||||
op = '$ne';
|
||||
i++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
token += char;
|
||||
}
|
||||
|
||||
if (currentStage === 'value') {
|
||||
if (char === '[') {
|
||||
currentStage = 'valueArr';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char === ',' || i == query.length - 1) {
|
||||
if (i == query.length - 1) token += char;
|
||||
|
||||
value = token;
|
||||
result.push({ [field]: { [op]: convertValue(value) } });
|
||||
|
||||
token = '';
|
||||
field = '';
|
||||
op = '';
|
||||
|
||||
currentStage = 'field';
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
token += char;
|
||||
}
|
||||
|
||||
if (currentStage === 'valueArr') {
|
||||
if (char === ',') {
|
||||
valueArr.push(convertValue(token));
|
||||
token = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char === ']') {
|
||||
valueArr.push(convertValue(token));
|
||||
result.push({
|
||||
[field]: { [op === '$eq' ? '$in' : '$nin']: valueArr },
|
||||
});
|
||||
|
||||
token = '';
|
||||
field = '';
|
||||
op = '';
|
||||
valueArr = [];
|
||||
|
||||
currentStage = 'field';
|
||||
i++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
token += char;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
return result;
|
||||
return parsedQuery;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user