New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

json-rules-engine

Package Overview
Dependencies
Maintainers
1
Versions
82
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-rules-engine - npm Package Compare versions

Comparing version 1.3.1 to 1.4.0

dist/errors.js

10

CHANGELOG.md

@@ -0,1 +1,11 @@

1.4.0 / 2017-01-23
==================
* Add `allowUndefinedFacts` engine option
1.3.1 / 2017-01-16
==================
* Bump object-hash dependency to latest
1.3.0 / 2016-10-24

@@ -2,0 +12,0 @@ ==================

4

dist/almanac.js

@@ -15,2 +15,4 @@ 'use strict';

var _errors = require('./errors');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -64,3 +66,3 @@

if (fact === undefined) {
throw new Error('Undefined fact: ' + factId);
throw new _errors.UndefinedFactError('Undefined fact: ' + factId);
}

@@ -67,0 +69,0 @@ return fact;

@@ -63,2 +63,3 @@ 'use strict';

var rules = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

@@ -70,2 +71,3 @@ _classCallCheck(this, Engine);

_this.rules = [];
_this.allowUndefinedFacts = options.allowUndefinedFacts || false;
_this.operators = new Map();

@@ -250,3 +252,3 @@ _this.facts = new Map();

function evaluateRules(_x2, _x3) {
function evaluateRules(_x3, _x4) {
return _ref.apply(this, arguments);

@@ -253,0 +255,0 @@ }

@@ -8,4 +8,4 @@ 'use strict';

exports.default = function (rules) {
return new _engine2.default(rules);
exports.default = function (rules, options) {
return new _engine2.default(rules, options);
};

@@ -12,0 +12,0 @@

@@ -199,3 +199,3 @@ 'use strict';

var _ref2 = _asyncToGenerator(regeneratorRuntime.mark(function _callee(condition) {
var comparisonValue, subConditions, passes;
var comparisonValue, passes, subConditions;
return regeneratorRuntime.wrap(function _callee$(_context) {

@@ -206,5 +206,6 @@ while (1) {

comparisonValue = void 0;
passes = void 0;
if (!condition.isBooleanOperator()) {
_context.next = 14;
_context.next = 15;
break;

@@ -216,39 +217,64 @@ }

if (!(condition.operator === 'all')) {
_context.next = 9;
_context.next = 10;
break;
}
_context.next = 6;
_context.next = 7;
return all(subConditions);
case 6:
case 7:
comparisonValue = _context.sent;
_context.next = 12;
_context.next = 13;
break;
case 9:
_context.next = 11;
case 10:
_context.next = 12;
return any(subConditions);
case 11:
case 12:
comparisonValue = _context.sent;
case 12:
_context.next = 17;
case 13:
_context.next = 28;
break;
case 14:
_context.next = 16;
case 15:
_context.prev = 15;
_context.next = 18;
return almanac.factValue(condition.fact, condition.params);
case 16:
case 18:
comparisonValue = _context.sent;
_context.next = 28;
break;
case 17:
_context.next = 19;
case 21:
_context.prev = 21;
_context.t0 = _context['catch'](15);
if (!(_this3.engine.allowUndefinedFacts && _context.t0.code === 'UNDEFINED_FACT')) {
_context.next = 27;
break;
}
passes = false;
_context.next = 28;
break;
case 27:
throw _context.t0;
case 28:
if (!(passes === undefined)) {
_context.next = 32;
break;
}
_context.next = 31;
return condition.evaluate(comparisonValue, _this3.engine.operators);
case 19:
case 31:
passes = _context.sent;
case 32:
if (passes) {

@@ -261,3 +287,3 @@ _this3.emit('success', _this3.event, almanac);

case 22:
case 34:
case 'end':

@@ -267,3 +293,3 @@ return _context.stop();

}
}, _callee, _this3);
}, _callee, _this3, [[15, 21]]);
}));

@@ -270,0 +296,0 @@

@@ -7,3 +7,3 @@ # Engine

### constructor([Array rules])
### constructor([Array rules], Object [options])

@@ -17,4 +17,16 @@ ```js

let engine = new Engine([Array rules])
// initialize with options
let options = {
allowUndefinedFacts: false
};
let engine = new Engine([Array rules], options)
```
#### Options
`allowUndefinedFacts` - By default, when a running engine encounters an undefined fact,
an exception is thrown. Turning this option on will cause the engine to treat
undefined facts as falsey conditions. (default: false)
### engine.addFact(String id, Function [definitionFunc], Object [options])

@@ -21,0 +33,0 @@

@@ -64,4 +64,6 @@ # Walkthrough

Facts are constant values or pure functions. Using the current example, if the engine were to be run, it would throw an error: "Undefined fact: 'age'". So let's define some facts!
Facts are constant values or pure functions. Using the current example, if the engine were to be run, it would throw an exception: `Undefined fact:'age'` (note: this behavior can be disable via [engine options](./engine.md#Options)).
Let's define some facts:
```js

@@ -68,0 +70,0 @@

{
"name": "json-rules-engine",
"version": "1.3.1",
"version": "1.4.0",
"description": "Rules Engine expressed in simple json",

@@ -27,2 +27,4 @@ "main": "dist/index.js",

"globals": [
"context",
"xcontext",
"describe",

@@ -29,0 +31,0 @@ "xdescribe",

@@ -45,17 +45,21 @@ 'use strict'

}
let baseConditions = {
any: [{
fact: 'eligibilityField',
operator: 'lessThan',
params: {
eligibilityId: 1,
field: 'age'
},
value: 50
}]
function baseConditions () {
return {
any: [{
fact: 'eligibilityField',
operator: 'lessThan',
params: {
eligibilityId: 1,
field: 'age'
},
value: 50
}]
}
}
let eventSpy = sinon.spy()
function setup (conditions = baseConditions) {
eventSpy.reset()
engine = engineFactory()
let successSpy = sinon.spy()
let failureSpy = sinon.spy()
function setup (conditions = baseConditions(), engineOptions = {}) {
successSpy.reset()
failureSpy.reset()
engine = engineFactory([], engineOptions)
let rule = factories.rule({ conditions, event })

@@ -65,5 +69,50 @@ engine.addRule(rule)

engine.addFact('eligibilityData', eligibilityData)
engine.on('success', eventSpy)
engine.on('success', successSpy)
engine.on('failure', failureSpy)
}
describe('options', () => {
describe('options.allowUndefinedFacts', () => {
it('throws when fact is undefined by default', async () => {
let conditions = Object.assign({}, baseConditions())
conditions.any.push({
fact: 'undefined-fact',
operator: 'equal',
value: true
})
setup(conditions)
return expect(engine.run()).to.be.rejectedWith(/Undefined fact: undefined-fact/)
})
context('treats undefined facts as falsey when allowUndefinedFacts is set', () => {
it('emits "success" when the condition succeeds', async () => {
let conditions = Object.assign({}, baseConditions())
conditions.any.push({
fact: 'undefined-fact',
operator: 'equal',
value: true
})
setup(conditions, { allowUndefinedFacts: true })
await engine.run()
expect(successSpy).to.have.been.called
expect(failureSpy).to.not.have.been.called
})
it('emits "failure" when the condition fails', async () => {
let conditions = Object.assign({}, baseConditions())
conditions.any.push({
fact: 'undefined-fact',
operator: 'equal',
value: true
})
conditions.any[0].params.eligibilityId = 2
setup(conditions, { allowUndefinedFacts: true })
await engine.run()
expect(successSpy).to.not.have.been.called
expect(failureSpy).to.have.been.called
})
})
})
})
describe('params', () => {

@@ -73,11 +122,11 @@ it('emits when the condition is met', async () => {

await engine.run()
expect(eventSpy).to.have.been.calledWith(event)
expect(successSpy).to.have.been.calledWith(event)
})
it('does not emit when the condition fails', async () => {
let conditions = Object.assign({}, baseConditions)
let conditions = Object.assign({}, baseConditions())
conditions.any[0].params.eligibilityId = 2
setup(conditions)
await engine.run()
expect(eventSpy).to.not.have.been.called
expect(successSpy).to.not.have.been.called
})

@@ -103,3 +152,3 @@ })

await engine.run()
expect(eventSpy).to.have.been.calledWith(event)
expect(successSpy).to.have.been.calledWith(event)
})

@@ -112,3 +161,3 @@

await engine.run()
expect(eventSpy).to.not.have.been.called
expect(successSpy).to.not.have.been.called
})

@@ -123,3 +172,3 @@

await engine.run()
expect(eventSpy).to.have.been.calledWith(event)
expect(successSpy).to.have.been.calledWith(event)
})

@@ -134,3 +183,3 @@

await engine.run()
expect(eventSpy).to.not.have.been.calledWith(event)
expect(successSpy).to.not.have.been.calledWith(event)
})

@@ -145,3 +194,3 @@

await engine.run()
expect(eventSpy).to.have.been.calledWith(event)
expect(successSpy).to.have.been.calledWith(event)
})

@@ -156,3 +205,3 @@

await engine.run()
expect(eventSpy).to.have.been.calledWith(event)
expect(successSpy).to.have.been.calledWith(event)
})

@@ -173,3 +222,3 @@ })

await engine.run()
expect(eventSpy).to.have.been.called
expect(successSpy).to.have.been.called
})

@@ -186,3 +235,3 @@ })

await engine.run()
expect(eventSpy).to.have.been.called
expect(successSpy).to.have.been.called
})

@@ -197,5 +246,5 @@

await engine.run()
expect(eventSpy).to.not.have.been.called
expect(successSpy).to.not.have.been.called
})
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc