README
jse-eval
Credits
Heavily based on expression-eval and jsep, with thanks to their awesome work.
Forked from expression-eval v5.0.0. Many thanks to @donmccurdy for the initial package
JavaScript expression parsing and evaluation.
IMPORTANT: As mentioned under Security below, this library does not attempt to provide a secure sandbox for evaluation. Evaluation involving user inputs (expressions or values) may lead to unsafe behavior. If your project requires a secure sandbox, consider alternatives such as vm2.
Usage
Evaluates an estree expression from jsep
(as well as [@babel/parser][], [esprima][], [acorn][], or any other library that parses and returns a valid estree
expression).
Install
Install:
npm install --save jse-eval
Import:
// ES6
import { parse, evaluate, compile, jsep } from 'jse-eval';
// CommonJS
const { parse, evaluate, compile, jsep } = require('jse-eval');
// UMD / standalone script
const { parse, evaluate, compile, jsep } = window.expressionEval;
API
Parsing
import { parse } from 'jse-eval';
const ast = parse('1 + foo');
The result of the parse is an AST (abstract syntax tree), like:
{
"type": "BinaryExpression",
"operator": "+",
"left": {
"type": "Literal",
"value": 1,
"raw": "1"
},
"right": {
"type": "Identifier",
"name": "foo"
}
}
Evaluation
import { parse, evaluate } from 'jse-eval';
const ast = parse('a + b / c'); // abstract syntax tree (AST)
const value = eval(ast, {a: 2, b: 2, c: 5}); // 2.4
// alternatively:
const value = await evalAsync(ast, {a: 2, b: 2, c: 5}); // 2.4
Compilation
import { compile } from 'jse-eval';
const fn = compile('foo.bar + 10');
fn({foo: {bar: 'baz'}}); // 'baz10'
// alternatively:
import { compileAsync } from 'jse-eval';
const fn = compileAsync('foo.bar + 10');
fn({foo: {bar: 'baz'}}); // 'baz10'
JSEP Plugins
const { jsep } = require('jse-eval');
jsep.plugins.register(
require('@jsep-plugin/arrow'),
require('@jsep-plugin/assignment'),
require('@jsep-plugin/async-await'),
require('@jsep-plugin/new'),
require('@jsep-plugin/object'),
require('@jsep-plugin/regex'),
require('@jsep-plugin/spread'),
require('@jsep-plugin/template'),
require('@jsep-plugin/ternary')
);
Extending evaluation
To modify the evaluation, use any of the modification methods:
addUnaryOp(operator, evaluator)
. Will add the operator to jsep, and the function to evaluate the operatoraddBinaryOp(operator, precedence | evaluator, evaluator)
. Will add the operator to jsep at the given precedence (if provided), and the function to evaluate the operatoraddEvaluator(nodeType, evaluator)
. Will add the evaluator function to the map of functions for each node type. This evaluator will be called with the ExpressionEval instance bound to it. The evaluator is responsible for handling both sync and async, as needed, but can use thethis.isAsync
orthis.evalSyncAsync()
to help.- If the node type is unknown, jse-eval will check for a
default
node type handler before throwing an error for an unknown node type. If any other behavior is desired, this can be overridden by providing a newdefault
evaluator.
- If the node type is unknown, jse-eval will check for a
Node Types Supported:
This project will try to stay current with all JSEP's node types::
ArrayExpression
LogicalExpression
/BinaryExpression
CallExpression
ConditionalExpression
Identifier
Literal
MemberExpression
ThisExpression
UnaryExpression
As well as the optional plugin node types:
ArrowFunctionExpression
AssignmentExpression
/UpdateExpression
AwaitExpression
NewExpression
ObjectExpression
SpreadElement
TaggedTemplateExpression
/TemplateLiteral
Related Packages
Depending on your specific use-case, there are other related packages available, including:
Security
Although this package does avoid the use of eval()
, it cannot guarantee that user-provided expressions, or user-provided inputs to evaluation, will not modify the state or behavior of your application. This library does not attempt to provide a secure sandbox for evaluation. Evaluation of arbitrary user inputs (expressions or values) may lead to unsafe behavior. If your project requires a secure sandbox, consider alternatives such as vm2.
Contributing
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on the guidelines for contributing and then feel free to submit a PR with your contribution.
Code of Conduct
Help us keep this project open and inclusive. Please read and follow the Code of Conduct.
License
MIT License.