Files
permit-api/src/utils/queryParser.ts
2025-02-08 15:48:14 +05:30

110 lines
2.1 KiB
TypeScript

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(parseInt(value)) &&
parseInt(value).toString().length == value.toString().length
) {
return parseInt(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;
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);
result.push({
[field]: { [op === "$eq" ? "$in" : "$nin"]: valueArr },
});
token = "";
field = "";
op = "";
valueArr = [];
currentStage = "field";
i++;
continue;
}
token += char;
}
}
return result;
}