kenolo
v2.2.2
Published
A lightweight JSON-based business rules engine
Downloads
21
Readme
KENOLO
A lightweight JSON-based business rules engine
Consider Using KENOLO, If:
- You want non-programmers to be able to understand and modify the rules themselves
KENOLO ruleset is simple yet powerful thanks to the operators which are supported - You need to apply different rules and conditions per environment
Use npm configuration packages, such as config or nconf, to store your ruleset per environment. - Rules are frequently changed, but you strive to keep source code modifications and consequently tedious QA cycles to the minimum
Simply modify an external JSON file to update your ruleset. - Security, size & performance concern you
KENOLO is a 22KBeval
-free npm package.
Installation
npm i kenolo -S
Ruleset Structure
{
"NAME_OF_RULE_1": {
// mandatory - object of one or more conditions to check whether rule should apply:
"include":
// condition 1:
{ "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "eq", "value": "VALUE_TO_COMPARE_WITH" },
// optional - object of one or more conditions to check whether rule should NOT apply:
"exclude": {
// array of conditions which should all be truthy for rule to apply:
"and": [
// condition 1:
{ "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "gt", "value": "VALUE_TO_COMPARE_WITH" },
// condition 2:
{ "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "neq", "value": "VALUE_TO_COMPARE_WITH" },
// more conditions:
//...
],
// array of conditions from which at least one of them should be truthy for rule to apply:
"or": [
// condition 1:
{ "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "eq", "value": "VALUE_TO_COMPARE_WITH" },
// condition 2:
{ "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "eq", "value": "VALUE_TO_COMPARE_WITH" },
// more conditions:
//...
]
}
},
"NAME_OF_RULE_2": {
"include": [
// ...
]
}
}
Basic Example
const kenolo = require('kenolo');
const data = {
order: {
status: 2,
user: {
email: '[email protected]'
}
}
};
const SHOULD_REVIEW = {
include: {
and: [
{ name: 'STATUS_PENDING', property: 'order.status', operator: 'eq', value: 2 },
{
or: [
{ name: 'HIGH_RISK_USER_EMAILS', property: 'order.user.email', operator: 'in', value: ['[email protected]', '[email protected]'] },
{ name: 'MAX_PRICE_EXCEEDED', property: 'order.price', operator: 'gt', value: 500 }
]
}
]
}
};
kenolo(SHOULD_REVIEW, data);
// -> { apply: true, conditions: [ 'STATUS_PENDING', 'HIGH_RISK_USER_EMAILS' ] }
See tests directory for more examples
Response Object
{
// {Boolean} apply - Should rule apply?
apply: true,
// {String[]} conditions - Truthy condition names
conditions: ['CONDITION_NAME_1', 'CONDITION_NAME_2']
}
Supported Operators
ex
- Property exists{ "property": "a", "operator": "ex" }
nex
- Property doesn't exists{ "property": "a", "operator": "nex" }
eq
- Equals to (a single value){ "property": "a", "operator": "eq", "value": "a" }
neq
- Not equals to (a single value){ "property": "a", "operator": "neq", "value": "b" }
weq
- Weak equals to (a single value){ "property": "2", "operator": "weq", "value": 2 }
nweq
- Not weak equals to (a single value){ "property": "a", "operator": "nweq", "value": "b" }
in
- In (an array of values){ "property": "a", "operator": "in", "value": ["a", "b", "c"] }
nin
- Not in (an array of values){ "property": "d", "operator": "nin", "value": ["a", "b", "c"] }
gt
- Greater than (a single value){ "property": 100, "operator": "gt", "value": 80 }
gte
- Greater than or equals to (a single value){ "property": 100, "operator": "gte", "value": 100 }
lt
- Lower than (a single value){ "property": 100, "operator": "lt", "value": 120 }
lte
- Lower than or equals to (a single value){ "property": 100, "operator": "lte", "value": 100 }
sw
- Starts with (an array of values){ "property": "+1 40 9871625", "operator": "sw", "value": ["+1", "+40"] }
nsw
- Not starts with (an array of values){ "property": "+1 40 9871625", "operator": "nsw", "value": ["+1", "+40"] }
ew
- Ends with (an array of values){ "property": "[email protected]", "operator": "ew", "value": ["@hacker.com", "@hazard.com"] }
new
- Not ends with (an array of values){ "property": "[email protected]", "operator": "new", "value": ["@hacker.com", "@hazard.com"] }
inc
- Includes (an array of values){ "property": "John", "operator": "inc", "value": ["oh", "bla"] }
ninc
- Not includes (an array of values){ "property": "John", "operator": "ninc", "value": ["oh", "bla"] }
sl
- Sounds like (an array of values){ "property": "John", "operator": "sl", "value": ["Jon", "David"] }
re
- Regular expression (an array of values){ "property": "New York", "operator": "re", "value": [/New/i] }
{ "property": "New York", "operator": "re", "value": ["\\w+"] }
Array properties
some
- Some are included (an array of values){ "property": [1, 2, 3], "operator": "some", "value": [1, 5, 8] }
every
- All are included (an array of values){ "property": [1, 2, 3], "operator": "every", "value": [1, 2, 3, 4, 5] }
none
- None are included (an array of values){ "property": [1, 2, 3], "operator": "none", "value": [4, 5, 7, 8] }