updated filter parser

This commit is contained in:
2025-01-31 11:12:51 +05:30
parent def1dce168
commit da06598503
2 changed files with 108 additions and 10 deletions

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { parse } from "./utils/queryParser";
export const pageMetadata = z.object({
count: z.number(),
@@ -43,16 +44,7 @@ export function getFilterObject(
const filterObj: Array<{}> = [];
if (params.filter && params.filter != "") {
const filterOptions = params.filter.split(",");
filterOptions.forEach((item) => {
if (item.includes("!=")) {
const [key, val] = item.split("!=").map((token) => token.trim());
if (validFields.includes(key)) filterObj.push({ [key]: { $ne: val } });
} else if (item.includes("=")) {
const [key, val] = item.split("=").map((token) => token.trim());
if (validFields.includes(key)) filterObj.push({ [key]: { $eq: val } });
}
});
filterObj.push(...parse(params.filter, validFields));
}
return filterObj;

106
src/utils/queryParser.ts Normal file
View File

@@ -0,0 +1,106 @@
import mongoose from "mongoose";
type ParsedQuery = Array<
Record<
string,
Record<"$eq" | "$neq" | "$in" | "$nin", string | Date | Object>
>
>;
function convertValue(value: any) {
if (mongoose.Types.ObjectId.isValid(value)) {
return mongoose.Types.ObjectId.createFromHexString(value);
} else if (!isNaN(Date.parse(value))) {
return new Date(value);
} else {
return value;
}
}
export function parse(query: string, validFields: Array<string>): ParsedQuery {
const result = [];
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 = "$neq";
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;
if (validFields.includes(field))
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(token);
if (validFields.includes(field))
result.push({
[field]: { [op === "$eq" ? "$in" : "$nin"]: valueArr },
});
token = "";
field = "";
op = "";
valueArr = [];
currentStage = "field";
i++;
continue;
}
token += char;
}
}
return result;
}