@digifi/jexl
Version:
Javascript Expression Language: Powerful context-based expression parser and evaluator
122 lines (102 loc) • 3.74 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
/*
* Jexl
* Copyright 2020 Tom Shawver
*/
var Evaluator = require('./evaluator/Evaluator');
var Lexer = require('./Lexer');
var Parser = require('./parser/Parser');
var PromiseSync = require('./PromiseSync');
var Expression = /*#__PURE__*/function () {
function Expression(grammar, exprStr, ast) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
(0, _classCallCheck2.default)(this, Expression);
this._grammar = grammar;
this._exprStr = exprStr;
this._ast = ast || null;
this._options = options;
}
/**
* Forces a compilation of the expression string that this Expression object
* was constructed with. This function can be called multiple times; useful
* if the language elements of the associated Jexl instance change.
* @returns {Expression} this Expression instance, for convenience
*/
(0, _createClass2.default)(Expression, [{
key: "compile",
value: function compile() {
if (!this._exprStr) {
throw new Error('Expression is not provided');
}
var lexer = new Lexer(this._grammar);
var parser = new Parser(this._grammar, this._options.minify);
var tokens = lexer.tokenize(this._exprStr);
parser.addTokens(tokens);
this._ast = parser.complete();
return this;
}
/**
* Asynchronously evaluates the expression within an optional context.
* @param {Object} [context] A mapping of variables to values, which will be
* made accessible to the Jexl expression when evaluating it
* @returns {Promise<*>} resolves with the result of the evaluation.
*/
}, {
key: "eval",
value: function _eval() {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return this._eval(context, Promise);
}
/**
* Synchronously evaluates the expression within an optional context.
* @param {Object} [context] A mapping of variables to values, which will be
* made accessible to the Jexl expression when evaluating it
* @returns {*} the result of the evaluation.
* @throws {*} on error
*/
}, {
key: "evalSync",
value: function evalSync() {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var res = this._eval(context, PromiseSync);
if (res.error) throw res.error;
return res.value;
}
/**
* Returns compiled abstract syntax tree
* @returns {*} abstract syntax tree
* @throws {*} on error
*/
}, {
key: "getAst",
value: function getAst() {
if (!this._ast) {
this.compile();
}
return this._ast;
}
}, {
key: "_eval",
value: function _eval(context, promise) {
var _this = this;
return promise.resolve().then(function () {
var ast = _this.getAst();
var evaluator = new Evaluator(_this._grammar, context, undefined, {
strictMode: _this._options.strictMode,
timeout: _this._options.timeout,
strictOptions: _this._options.strictOptions,
emptyContextValue: _this._options.emptyContextValue,
emptySubjectValue: _this._options.emptySubjectValue,
scriptStartTimestamp: Date.now(),
minified: ast.minified
}, promise);
return evaluator.eval(ast);
});
}
}]);
return Expression;
}();
module.exports = Expression;