json-rules-engine
Version:
Rules Engine expressed in simple json
178 lines (148 loc) • 6.71 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _operator = require('./operator');
var _operator2 = _interopRequireDefault(_operator);
var _operatorDecorator = require('./operator-decorator');
var _operatorDecorator2 = _interopRequireDefault(_operatorDecorator);
var _debug = require('./debug');
var _debug2 = _interopRequireDefault(_debug);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var OperatorMap = function () {
function OperatorMap() {
_classCallCheck(this, OperatorMap);
this.operators = new Map();
this.decorators = new Map();
}
/**
* Add a custom operator definition
* @param {string} operatorOrName - operator identifier within the condition; i.e. instead of 'equals', 'greaterThan', etc
* @param {function(factValue, jsonValue)} callback - the method to execute when the operator is encountered.
*/
_createClass(OperatorMap, [{
key: 'addOperator',
value: function addOperator(operatorOrName, cb) {
var operator = void 0;
if (operatorOrName instanceof _operator2.default) {
operator = operatorOrName;
} else {
operator = new _operator2.default(operatorOrName, cb);
}
(0, _debug2.default)('operatorMap::addOperator', { name: operator.name });
this.operators.set(operator.name, operator);
}
/**
* Remove a custom operator definition
* @param {string} operatorOrName - operator identifier within the condition; i.e. instead of 'equals', 'greaterThan', etc
* @param {function(factValue, jsonValue)} callback - the method to execute when the operator is encountered.
*/
}, {
key: 'removeOperator',
value: function removeOperator(operatorOrName) {
var operatorName = void 0;
if (operatorOrName instanceof _operator2.default) {
operatorName = operatorOrName.name;
} else {
operatorName = operatorOrName;
}
// Delete all the operators that end in :operatorName these
// were decorated on-the-fly leveraging this operator
var suffix = ':' + operatorName;
var operatorNames = Array.from(this.operators.keys());
for (var i = 0; i < operatorNames.length; i++) {
if (operatorNames[i].endsWith(suffix)) {
this.operators.delete(operatorNames[i]);
}
}
return this.operators.delete(operatorName);
}
/**
* Add a custom operator decorator
* @param {string} decoratorOrName - decorator identifier within the condition; i.e. instead of 'everyFact', 'someValue', etc
* @param {function(factValue, jsonValue, next)} callback - the method to execute when the decorator is encountered.
*/
}, {
key: 'addOperatorDecorator',
value: function addOperatorDecorator(decoratorOrName, cb) {
var decorator = void 0;
if (decoratorOrName instanceof _operatorDecorator2.default) {
decorator = decoratorOrName;
} else {
decorator = new _operatorDecorator2.default(decoratorOrName, cb);
}
(0, _debug2.default)('operatorMap::addOperatorDecorator', { name: decorator.name });
this.decorators.set(decorator.name, decorator);
}
/**
* Remove a custom operator decorator
* @param {string} decoratorOrName - decorator identifier within the condition; i.e. instead of 'everyFact', 'someValue', etc
*/
}, {
key: 'removeOperatorDecorator',
value: function removeOperatorDecorator(decoratorOrName) {
var decoratorName = void 0;
if (decoratorOrName instanceof _operatorDecorator2.default) {
decoratorName = decoratorOrName.name;
} else {
decoratorName = decoratorOrName;
}
// Delete all the operators that include decoratorName: these
// were decorated on-the-fly leveraging this decorator
var prefix = decoratorName + ':';
var operatorNames = Array.from(this.operators.keys());
for (var i = 0; i < operatorNames.length; i++) {
if (operatorNames[i].includes(prefix)) {
this.operators.delete(operatorNames[i]);
}
}
return this.decorators.delete(decoratorName);
}
/**
* Get the Operator, or null applies decorators as needed
* @param {string} name - the name of the operator including any decorators
* @returns an operator or null
*/
}, {
key: 'get',
value: function get(name) {
var decorators = [];
var opName = name;
// while we don't already have this operator
while (!this.operators.has(opName)) {
// try splitting on the decorator symbol (:)
var firstDecoratorIndex = opName.indexOf(':');
if (firstDecoratorIndex > 0) {
// if there is a decorator, and it's a valid decorator
var decoratorName = opName.slice(0, firstDecoratorIndex);
var decorator = this.decorators.get(decoratorName);
if (!decorator) {
(0, _debug2.default)('operatorMap::get invalid decorator', { name: decoratorName });
return null;
}
// we're going to apply this later, use unshift since we'll apply in reverse order
decorators.unshift(decorator);
// continue looking for a known operator with the rest of the name
opName = opName.slice(firstDecoratorIndex + 1);
} else {
(0, _debug2.default)('operatorMap::get no operator', { name: opName });
return null;
}
}
var op = this.operators.get(opName);
// apply all the decorators
for (var i = 0; i < decorators.length; i++) {
op = decorators[i].decorate(op);
// create an entry for the decorated operation so we don't need
// to do this again
this.operators.set(op.name, op);
}
// return the operation
return op;
}
}]);
return OperatorMap;
}();
exports.default = OperatorMap;
;