UNPKG

@stimulus-library/controllers

Version:

A library of useful controllers for Stimulus

59 lines (58 loc) 2.63 kB
export function extractExpressions(expressionString) { const andExpression = expressionString.includes("&&"); return expressionString.split(andExpression ? "&&" : "||"); } export function extractPredicates(expressionString) { expressionString = expressionString.trim(); const andExpression = expressionString.includes("&&"); const orExpression = expressionString.includes("||"); const groupings = expressionString.includes("(") || expressionString.includes(")"); if (andExpression && orExpression) { throw new Error("Cannot have both && and || in the same expression."); } if (groupings) { throw new Error("Cannot have logical groupings `(>3 && <= 9) || (>1 && <2)` in the expression. Only supports simple expressions like `>1 && <3`"); } const expressions = extractExpressions(expressionString); if (andExpression) { return expressions.map(ex => _predicateForExpression(ex)); } else if (orExpression) { return expressions.map(ex => _predicateForExpression(ex)); } else { return [_predicateForExpression(expressionString)]; } } function _predicateForExpression(expression) { const operators = [">=", "<=", "==", "!=", ">", "<"]; const operator = operators.find(part => expression.includes(part)); if (!operator) { throw new Error(`Could not find operator in expression: ${expression}`); } let expressionValue = expression.split(operator)[1].trim(); const isNumber = /^-?\d*(\.\d+)?$/.test(expressionValue); if (isNumber) { expressionValue = parseFloat(expressionValue); } if (expressionValue === "") { throw new Error(`Could not find a value in expression: ${expression}`); } const notEmpty = (signalValue) => signalValue !== ""; switch (operator) { case ">": return (signalValue) => isNumber && notEmpty(signalValue) && signalValue > expressionValue; case "<": return (signalValue) => isNumber && notEmpty(signalValue) && signalValue < expressionValue; case ">=": return (signalValue) => isNumber && notEmpty(signalValue) && signalValue >= expressionValue; case "<=": return (signalValue) => isNumber && notEmpty(signalValue) && signalValue <= expressionValue; case "==": return (signalValue) => notEmpty(signalValue) && signalValue == expressionValue; case "!=": return (signalValue) => notEmpty(signalValue) && signalValue != expressionValue; default: throw new Error(`Unknown operator ${operator}`); } }