UNPKG

vulcain-corejs

Version:
190 lines 6.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class MongoQueryParser { constructor(query) { this.query = query; } execute(entity) { if (!this.query) return true; return this.executeExpression(entity, this.query); } executeExpression(entity, query) { let keys = Object.keys(query); if (keys.length === 0) return true; let op = keys[0]; let val; switch (op) { case "$or": val = query[op]; if (!Array.isArray(val)) throw new Error("Syntax error in logical expression"); for (let o of val) { if (this.executeExpression(entity, o)) return true; } return false; case "$and": val = query[op]; if (!Array.isArray(val)) throw new Error("Syntax error in logical expression"); for (let o of val) { if (!this.executeExpression(entity, o)) return false; } return true; case "$nor": val = query[op]; if (!Array.isArray(val)) throw new Error("Syntax error in logical expression"); for (let o of val) { if (this.executeExpression(entity, o)) return false; } return true; default: if (keys.length > 1) { for (let k of keys) { let obj = {}; obj[k] = query[k]; if (!this.executeOperator(entity, obj)) return false; } } else { if (!this.executeOperator(entity, query)) return false; } } return true; } executeOperator(entity, query) { let keys = Object.keys(query); if (keys.length !== 1) throw new Error("Syntax error"); let k = keys[0]; let left = this.getFieldValue(entity, k); let val = query[k]; if (typeof val !== "object") { return this.evaluate({ "$eq": val }, left); } let v = this.getExpressionValue(val); if (v["$not"]) { v = this.getExpressionValue(v["$not"]); return !this.evaluate(v, left); } return this.evaluate(v, left); } getExpressionValue(val) { if (!val || typeof val !== "object") { return { "$eq": val }; } if (Object.prototype.toString.call(val) === '[object RegExp]') { return { "$regex": val }; } return val; } evaluate(op, left) { let opval; if (opval = op["$eq"]) { if (Array.isArray(left)) return left.indexOf(opval) >= 0; return (left === opval); } else if (opval = op["$comment"]) { return true; } else if (opval = op["$lt"]) { return (left < opval); } else if (opval = op["$gt"]) { return (left > opval); } else if (opval = op["$lte"]) { return (left <= opval); } else if (opval = op["$gte"]) { return (left >= opval); } else if (opval = op["$ne"]) { return (left !== opval); } else if (opval = op["$exists"]) { return (left !== undefined) === opval; } else if (opval = op["$regex"]) { return left && left.match(RegExp(opval, op.$options)) !== null; } else if (opval = op["$in"]) { if (!Array.isArray(opval)) throw new Error("Syntax error for $in"); let arr = Array.isArray(left) ? left : [left]; for (let i of arr) { if (opval.indexOf(i) >= 0) return true; } return false; } else if (opval = op["$nin"]) { if (!Array.isArray(opval)) throw new Error("Syntax error for $nin"); let arr2 = Array.isArray(left) ? left : [left]; for (let i of arr2) { if (opval.indexOf(i) >= 0) return false; } return true; //} else if(opval = op["$startsWith": // return left && ((<string>left).startsWith(right)); } else if (opval = op["$mod"]) { if (!Array.isArray(opval)) throw new Error("Syntax error for $mod"); let divider = parseInt(opval[0]); let remainder = parseInt(opval[1]); return left % divider === remainder; } else if (opval = op["$elemMatch"]) { if (!left) return false; if (!Array.isArray(left)) throw new Error("Syntax error for $elemMatch"); for (let elem of left) { if (this.executeExpression(elem, opval)) return true; } return false; } else if (opval = op["$all"]) { if (!left) return false; if (!Array.isArray(opval) && !Array.isArray(left)) throw new Error("Syntax error for $all"); for (let elem of left) { if (opval.indexOf(elem) <= 0) return false; } return true; } else if (opval = op["$size"]) { if (!left) return false; if (!Array.isArray(left)) throw new Error("Syntax error for $size"); return left.length === opval; } else throw new Error("Operator not implemented"); } getFieldValue(entity, path) { let current = entity; let parts = path.split('.'); for (let part of parts) { current = current && current[part]; } return current; } } exports.MongoQueryParser = MongoQueryParser; //# sourceMappingURL=mongoQueryParser.js.map