safe-evaluate-expression
v1.7.3
Published
Small library to dynamically create and evaluate expression with multiple parameters (even undefined)
Downloads
642
Maintainers
Readme
safe-evaluate-expression
Small library to dynamically create and evaluate expression with multiple parameters (even undefined).
- 🔥 To handle more sofisticate use cases is provided a Factory functionality to build evaluate functions with some spice
- 🧬 You can also use pseudo JsonLogic syntax to write expressions.
It also offer an ancillary function to protect lambda function to undefined params inputs.
Installation
npm install safe-evaluate-expression
Evaluate
evaluate(expression:[String | Object], params:[Object]) -> [expression evaluated]
Example
const evaluate = require('safe-evaluate-expression');
// Using Simple Text Expression
evaluate('a > 1', { a: 3 }); // -> true
// Using Pseudo JSONLogic Expression
evaluate(
{
and: [
{
operator: 'isLower',
values: [{ value: 1 }, { value: 'a' }],
},
],
},
{ a: 3 }
); // --> true
Advanced Example
const evaluate = require('safe-evaluate-expression');
const operators = {
isUndefined: (x) => x === undefined,
isEqual: (a, b) => a === b,
isGreater: (a, b) => a > b,
isLower: (a, b) => a < b,
};
const vars = { a: 1, b: 1, c: 2 };
const params = { ...vars, ...operators };
evaluate('isEqual(a,b)', params); // -> true
evaluate('isEqual(a,c)', params); // -> false
evaluate('isEqual(a,notDefined)', params); // -> false
evaluate('isUndefined(a)', params); // -> false
evaluate('isUndefined(notDefined)', params); // -> true
// It works also with infinite nested conditions
evaluate('(isUndefined(notDefined) || (isGreater(c, a) && isLower(b, c))) && isEqual(a,1)', params); // -> true
Factory
factory(options:[Object]) -> [evaluate function]
Example
const { factory, operators } = require('safe-evaluate-expression');
const evaluate = factory({ operators, multipleParams: true, translateLogical: true });
const metadata = { x: 1.1, y: 2 };
const list = { k: 3, z: 4 };
const map = new Map([['pi', 3.14]]);
const expression1 = 'isLower(x,z)';
const expression2 = 'isLower(k,y)';
const expression3 = 'isLower(notDefined,z)'; // put a not defined value
const pseudoJSONLogic = {
and: [
{ operator: '!isEmpty', values: [{ value: '"lorem"' }] },
{
or: [
{
operator: 'isEqual',
values: [{ value: 'x' }, { value: '"x"' }],
},
{
operator: 'isLower',
values: [{ value: '3' }, { value: '4' }],
},
],
},
],
};
evaluate(expression1, metadata, list); // -> true
evaluate(expression2, metadata, list); // -> false
evaluate(`${expression1} AND ${expression2}`, metadata, list); // -> false
evaluate(`${expression1} OR ${expression2}`, metadata, list); // -> true
evaluate(expression3, metadata, list);
evaluate(`${expression3} AND ${expression2}`, metadata, list); // -> false
evaluate(`(isLower(x,z) AND isLower(k,y) OR (isLower(z,P) AND NOT isLower(P,k)))`, metadata, list);
evaluate(`isLower(z,pi)`, metadata, list, map); // -> false
evaluate(pseudoJSONLogic, metadata, list, map); // -> true
Factory Params
The Factory used without parameters gives the same results as the "evaluate" function. However, it is possible to create new "evaluate" functions with much more spice by setting the Factory parameters correctly. All parameters are optional. The parameter "multipleParams" allows you to pass various objects (or Maps) to the evaluation function, thus avoiding the need to deconstruct operators and values in a single object. It is important to remember that the parameter "operators", if specified, must contain an object with all the functions you want to define as operators. This object can be plugged in-scope within the evaluation function to optimise performance. However, if the "operators" functions depend on the external libraries, you should not set the "operatorsInScope" functionality.
Safe Lambda
safeLambda(lamdaFunc, [undefined defalut])
Protect lambda function by assigning a default value for undefined input paramters.
const { safeLambda } = require('safe-evaluate-expression');
const lambda = (a, b, c) => a + b + c;
const protectedLambda = safeLambda(lambda, 0);
// The unprotected lambda returns NaN because all values are undefined
// The protected one return zero (default): 0 + 0 + 0
console.log(lambda(), protectedLambda()); // -> NaN 0