the-rule-engine
Version:
⚙️ A small fluent DSL for conditional logic (validation, gating, etc)
178 lines (122 loc) • 4.81 kB
Markdown
# ⚙️ the-rule-engine
[](https://www.npmjs.com/package/the-rule-engine) [](https://npmjs.org/package/the-rule-engine)
> "Declarative. Readable. Chainable. Unreasonably good looking."
`the-rule-engine` is a lightweight, fluent API for building business logic, conditional flows, validations, or feature gating — without writing spaghetti `if (a && (b || !c))` messes.
It's your very own rule DSL – ideal for settings where rules might get complicated, but your brain shouldn't have to.
## 🧩 Use Cases
- ✅ Feature gating (A/B testing, roles, regions)
- ✅ Form validation logic
- ✅ Dynamic pricing tiers
- ✅ Content access control
- ✅ Rule-based UI rendering
- ✅ Complex conditional branching
## 🦾 Why use **the-rule-engine**?
- 🧠 **Fluent DSL**: Read like English. Write like code.
- 🧼 **Zero boilerplate**: No ASTs, no config, no YAML dragons.
- 🧪 **Fully testable**: Tiny API surface, easy mocks, clean logic.
- 🧩 **Composable**: Use sub-engines or group logic like a pro.
- 🔁 **Negations & nesting**: Yes, we support `.notGroup(...)`.
## 🚀 Installation
```bash
npm install the-rule-engine
````
## 🧑💻 Usage
```js
import { createRuleEngine } from 'the-rule-engine';
const engine = createRuleEngine()
.when(user => user.age >= 18)
.and(user => user.country === 'US')
.notGroup(group =>
group.when(user => user.banned).or(user => user.status === 'inactive')
)
.then(() => '✅ Access Granted')
.otherwise(() => '❌ Access Denied');
console.log(engine.evaluate({
age: 22,
country: 'US',
banned: false,
status: 'active'
})); // ✅ Access Granted
```
## 🧠 API Overview
| Method | Description |
| ------------------------ | -------------------------------------------- |
| `when(fn)` | Entry condition (`if`). Starts rule chain. |
| `and(fn)` | Adds `AND` condition to current logic chain. |
| `or(fn)` | Adds `OR` condition. |
| `not(fn)` | Negates a condition. |
| `group(cb)` | Nest AND conditions inside a callback. |
| `orGroup(cb)` | Nest OR group of rules. |
| `andGroup(cb)` | Explicit AND group. |
| `notGroup(cb)` | Nest rules and negate the group result. |
| `then(fn)` | What to do if the rules pass. |
| `otherwise(fn)` | What to do if rules fail. |
| `evaluate(ctx)` | Evaluate against input data. |
| `evaluateLogicOnly(ctx)` | Returns only boolean result. |
## 💡 Real-World Example
```js
const engine = createRuleEngine()
.when(u => u.role === 'admin')
.orGroup(g =>
g.when(u => u.plan === 'pro').and(u => u.paid === true)
)
.not(u => u.suspended)
.then(() => '🚀 Dashboard Access')
.otherwise(() => '🔒 Please upgrade');
engine.evaluate({ role: 'user', plan: 'pro', paid: true, suspended: false });
// → 🚀 Dashboard Access
```
## 🧪 Testing
```bash
npm run test
```
All examples from the README are covered in the test suite, including:
* 🧱 Basic rules
* 🔁 Nesting & grouping
* 🔀 Multiple logic paths
* ❗ Negations
* 🧼 Clean evaluation with return value or boolean
## 🗿 Philosophy
* Simplicity over frameworks.
* Logic should be readable by humans, not just parsed by AI.
* One chain to rule them all.
## 🐾 Related Inspiration
* Redux-style DSLs (`.map().reduce()`)
* Rule-based access control (RBAC)
* Business logic extractors
* Decision trees (without looking like one)
## 📦 CommonJS + ESM support
```js
// ESM
import { createRuleEngine } from 'the-rule-engine';
// CommonJS
const { createRuleEngine } = require('the-rule-engine');
```
## 🧘 Final Thoughts
Use it for fun, profit, or clarity.
If your logic starts to look like:
```js
if (a && (!b || (c && !d))) { ... }
```
It's time for `the-rule-engine`.
Made with ☕ + 😤 to avoid `if-else` spaghetti.
## 🧑🚀 About the Developer
Built by [cinfinit](https://github.com/cinfinit) who’s:
Written too many if/else blocks to count
Thought, “There has to be a cleaner way”
Refused to let business logic live in nested ternaries
Drinks water like .then() drinks callbacks
They don’t claim to be a 10x engineer — just someone who believes logic should be elegant, readable, and maybe even fun.
Feel free to open issues, contribute, or just send memes about ugly conditionals.