UNPKG

ncrudify

Version:

Configurable CRUD module for NestJS and Mongoose.

181 lines 7.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueryParser = void 0; class QueryParser { static parse(queryParams) { var _a, _b, _c; const filters = {}; const populate = []; const sort = {}; let skip = 0; let limit = 0; const regexPatterns = {}; for (const [key, value] of Object.entries(queryParams)) { if (key.endsWith("_op") && typeof value === "string") { const fieldName = key.replace("_op", ""); if (!regexPatterns[fieldName]) { regexPatterns[fieldName] = { cont: [], isOr: value.toLowerCase() === "or", }; } else { regexPatterns[fieldName].isOr = value.toLowerCase() === "or"; } continue; } if (typeof value === "object" && !Array.isArray(value)) { const fieldName = key; if (!regexPatterns[fieldName]) { regexPatterns[fieldName] = { cont: [], isOr: false }; } for (const [operator, operatorValue] of Object.entries(value)) { if (this.operatorsMap[operator]) { if (["starts", "ends", "cont"].includes(operator) && typeof operatorValue === "string") { if (operator === "starts") { regexPatterns[fieldName].starts = operatorValue; } else if (operator === "ends") { regexPatterns[fieldName].ends = operatorValue; } else if (operator === "cont") { (_a = regexPatterns[fieldName].cont) === null || _a === void 0 ? void 0 : _a.push(operatorValue); } } else if (operator === "isnull") { filters[fieldName] = { $exists: false }; } else if (operator === "notnull") { filters[fieldName] = { $exists: true }; } else if (operator === "between" && typeof operatorValue === "string") { const [start, end] = operatorValue .split(",") .map((v) => this.castValue(v.trim())); filters[fieldName] = { $gte: start, $lte: end }; } else if (operator === "excl" && typeof operatorValue === "string") { filters[fieldName] = { $not: { $regex: operatorValue, $options: "i" }, }; } else if (operator === "in" && typeof operatorValue === "string") { filters[fieldName] = { $in: operatorValue.split(",") }; } else { const value = operatorValue == "null" ? null : this.castValue(operatorValue); const mongoOperator = this.operatorsMap[operator]; if (!filters[fieldName]) filters[fieldName] = {}; filters[fieldName][mongoOperator] = value; } } } } else if (key === "populate" && typeof value === "string") { const paths = value.split(","); paths.forEach((path) => populate.push({ path })); } else if (key === "sort" && typeof value === "string") { const fields = value.split(","); for (const field of fields) { if (field.startsWith("-")) { sort[field.slice(1)] = -1; } else { sort[field] = 1; } } } else if (key === "skip" && typeof value === "string" && !isNaN(Number(value))) { skip = parseInt(value, 10); } else if (key === "limit" && typeof value === "string" && !isNaN(Number(value))) { limit = parseInt(value, 10); } } for (const [fieldName, patterns] of Object.entries(regexPatterns)) { if (patterns.isOr) { const conditions = []; if (patterns.starts) { conditions.push({ [fieldName]: { $regex: `^${patterns.starts}`, $options: "i" }, }); } if (patterns.ends) { conditions.push({ [fieldName]: { $regex: `${patterns.ends}$`, $options: "i" }, }); } (_b = patterns.cont) === null || _b === void 0 ? void 0 : _b.forEach((contPattern) => { conditions.push({ [fieldName]: { $regex: contPattern, $options: "i" }, }); }); if (conditions.length > 0) { filters.$or = conditions; } } else { let pattern = ""; if (patterns.starts) { pattern += `^${patterns.starts}`; } if ((_c = patterns.cont) === null || _c === void 0 ? void 0 : _c.length) { patterns.cont.forEach((contPattern) => { pattern += pattern ? `.*${contPattern}` : contPattern; }); } if (patterns.ends) { pattern += pattern ? `.*${patterns.ends}$` : `${patterns.ends}$`; } if (pattern) { filters[fieldName] = { $regex: pattern, $options: "i" }; } } } return { filters, populate, sort, skip, limit }; } static castValue(value) { if (typeof value === "string") { const isoDateRegex = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d{3})?([+-]\d{2}:\d{2}|Z)?)?$/; if (value.match(isoDateRegex)) { return new Date(value); } if (!isNaN(Number(value))) return Number(value); if (value === "true") return true; if (value === "false") return false; return value; } return value; } } exports.QueryParser = QueryParser; QueryParser.operatorsMap = { eq: "$eq", ne: "$ne", gt: "$gt", gte: "$gte", lt: "$lt", lte: "$lte", starts: "$regex", ends: "$regex", cont: "$regex", excl: "$not", in: "$in", notin: "$nin", isnull: "$exists", notnull: "$exists", between: "$gte", }; //# sourceMappingURL=query-parser.namespace.js.map