All Projects → buttonwoodcx → bcx-expression-evaluator

buttonwoodcx / bcx-expression-evaluator

Licence: MIT License
Safely evaluate JavaScript-like expression in given context.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to bcx-expression-evaluator

Matex
PHP Mathematical expression parser and evaluator
Stars: ✭ 55 (+189.47%)
Mutual labels:  eval
Gomacro
Interactive Go interpreter and debugger with REPL, Eval, generics and Lisp-like macros
Stars: ✭ 1,784 (+9289.47%)
Mutual labels:  eval
expreso
☕ A boolean expression parser and evaluator in Elixir.
Stars: ✭ 54 (+184.21%)
Mutual labels:  eval
Csharp Eval Unity3d
C# Expression Parser for Unity3D
Stars: ✭ 102 (+436.84%)
Mutual labels:  eval
Quickjs Emscripten
Javascript/Typescript bindings for QuickJS, a modern Javascript interpreter written in C by Fabrice Bellard.
Stars: ✭ 124 (+552.63%)
Mutual labels:  eval
Fasteval
Fast and safe evaluation of algebraic expressions
Stars: ✭ 177 (+831.58%)
Mutual labels:  eval
Eval
Package eval implements evaluation of GoLang expression at runtime.
Stars: ✭ 42 (+121.05%)
Mutual labels:  eval
math eval
✖️➕➖➗ `math_eval` safely evaluates mathematical expressions
Stars: ✭ 33 (+73.68%)
Mutual labels:  eval
Compiler Util
An NX utility, responsible for executing code in the context of an object.
Stars: ✭ 130 (+584.21%)
Mutual labels:  eval
Expressionevaluator
A Simple Math and Pseudo C# Expression Evaluator in One C# File. Can also execute small C# like scripts
Stars: ✭ 194 (+921.05%)
Mutual labels:  eval
Wasm Jseval
A safe eval library based on WebAssembly and Duktape/QuickJS.
Stars: ✭ 111 (+484.21%)
Mutual labels:  eval
Asteval
minimalistic evaluator of python expression using ast module
Stars: ✭ 116 (+510.53%)
Mutual labels:  eval
Php Antimalware Scanner
AMWScan (PHP Antimalware Scanner) is a free tool to scan php files and analyze your project to find any malicious code inside it.
Stars: ✭ 181 (+852.63%)
Mutual labels:  eval
Eval Sql.net
SQL Eval Function | Dynamically Evaluate Expression in SQL Server using C# Syntax
Stars: ✭ 84 (+342.11%)
Mutual labels:  eval
decimal-eval
A tiny, safe, fast JavaScript library for decimal arithmetic expressions.
Stars: ✭ 18 (-5.26%)
Mutual labels:  eval
Adder
Executing untrusted code with ease.
Stars: ✭ 45 (+136.84%)
Mutual labels:  eval
Eval
Eval is a lightweight interpreter framework written in Swift, evaluating expressions at runtime
Stars: ✭ 157 (+726.32%)
Mutual labels:  eval
eval-estree-expression
Safely evaluate JavaScript (estree) expressions, sync and async.
Stars: ✭ 22 (+15.79%)
Mutual labels:  eval
ctxexp-parser
In the dynamic execution of JS language environment (wechat applet) to execute JS class calling function.
Stars: ✭ 17 (-10.53%)
Mutual labels:  eval
Injectioniii
Re-write of Injection for Xcode in (mostly) Swift
Stars: ✭ 2,680 (+14005.26%)
Mutual labels:  eval

bcx-expression-evaluator CI

Safely evaluate a JavaScript-like expression in given context.

In Buttonwood, we heavily use meta-data (JSON format) to deliver business logic from backend to front-end. We don't want to design a meta-data format too complex to maintain, this tool allows us to define some light logic in pure string, way more flexible than rigid meta-data, much safer and more maintainable than passing js function as string (we did that) from backend to front-end.

This tool was mainly extracted, modified and extended from the expression parser of aurelia-binding.

Install

npm install bcx-expression-evaluator

Document

function evaluate(expression, context, helper, opts)

  • expression: the expression string to be evaluated
  • context: the input model object
  • helper: optional helper object
  • opts: optional hashmap, currently only support rejectAssignment and stringInterpolationMode
    • rejectAssignment rejects assignment in expression
    • stringInterpolationMode treats the whole expression like if it's in backticks `expression`

function evaluateStringInterpolation is a short-cut to call evaluate with stringInterpolationMode option.

Usage (in es6 syntax)

import {evaluate, evaluateStringInterpolation} from 'bcx-expression-evaluator';

const context = {
    a: 1,
    b: 2,
    c: {
    one: 'one',
    two: 'two'
    },
    avg: function() { return (this.a + this.b) / 2; }
};

evaluate('avg() > a ? c.one : c.two', context);  // => 'one';

use some helper

const helper = {
    limit: 5,
    sum: (v1, v2) => v1 + v2
};

evaluate('sum(a, b) > limit', context, helper);  // => false;

access context object itself with special $this variable

evaluate('$this', context); // => the context object
evaluate('$this.a', context); // => 1

explicitly access helper object with special $parent variable

(carried over from aurelia-binding, might change $parent to $helper in future releases.)

evaluate('a', {a:1}, {a:2}); // => 1
evaluate('$this.a', {a:1}, {a:2}); // => 1
evaluate('$parent.a', {a:1}, {a:2}); // => 2

support es6 string interpolation

evaluate('`${a+1}`', {a:1}); // => '2'

You can evaluate a string interpolation without backtick "`"

evaluate('${a+1}', {a:1}, null, {stringInterpolationMode: true}); // => '2'
evaluateStringInterpolation('${a+1}', {a:1}); // => '2'

You don't have to escape backtick in stringInterpolationMode

evaluate('`\\`${a+1}\\``', {a:1}); // => '`2`', beware you need double escape as we are writing expression in string quotes
evaluate('`${a+1}`', {a:1}, null, {stringInterpolationMode: true}); // => '`2`'
evaluateStringInterpolation('`${a+1}`', {a:1}); // => '`2`'

safe. It is not an eval in JavaScript, doesn't have access to global JavaScript objects

evaluate('parseInt(a, 10)', {a:"7"}) // => undefined

// only have access to context and helper
evaluate('parseInt(a, 10)', {a:"7"}, {parseInt: parseInt}) // => 7

silent most of the time

evaluate('a.b', {}) // => undefined, no error thrown
evaluate('a.b || c', {c: 'lorem'}) // => 'lorem', no error thrown

you can use assignment to mutate context object (or even helper object)

let obj = {a: 1, b: 2};
evaluate('a = 3', obj); // obj is now {a: 3, b: 2}
evaluate('b > 3 ? (a = true) : (a = false)', obj); // obj is now {a: false, b: 2}

disable assignment if you don't need it

This doesn't eliminate side effect, it would not prevent any function you called in bcx-expression to mutate something.

evaluate('a=1', {a:0}, null, {rejectAssignment: true}); // throws error

Difference from real JavaScript expression

bcx-expression looks like JavaScript expression, but there are some difference.

wrong reference results undefined instead of error

let obj = {a: 1};
obj.b.a // => error
evaluate('b.a', obj); // => undefined

default result for +/- operators

Behaviour carried over from aurelia-binding.

// +/- behaviour in normal JavaScript expression
undefined + 1 // => NaN
1 + undefined // => NaN
null + 1 // => 1
1 + null // => 1
undefined + undefined // => NaN
null + null // => 0

// in bcx-expression, + and - ignores undefined/null value,
// if both left and right parts are (evaluated to) undefined/null, result default to 0
evaluate('undefined + 1'); // => 1
evaluate('1 + undefined'); // => 1
evaluate('null + 1'); // => 1
evaluate('1 + null'); // => 1
evaluate('undefined + undefined'); // => 0
evaluate('null + null'); // => 0

no function expression

// all following JavaScript expressions would not work in bcx-expression
(function(){return 1})()
(() => 1)()
arr.sort((a, b) => a > b)

// but this would work
arr.sort(aHelperFunc)

no regular expression support

Regex syntax is too complex to be supported for our AST (abstract syntax tree).

// regex literal would not work in bcx-expression.
/\w/.test(string)

One way to bypass this is to supply regex literal in helper object.

evaluate('tester.test(str)', {str: '%'}, {tester: /\w/});

some JavaScript operators would not work

typeof, instanceof, delete would not work, because bcx-expression is not real JavaScript.

BUTTONWOODCX™ PTY LTD.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].