summaryrefslogtreecommitdiffstats
path: root/server/monitor-conditions/evaluator.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel@debian.org>2024-11-26 09:28:28 +0100
committerDaniel Baumann <daniel@debian.org>2024-11-26 12:25:58 +0100
commita1882b67c41fe9901a0cd8059b5cc78a5beadec0 (patch)
tree2a24507c67aa99a15416707b2f7e645142230ed8 /server/monitor-conditions/evaluator.js
parentInitial commit. (diff)
downloaduptime-kuma-a1882b67c41fe9901a0cd8059b5cc78a5beadec0.tar.xz
uptime-kuma-a1882b67c41fe9901a0cd8059b5cc78a5beadec0.zip
Adding upstream version 2.0.0~beta.0+dfsg.upstream/2.0.0_beta.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'server/monitor-conditions/evaluator.js')
-rw-r--r--server/monitor-conditions/evaluator.js71
1 files changed, 71 insertions, 0 deletions
diff --git a/server/monitor-conditions/evaluator.js b/server/monitor-conditions/evaluator.js
new file mode 100644
index 0000000..3860a33
--- /dev/null
+++ b/server/monitor-conditions/evaluator.js
@@ -0,0 +1,71 @@
+const { ConditionExpressionGroup, ConditionExpression, LOGICAL } = require("./expression");
+const { operatorMap } = require("./operators");
+
+/**
+ * @param {ConditionExpression} expression Expression to evaluate
+ * @param {object} context Context to evaluate against; These are values for variables in the expression
+ * @returns {boolean} Whether the expression evaluates true or false
+ * @throws {Error}
+ */
+function evaluateExpression(expression, context) {
+ /**
+ * @type {import("./operators").ConditionOperator|null}
+ */
+ const operator = operatorMap.get(expression.operator) || null;
+ if (operator === null) {
+ throw new Error("Unexpected expression operator ID '" + expression.operator + "'. Expected one of [" + operatorMap.keys().join(",") + "]");
+ }
+
+ if (!Object.prototype.hasOwnProperty.call(context, expression.variable)) {
+ throw new Error("Variable missing in context: " + expression.variable);
+ }
+
+ return operator.test(context[expression.variable], expression.value);
+}
+
+/**
+ * @param {ConditionExpressionGroup} group Group of expressions to evaluate
+ * @param {object} context Context to evaluate against; These are values for variables in the expression
+ * @returns {boolean} Whether the group evaluates true or false
+ * @throws {Error}
+ */
+function evaluateExpressionGroup(group, context) {
+ if (!group.children.length) {
+ throw new Error("ConditionExpressionGroup must contain at least one child.");
+ }
+
+ let result = null;
+
+ for (const child of group.children) {
+ let childResult;
+
+ if (child instanceof ConditionExpression) {
+ childResult = evaluateExpression(child, context);
+ } else if (child instanceof ConditionExpressionGroup) {
+ childResult = evaluateExpressionGroup(child, context);
+ } else {
+ throw new Error("Invalid child type in ConditionExpressionGroup. Expected ConditionExpression or ConditionExpressionGroup");
+ }
+
+ if (result === null) {
+ result = childResult; // Initialize result with the first child's result
+ } else if (child.andOr === LOGICAL.OR) {
+ result = result || childResult;
+ } else if (child.andOr === LOGICAL.AND) {
+ result = result && childResult;
+ } else {
+ throw new Error("Invalid logical operator in child of ConditionExpressionGroup. Expected 'and' or 'or'. Got '" + group.andOr + "'");
+ }
+ }
+
+ if (result === null) {
+ throw new Error("ConditionExpressionGroup did not result in a boolean.");
+ }
+
+ return result;
+}
+
+module.exports = {
+ evaluateExpression,
+ evaluateExpressionGroup,
+};