@arunkumar_h/rule-engine
Version:
A lightweight and extensible rule engine built with TypeScript and Node.js. Define complex business rules and evaluate conditions easily using a simple JSON structure.
259 lines (206 loc) โข 8.97 kB
Markdown
[](https://snyk.io/test/github/Arunkumarcs/rule-engine)
[](https://www.npmjs.com/package/@arunkumar_h/rule-engine)
[](https://www.npmjs.com/package/@arunkumar_h/rule-engine)
[](https://github.com/arunkumar-h/rule-engine/blob/main/LICENSE)
[](https://bundlephobia.com/package/@arunkumar_h/rule-engine)
[](https://packagephobia.com/result?p=@arunkumar_h/rule-engine)
[](badges/badge-branches.svg)
[](badges/badge-functions.svg)
[](badges/badge-lines.svg)
[](badges/badge-statements.svg)
***
**Breaking Change:** Please move to v3.1.0 or later.
<!-- [More info here.](
***
A lightweight and extensible rule engine built with TypeScript and Node.js. Define complex business rules and evaluate conditions easily using a simple JSON structure.
```bash
npm install @arunkumar_h/rule-engine
```
```bash
yarn add @arunkumar_h/rule-engine
```
- โ
Logical condition support (and, or, nested expressions)
- ๐ง Custom operators and named conditions
- ๐ Fully typed with TypeScript
- ๐ Lightweight and dependency-aware
- ๐ Native [JMESPath](https://jmespath.org/) support for data querying
- ๐งฐ Built-in caching using [`lru-cache`](https://isaacs.github.io/node-lru-cache/) for better performance
| Feature / Capability | @arunkumar_h/rule-engine |
| --- | --- |
| โ
Written in TypeScript | โ
Native TypeScript with full type safety |
| โ๏ธ Custom Operators | โ
Built-in support, sync or async |
| ๐ง Named Conditions | โ
Supports reusable named conditions |
| ๐งฑ Nested Logical Trees | โ
Fully supported (and, or, deeply nested) |
| ๐ Data Query Language | โ
Built-in JMESPath support |
| ๐ Performance Optimizations | โ
Rule-level cache with lru-cache |
| ๐งฐ Extensibility | โ
Add custom operators, conditions dynamically |
| โ๏ธ Lightweight | โ
Small and focused build |
| ๐งช Testing Coverage Ready | โ
Easy to unit test each rule block |
| ๐ Dynamic Rule Loading | โ
Add/modify rules at runtime |
| ๐ Async Support | โ
Full async engine and operators |
| ๐ฆ Modern Packaging | โ
ESM + CJS + .d.ts types out of the box |
## โ๏ธ Default Operators
The following operators are available by default:
| Operator | Description |
| ------ | ------ |
| === | Strict equality |
| !== | Strict inequality |
| == | Loose equality |
| != | Loose inequality |
| > | Greater than |
| >= | Greater than or equal to |
| < | Less than |
| <= | Less than or equal to |
| %like | Starts with |
| like% | Ends with |
| %like% | Contains |
| in | Value is in the array |
| !in | Value is not in the array |
| includes | Array includes value |
| !includes | Array does not include value |
- `condition` This containes `and` and `or` as main block.
- `onSuccess` value that will be returned or function that will be invoked if the condition is satisfied.
- `onFail` value that will be returned or function that will be invoked if the condition fails.
- `cache` as default this will be set to `true` and can be disabled for rule wise `false`
```javascript
import { Engine } from "@arunkumar_h/rule-engine";
const engineObj = new Engine();
const rule = {
testRule: {
condition: {
and: [
{ path: "age", operator: "!==", value: 10 },
{
and: [
{ path: "age", operator: ">", value: 15 },
{
or: [
{ path: "age", operator: "!==", value: 30 },
{ path: "skills", operator: "includes", value: "ts" },
],
},
],
},
{ path: "language", operator: "in", value: ["tamil", "english"] },
],
},
onSuccess: (fact, ruleName) => "Success", // onSuccess: { id: 23 }
onFail: (fact, ruleName) => "Fail", // onFail: "Error"
cache: false, // default will be true
}
};
engine.addRule(rule);
const fact = {age: 16, skills: ["ts", "php"], language: "tamil"}; // Your data to be validated
const result = await engineObj.run(fact, "testRule");
```
```javascript
engine.addOperator({
isEven: (factValue) => factValue % 2 === 0,
});
const rule = {
evenCheck: {
condition: {
and: [
{ path: "number", operator: "isEven" },
],
},
onSuccess: "Number is even",
onFail: "Number is odd",
},
};
const result = await engine.run({ number: 8 }, "evenCheck");
```
```mermaid
flowchart TB
Rule --> onSuccess
Rule --> onFail
Rule --> Condition --> AND --> Operation
Condition --> OR --> Operation
```
```javascript
let engine = new Engine()
```
addRule({ rule1, rule2, ... })
- Add named rules dynamically.
addCondition({ condition1, condition2, ... })
- Add reusable named conditions.
- Conditions can reference other named conditions.
addOperator({ customOperator1, customOperator2, ... })
- Add custom (sync or async) operators.
run(fact, ruleName)
- Executes a given rule against the provided fact
## โก Advanced Usage
- Adding named conditions.
- Adding named operators.
- Rule wise cache disabling.
```javascript
import { Engine } from "@arunkumar_h/rule-engine";
const engineObj = new Engine();
const condition1 = {
condition1: {
and: [
{ path: "age", operator: "!==", value: 10 },
{
and: [
{ path: "age", operator: ">", value: 15 },
{
or: [
{ path: "age", operator: "!==", value: 30 },
{ path: "skills", operator: "includes", value: "ts" },
],
},
],
},
{ path: "language", operator: "in", value: ["tamil", "english"] },
],
}
};
engine.addCondition(condition1); // adding named condition
const rule = {
testRule: {
condition: "condition1", // Using named condition
onSuccess: "Success", // can be a function or a data
onFail: "Fail", // can be a function or a data
cache: false // disable cache for this rule
}
};
engine.addRule(rule);
const fact = {age: 16, skills: ["ts", "php"], language: "tamil"}; // Your data to be validated
const result = await engineObj.run(fact, "testRule");
```
Badges above represent live coverage stats for:
- [](badges/badge-branches.svg)
- [](badges/badge-functions.svg)
- [](badges/badge-lines.svg)
- [](badges/badge-statements.svg)
<!--
Due to a breaking change in
the [rule-engine](https://github.com/Arunkumarcs/rule-engine/releases/tag/v3.0.1)
old versions might break when newly installed from `npm`.
- ๐ Native [JMESPath](https://jmespath.org/) support for data querying
- ๐งฐ Built-in caching using [`lru-cache`](https://isaacs.github.io/node-lru-cache/) for better performance
**Therefore, please move to vv3.0.3 or later.**
-->
**Arunkumar H**
[](https://www.linkedin.com/in/arunkumar-h-0716b6104)
[](https://github.com/Arunkumarcs)
[](mailto:arunkumar.h.in.1991@gmail.com)
- **Code**: Licensed under the [MIT License](./LICENSE)
- **Assets & Documentation**: Licensed under the [CC BY-SA 4.0 License](./LICENSE.assets)
Some non-code content (e.g. diagrams, images, markdown docs) is licensed under the
Creative Commons Attribution-ShareAlike 4.0 International License.
See [https://creativecommons.org/licenses/by-sa/4.0/](https://creativecommons.org/licenses/by-sa/4.0/) for more info.
The detailed list of Open Source dependencies can be found in Fossa report.
<!-- [](https://app.fossa.com/projects/git%2Bgithub.com%2FArunkumarcs%2Frule-engine?ref=badge_large&issueType=license) -->
<!-- ## ๐งพ SBOM
A [Software Bill of Materials](./sbom.json) is included to list all open source dependencies and licenses used in this package. -->