Overview
Logical operators let you combine multiple conditions together. Think of them like building blocks for complex rules.
and All conditions must be true
or At least one condition must be true
Architecture
Logical operators are implemented in the LogicalOperators class:
Source Files:
Logical operators: src/operators/logical.js
Base operator: src/operators/base/BaseOperator.js
Unit tests: tests/unit/operators/logical.test.js
Key Features
Short-circuit evaluation - Stops checking as soon as result is known
Unlimited nesting - Combine operators inside each other
Works with any operator - Combine comparison, string, array operators, etc.
Clear error messages - Helpful feedback when something goes wrong
and - All Must Be True
All conditions must pass for the rule to pass. Like saying “I need this AND that AND those.”
Syntax
{ and : [ condition1 , condition2 , ... ] }
Parameters
Array of rule conditions (minimum 1 condition)
Returns
boolean - true only if all conditions are true
How It Works
✓ true AND ✓ true = ✓ true
✓ true AND ✗ false = ✗ false
✗ false AND ✓ true = ✗ false
✗ false AND ✗ false = ✗ false
Examples
Basic AND
Access Control
Nested AND
With Rule Helpers
import { createRuleEngine } from 'rule-engine-js' ;
const engine = createRuleEngine ();
const user = {
age: 28 ,
role: 'admin' ,
active: true
};
// All three conditions must be true
const rule = {
and: [
{ gte: [ 'age' , 18 ] }, // ✓ 28 >= 18
{ eq: [ 'role' , 'admin' ] }, // ✓ role is admin
{ eq: [ 'active' , true ] } // ✓ active is true
]
};
engine . evaluateExpr ( rule , user );
// Result: { success: true, value: true }
// If ANY condition fails, AND fails
const failRule = {
and: [
{ gte: [ 'age' , 18 ] }, // ✓ true
{ eq: [ 'role' , 'guest' ] } // ✗ false (role is 'admin', not 'guest')
]
};
engine . evaluateExpr ( failRule , user );
// Result: { success: true, value: false }
Common Use Cases
// User needs specific role AND active status
const hasPermission = {
and: [
{ eq: [ 'role' , 'admin' ] },
{ eq: [ 'status' , 'active' ] },
{ neq: [ 'banned' , true ] }
]
};
// Price must be within range
const validPrice = {
and: [
{ gte: [ 'price' , 10 ] }, // At least $10
{ lte: [ 'price' , 100 ] } // At most $100
]
};
Short-circuit : AND stops checking as soon as it finds a false condition, making it faster.
or - At Least One Must Be True
At least one condition must pass. Like saying “I need this OR that OR those.”
Syntax
{ or : [ condition1 , condition2 , ... ] }
Parameters
Array of rule conditions (minimum 1 condition)
Returns
boolean - true if any condition is true
How It Works
✓ true OR ✓ true = ✓ true
✓ true OR ✗ false = ✓ true
✗ false OR ✓ true = ✓ true
✗ false OR ✗ false = ✗ false
Examples
Basic OR
Multiple Payment Methods
Nested OR
With Rule Helpers
const user = {
role: 'editor' ,
isOwner: false ,
isModerator: false
};
// User needs at least ONE of these roles
const canEdit = {
or: [
{ eq: [ 'role' , 'admin' ] }, // ✗ false
{ eq: [ 'role' , 'editor' ] }, // ✓ true (this one passes!)
{ eq: [ 'isOwner' , true ] }, // ✗ false
{ eq: [ 'isModerator' , true ] } // ✗ false
]
};
engine . evaluateExpr ( canEdit , user );
// Result: { success: true, value: true }
// All conditions must fail for OR to fail
const noAccess = {
or: [
{ eq: [ 'role' , 'admin' ] }, // ✗ false
{ eq: [ 'isOwner' , true ] } // ✗ false
]
};
engine . evaluateExpr ( noAccess , user );
// Result: { success: true, value: false }
Common Use Cases
// Grant access to multiple roles
const canAccess = {
or: [
{ eq: [ 'role' , 'admin' ] },
{ eq: [ 'role' , 'moderator' ] },
{ eq: [ 'role' , 'editor' ] }
]
};
// Discount for students OR seniors OR members
const getsDiscount = {
or: [
{ eq: [ 'isStudent' , true ] },
{ gte: [ 'age' , 65 ] },
{ eq: [ 'membershipLevel' , 'gold' ] }
]
};
// Match any category
const matchesSearch = {
or: [
{ contains: [ 'category' , 'electronics' ] },
{ contains: [ 'category' , 'computers' ] },
{ contains: [ 'category' , 'phones' ] }
]
};
Short-circuit : OR stops checking as soon as it finds a true condition, making it faster.
not - Reverse a Condition
Flips a condition - true becomes false, false becomes true. Like saying “NOT this.”
Syntax
Parameters
Single rule condition (exactly 1, no more, no less)
Returns
boolean - true if condition is false, false if condition is true
How It Works
NOT ✓ true = ✗ false
NOT ✗ false = ✓ true
Examples
Basic NOT
Exclude Conditions
Combined with AND/OR
With Rule Helpers
const user = {
name: 'John' ,
banned: false ,
deleted: false
};
// User is NOT banned
const notBanned = {
not: [
{ eq: [ 'banned' , true ] } // false, so NOT false = true
]
};
engine . evaluateExpr ( notBanned , user );
// Result: { success: true, value: true }
// User is NOT named Jane
const notJane = {
not: [
{ eq: [ 'name' , 'Jane' ] } // false, so NOT false = true
]
};
engine . evaluateExpr ( notJane , user );
// Result: { success: true, value: true }
// User is NOT named John (this fails!)
const notJohn = {
not: [
{ eq: [ 'name' , 'John' ] } // true, so NOT true = false
]
};
engine . evaluateExpr ( notJohn , user );
// Result: { success: true, value: false }
Common Use Cases
// User is NOT banned or deleted
const activeUser = {
and: [
{ not: [{ eq: [ 'banned' , true ] }] },
{ not: [{ eq: [ 'deleted' , true ] }] }
]
};
// NOT a minor (under 18)
const isAdult = {
not: [
{ lt: [ 'age' , 18 ] }
]
};
// Show all products EXCEPT archived
const visibleProducts = {
not: [
{ eq: [ 'status' , 'archived' ] }
]
};
NOT takes exactly one condition. Use { neq: [...] } for simple “not equal” checks.
Combining Operators
Mix AND, OR, and NOT to create complex logic:
Complex Examples
Premium Access
Shipping Eligibility
Content Moderation
const user = {
subscription: 'basic' ,
vipMember: false ,
trialActive: true ,
banned: false
};
// Premium access rules:
// (Premium subscriber OR VIP OR active trial) AND NOT banned
const hasPremiumAccess = {
and: [
{
or: [
{ eq: [ 'subscription' , 'premium' ] },
{ eq: [ 'vipMember' , true ] },
{ eq: [ 'trialActive' , true ] }
]
},
{
not: [
{ eq: [ 'banned' , true ] }
]
}
]
};
engine . evaluateExpr ( hasPremiumAccess , user );
// Result: { success: true, value: true }
// ✓ true because trial is active and not banned
Error Handling
Common Errors
// AND/OR need at least one condition
const result = engine . evaluateExpr ({ and: [] }, {});
// Returns:
// {
// success: false,
// error: "AND operator requires at least one argument"
// }
NOT with Wrong Number of Arguments
// NOT needs exactly one condition
const result = engine . evaluateExpr (
{ not: [] }, // Missing condition
{}
);
// Returns:
// {
// success: false,
// error: "NOT operator requires 1 arguments, got 0"
// }
// Also fails with multiple conditions
const result2 = engine . evaluateExpr (
{ not: [{ eq: [ 'a' , 1 ] }, { eq: [ 'b' , 2 ] }] },
{}
);
// Error: NOT requires exactly 1 argument
// Nested condition has an error
const result = engine . evaluateExpr (
{
and: [
{ eq: [ 'valid' , true ] },
{ invalidOp: [ 'field' ] } // Unknown operator
]
},
{ valid: true }
);
// Returns:
// {
// success: false,
// error: "Unknown operator: invalidOp"
// }
Tips for Debugging
// Break complex rules into smaller pieces
const isAdult = { gte: [ 'age' , 18 ] };
const isActive = { eq: [ 'status' , 'active' ] };
const isPremium = { eq: [ 'tier' , 'premium' ] };
// Test each piece separately
console . log ( engine . evaluateExpr ( isAdult , user ));
console . log ( engine . evaluateExpr ( isActive , user ));
console . log ( engine . evaluateExpr ( isPremium , user ));
// Then combine
const rule = {
and: [ isAdult , isActive , isPremium ],
};
console . log ( engine . evaluateExpr ( rule , user ));
Quick Reference
Operator Comparison
Operator Needs Returns True When Example
andAll conditions true All pass User is adult AND verified orAny condition true At least one passes Admin OR moderator notCondition to reverse Condition is false NOT banned
Common Patterns
Range Check
Multiple Roles
Exclude Status
// Value between min and max
{
and : [
{ gte: [ 'price' , 10 ] },
{ lte: [ 'price' , 100 ] }
]
}
API Reference
For complete API documentation: