/** * Class used to evaluate queries containing `and` and `or` operators */ export class AndOrNotEvaluator { /** * Evaluate a query * @param query defines the query to evaluate * @param evaluateCallback defines the callback used to filter result * @returns true if the query matches */ static Eval(query, evaluateCallback) { if (!query.match(/\([^()]*\)/g)) { query = AndOrNotEvaluator._HandleParenthesisContent(query, evaluateCallback); } else { query = query.replace(/\([^()]*\)/g, (r) => { // remove parenthesis r = r.slice(1, r.length - 1); return AndOrNotEvaluator._HandleParenthesisContent(r, evaluateCallback); }); } if (query === "true") { return true; } if (query === "false") { return false; } return AndOrNotEvaluator.Eval(query, evaluateCallback); } static _HandleParenthesisContent(parenthesisContent, evaluateCallback) { evaluateCallback = evaluateCallback || ((r) => { return r === "true" ? true : false; }); let result; const or = parenthesisContent.split("||"); for (const i in or) { if (Object.prototype.hasOwnProperty.call(or, i)) { let ori = AndOrNotEvaluator._SimplifyNegation(or[i].trim()); const and = ori.split("&&"); if (and.length > 1) { for (let j = 0; j < and.length; ++j) { const andj = AndOrNotEvaluator._SimplifyNegation(and[j].trim()); if (andj !== "true" && andj !== "false") { if (andj[0] === "!") { result = !evaluateCallback(andj.substring(1)); } else { result = evaluateCallback(andj); } } else { result = andj === "true" ? true : false; } if (!result) { // no need to continue since 'false && ... && ...' will always return false ori = "false"; break; } } } if (result || ori === "true") { // no need to continue since 'true || ... || ...' will always return true result = true; break; } // result equals false (or undefined) if (ori !== "true" && ori !== "false") { if (ori[0] === "!") { result = !evaluateCallback(ori.substring(1)); } else { result = evaluateCallback(ori); } } else { result = ori === "true" ? true : false; } } } // the whole parenthesis scope is replaced by 'true' or 'false' return result ? "true" : "false"; } static _SimplifyNegation(booleanString) { booleanString = booleanString.replace(/^[\s!]+/, (r) => { // remove whitespaces r = r.replace(/[\s]/g, () => ""); return r.length % 2 ? "!" : ""; }); booleanString = booleanString.trim(); if (booleanString === "!true") { booleanString = "false"; } else if (booleanString === "!false") { booleanString = "true"; } return booleanString; } } //# sourceMappingURL=andOrNotEvaluator.js.map