Complete reference for all built-in operators in Rule Engine JS.
eq
- EqualChecks if two values are equal.
Syntax:
{ "eq": [leftValue, rightValue, options?] }
rules.eq(leftValue, rightValue, options?)
Parameters:
leftValue
: First value to compare (can be path or literal)rightValue
: Second value to compare (can be path or literal)options
: Optional configuration objectOptions:
strict
: Boolean - Use strict equality (===
) vs loose (==
)Examples:
// Basic equality
rules.eq('user.role', 'admin')
{ "eq": ["user.role", "admin"] }
// Dynamic field comparison
rules.eq('order.currency', 'user.preferredCurrency')
{ "eq": ["order.currency", "user.preferredCurrency"] }
// Strict mode
rules.eq('user.age', '25', { strict: true }) // false - string vs number
rules.eq('user.age', 25, { strict: true }) // true - both numbers
// Loose mode (default)
rules.eq('user.age', '25') // true - '25' == 25
Type Coercion:
const data = { stringNumber: '42', actualNumber: 42 };
// Loose mode allows coercion
rules.eq('stringNumber', 42); // true ('42' == 42)
// Strict mode prevents coercion
rules.eq('stringNumber', 42, { strict: true }); // false ('42' !== 42)
neq
- Not EqualChecks if two values are not equal.
Syntax:
{ "neq": [leftValue, rightValue, options?] }
rules.neq(leftValue, rightValue, options?)
Examples:
// Basic inequality
rules.neq('user.status', 'deleted')
{ "neq": ["user.status", "deleted"] }
// Ensure fields are different
rules.neq('user.email', 'user.recoveryEmail')
// With strict mode
rules.neq('count', '0', { strict: true }) // true if count is number 0
gt
- Greater ThanChecks if left value is greater than right value.
Syntax:
{ "gt": [leftValue, rightValue, options?] }
rules.gt(leftValue, rightValue, options?)
Examples:
// Age validation
rules.gt('user.age', 17) // Must be 18 or older
{ "gt": ["user.age", 17] }
// Dynamic comparison
rules.gt('order.total', 'user.budget')
// Decimal numbers
rules.gt('product.rating', 4.5)
// Date comparison (using timestamps)
rules.gt('user.lastLogin', Date.now() - 86400000) // Active in last 24h
Type Handling:
const data = {
stringAge: '25',
numericAge: 25,
price: 99.99,
};
// Automatic coercion in loose mode
rules.gt('stringAge', 20); // true ('25' converted to 25)
rules.gt('price', 99); // true (99.99 > 99)
// Strict mode requires same types
rules.gt('stringAge', 20, { strict: true }); // Error - string vs number
gte
- Greater Than or EqualChecks if left value is greater than or equal to right value.
Syntax:
{ "gte": [leftValue, rightValue, options?] }
rules.gte(leftValue, rightValue, options?)
Examples:
// Minimum age requirement
rules.gte('user.age', 18)
{ "gte": ["user.age", 18] }
// Minimum score requirement
rules.gte('exam.score', 'exam.passingScore')
// Inventory check
rules.gte('product.stock', 'order.quantity')
// Boundary conditions
rules.gte('user.credits', 0) // Non-negative credits
lt
- Less ThanChecks if left value is less than right value.
Syntax:
{ "lt": [leftValue, rightValue, options?] }
rules.lt(leftValue, rightValue, options?)
Examples:
// Maximum limit check
rules.lt('order.total', 1000)
{ "lt": ["order.total", 1000] }
// Age limit
rules.lt('user.age', 65)
// Performance threshold
rules.lt('response.time', 'sla.maxResponseTime')
// Percentage validation
rules.lt('discount.percentage', 1.0) // Less than 100%
lte
- Less Than or EqualChecks if left value is less than or equal to right value.
Syntax:
{ "lte": [leftValue, rightValue, options?] }
rules.lte(leftValue, rightValue, options?)
Examples:
// Budget constraint
rules.lte('project.cost', 'project.budget')
{ "lte": ["project.cost", "project.budget"] }
// Capacity check
rules.lte('event.attendees', 'venue.capacity')
// Rating validation
rules.lte('review.rating', 5)
// Time limit
rules.lte('task.duration', 'task.estimatedTime')
and
- Logical ANDAll conditions must be true for the rule to pass.
Syntax:
{ "and": [condition1, condition2, ...] }
rules.and(condition1, condition2, ...)
Examples:
// User eligibility
rules.and(
rules.gte('user.age', 18),
rules.eq('user.status', 'active'),
rules.isTrue('user.verified')
)
{
"and": [
{ "gte": ["user.age", 18] },
{ "eq": ["user.status", "active"] },
{ "eq": ["user.verified", true] }
]
}
// Complex business logic
rules.and(
// Basic user validation
rules.validation.required('user.email'),
rules.validation.email('user.email'),
// Account status
rules.eq('user.accountStatus', 'active'),
// Permission check
rules.or(
rules.eq('user.role', 'admin'),
rules.in('write', 'user.permissions')
),
// Rate limiting
rules.lt('user.requestsToday', 'limits.dailyMax')
)
Short-Circuit Evaluation:
The and
operator stops at the first false
condition, improving performance:
// If user.active is false, remaining conditions aren't evaluated
rules.and(
rules.isTrue('user.active'), // Checked first
rules.validation.email('email'), // Skipped if user not active
rules.regex('phone', pattern) // Skipped if user not active
);
or
- Logical ORAt least one condition must be true for the rule to pass.
Syntax:
{ "or": [condition1, condition2, ...] }
rules.or(condition1, condition2, ...)
Examples:
// Multiple access methods
rules.or(
rules.eq('user.role', 'admin'),
rules.eq('user.role', 'moderator'),
rules.and(rules.eq('user.role', 'user'), rules.in('premium', 'user.subscriptions'))
);
// Alternative validation methods
rules.or(
rules.validation.email('contact.email'),
rules.validation.required('contact.phone'),
rules.validation.required('contact.address')
);
// Flexible discount eligibility
rules.or(
rules.gte('order.total', 100), // Large order
rules.eq('customer.type', 'vip'), // VIP customer
rules.gte('customer.loyaltyPoints', 500), // Loyal customer
rules.isTrue('customer.firstTime') // First-time customer
);
Early Success:
The or
operator stops at the first true
condition:
// If user is admin, other conditions aren't checked
rules.or(
rules.eq('user.role', 'admin'), // If true, stop here
rules.complexValidation('user'), // Skipped if admin
rules.expensiveApiCall('user') // Skipped if admin
);
not
- Logical NOTNegates the result of a condition.
Syntax:
{ "not": [condition] }
rules.not(condition)
Examples:
// User is not banned
rules.not(rules.eq('user.status', 'banned'))
{ "not": [{ "eq": ["user.status", "banned"] }] }
// Account is not expired
rules.not(rules.lt('account.expiryDate', Date.now()))
// Complex negation
rules.not(
rules.or(
rules.eq('user.status', 'banned'),
rules.eq('user.status', 'suspended'),
rules.eq('user.status', 'deleted')
)
)
// Equivalent positive form (often more readable)
rules.in('user.status', ['active', 'pending', 'verified'])
Double Negation:
// Avoid double negation - it's confusing
rules.not(rules.not(rules.eq('user.active', true))); // β Confusing
// Better: Use positive logic
rules.eq('user.active', true); // β
Clear
contains
- String ContainsChecks if a string contains a substring.
Syntax:
{ "contains": [string, substring, options?] }
rules.contains(string, substring, options?)
Examples:
// Basic substring search
rules.contains('user.bio', 'engineer')
{ "contains": ["user.bio", "engineer"] }
// Email domain check
rules.contains('user.email', '@company.com')
// Search in dynamic fields
rules.contains('product.description', 'search.keyword')
// Multiple keywords (using OR)
rules.or(
rules.contains('content', 'javascript'),
rules.contains('content', 'typescript'),
rules.contains('content', 'react')
)
Case Sensitivity:
const data = { title: 'JavaScript Tutorial' };
rules.contains('title', 'JavaScript'); // true
rules.contains('title', 'javascript'); // false - case sensitive
rules.contains('title', 'SCRIPT'); // false - case sensitive
// For case-insensitive search, use regex:
rules.regex('title', 'javascript', { flags: 'i' }); // true
Special Characters:
// Searching for special characters
rules.contains('text', '@'); // Find @ symbol
rules.contains('filename', '.pdf'); // Find file extension
rules.contains('code', 'function()'); // Find function calls
startsWith
- String Starts WithChecks if a string starts with a specific substring.
Syntax:
{ "startsWith": [string, prefix, options?] }
rules.startsWith(string, prefix, options?)
Examples:
// URL protocol check
rules.startsWith('website.url', 'https://')
{ "startsWith": ["website.url", "https://"] }
// File type validation
rules.startsWith('upload.filename', 'IMG_')
// Naming conventions
rules.startsWith('api.endpoint', '/api/v1/')
// Dynamic prefix
rules.startsWith('document.id', 'user.departmentCode')
// Phone number format
rules.startsWith('contact.phone', '+1') // US numbers
Empty String Edge Case:
const data = { value: 'hello', empty: '' };
rules.startsWith('value', ''); // true - every string starts with empty string
rules.startsWith('empty', ''); // true
rules.startsWith('empty', 'test'); // false
endsWith
- String Ends WithChecks if a string ends with a specific substring.
Syntax:
{ "endsWith": [string, suffix, options?] }
rules.endsWith(string, suffix, options?)
Examples:
// File extension validation
rules.endsWith('file.name', '.pdf')
{ "endsWith": ["file.name", ".pdf"] }
// Email domain validation
rules.endsWith('user.email', '.edu')
// URL validation
rules.endsWith('api.callback', '/webhook')
// Multiple valid extensions
rules.or(
rules.endsWith('upload.file', '.jpg'),
rules.endsWith('upload.file', '.png'),
rules.endsWith('upload.file', '.gif')
)
// Dynamic suffix
rules.endsWith('report.filename', 'report.expectedSuffix')
regex
- Regular ExpressionMatches a string against a regular expression pattern.
Syntax:
{ "regex": [string, pattern, options?] }
rules.regex(string, pattern, options?)
Options:
flags
: String - Regex flags ('g'
, 'i'
, 'm'
, 's'
, 'u'
, 'y'
)Common Patterns:
// Email validation
rules.regex('email', '^[\\w\\.-]+@[\\w\\.-]+\\.[a-zA-Z]{2,}$')
// Phone number validation (US format)
rules.regex('phone', '^\\+?1?[2-9]\\d{2}[2-9]\\d{2}\\d{4}$')
// Password strength (8+ chars, letter + number)
rules.regex('password', '^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d@$!%*?&]{8,}$')
// Credit card number (basic format)
rules.regex('creditCard', '^\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}$')
// URL validation
rules.regex('url', '^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b')
// IP address validation
rules.regex('ip', '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
Flags Usage:
// Case-insensitive matching
rules.regex('name', 'john', { flags: 'i' }); // Matches 'John', 'JOHN', 'john'
// Global matching (for validation, usually not needed)
rules.regex('text', 'pattern', { flags: 'g' });
// Multiline matching
rules.regex('content', '^Important:', { flags: 'm' }); // Match at start of any line
// Combined flags
rules.regex('text', 'pattern', { flags: 'gi' }); // Global + case-insensitive
Dynamic Patterns:
// Pattern from context
rules.regex('user.input', 'validation.pattern')
// Building patterns
const phonePatterns = {
US: '^\\+?1[2-9]\\d{2}[2-9]\\d{2}\\d{4},
UK: '^\\+?44[1-9]\\d{8,9},
FR: '^\\+?33[1-9]\\d{8}
};
rules.regex('phone', phonePatterns.US)
Common Validation Patterns:
// Social Security Number
rules.regex('ssn', '^\\d{3}-\\d{2}-\\d{4})
// ZIP Code (US)
rules.regex('zipCode', '^\\d{5}(-\\d{4})?)
// Date (YYYY-MM-DD)
rules.regex('date', '^\\d{4}-\\d{2}-\\d{2})
// Time (HH:MM or HH:MM:SS)
rules.regex('time', '^\\d{2}:\\d{2}(:\\d{2})?)
// Hexadecimal color
rules.regex('color', '^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}))
// Username (alphanumeric + underscore, 3-20 chars)
rules.regex('username', '^[a-zA-Z0-9_]{3,20})
in
- Value in ArrayChecks if a value exists in an array.
Syntax:
{ "in": [value, array, options?] }
rules.in(value, array, options?)
Examples:
// Static array membership
rules.in('user.role', ['admin', 'moderator', 'user'])
{ "in": ["user.role", ["admin", "moderator", "user"]] }
// Dynamic array from context
rules.in('permission', 'user.permissions')
// Check if value is in user's tags
rules.in('premium', 'user.tags')
// Multiple value checks
rules.and(
rules.in('read', 'user.permissions'),
rules.in('write', 'user.permissions')
)
// Complex array structures
const data = {
user: { skills: ['javascript', 'python', 'react'] },
job: { requiredSkills: ['javascript', 'react'] }
};
rules.in('javascript', 'user.skills') // true
Type Coercion:
const data = {
numbers: [1, 2, 3],
strings: ['1', '2', '3'],
mixed: [1, '2', 3],
};
// Loose mode (default) - allows coercion
rules.in('1', 'numbers'); // true ('1' == 1)
rules.in(2, 'strings'); // true (2 == '2')
// Strict mode - no coercion
rules.in('1', 'numbers', { strict: true }); // false ('1' !== 1)
rules.in(2, 'strings', { strict: true }); // false (2 !== '2')
Complex Data Structures:
const data = {
users: [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
],
userIds: [1, 2, 3, 4],
};
// Simple array membership
rules.in(1, 'userIds'); // true
// For object arrays, you'd need to extract IDs first
// or use custom operators for complex object matching
notIn
- Value Not in ArrayChecks if a value does NOT exist in an array.
Syntax:
{ "notIn": [value, array, options?] }
rules.notIn(value, array, options?)
Examples:
// Exclude banned users
rules.notIn('user.status', ['banned', 'suspended', 'deleted'])
{ "notIn": ["user.status", ["banned", "suspended", "deleted"]] }
// Permission restrictions
rules.notIn('admin', 'user.permissions')
// Content filtering
rules.notIn('adult', 'content.categories')
// Geographic restrictions
rules.notIn('user.country', 'restrictions.blockedCountries')
// Combined with positive checks
rules.and(
rules.in('user.role', ['user', 'premium', 'admin']), // Must have valid role
rules.notIn('user.status', ['banned', 'suspended']) // Must not be restricted
)
Whitelist vs Blacklist Pattern:
// Whitelist approach (more secure)
rules.in('user.role', ['user', 'admin', 'moderator']);
// Blacklist approach (less secure, easy to miss cases)
rules.notIn('user.role', ['banned', 'guest']);
// Combined approach (most robust)
rules.and(
rules.in('user.role', ['user', 'admin', 'moderator']), // Whitelist valid roles
rules.notIn('user.status', ['banned', 'suspended']) // Blacklist bad statuses
);
between
- Range CheckChecks if a value falls within a specified range (inclusive).
Syntax:
{ "between": [value, [min, max], options?] }
rules.between(value, [min, max], options?)
Examples:
// Age range
rules.between('user.age', [18, 65])
{ "between": ["user.age", [18, 65]] }
// Price range
rules.between('product.price', [10.99, 99.99])
// Score validation
rules.between('exam.score', [0, 100])
// Dynamic range from context
rules.between('user.score', 'game.scoreRange')
// where context.game.scoreRange = [100, 1000]
// Date range (using timestamps)
const lastWeek = Date.now() - (7 * 24 * 60 * 60 * 1000);
const now = Date.now();
rules.between('event.timestamp', [lastWeek, now])
Dynamic Range Boundaries:
const context = {
user: { age: 25, income: 50000 },
loan: { amount: 100000 },
criteria: {
minAge: 18,
maxAge: 70,
minIncomeMultiplier: 2, // loan amount can't exceed 2x income
maxIncomeMultiplier: 5, // loan amount can't exceed 5x income
},
};
// Age range with dynamic boundaries
rules.between('user.age', ['criteria.minAge', 'criteria.maxAge']);
// Complex calculated range
const enhancedContext = {
...context,
calculated: {
minLoanAmount: context.user.income * context.criteria.minIncomeMultiplier,
maxLoanAmount: context.user.income * context.criteria.maxIncomeMultiplier,
},
};
rules.between('loan.amount', ['calculated.minLoanAmount', 'calculated.maxLoanAmount']);
Edge Cases:
// Single value range (equality check)
rules.between('status.code', [200, 200]); // Equivalent to eq(200)
// Boundary values (inclusive)
rules.between('rating', [1, 5]); // 1 and 5 are valid
// Decimal ranges
rules.between('percentage', [0.0, 1.0]);
rules.between('rating', [1.0, 5.0]);
isNull
- Null CheckChecks if a value is null, undefined, or path doesnβt exist.
Syntax:
{ "isNull": [path] }
rules.isNull(path)
Examples:
// Check if field is null
rules.isNull('user.deletedAt')
{ "isNull": ["user.deletedAt"] }
// Optional field validation
rules.isNull('user.middleName')
// Check for missing nested properties
rules.isNull('user.profile.avatar')
// Conditional logic based on null values
rules.or(
rules.isNull('user.preferences'),
rules.eq('user.preferences.theme', 'default')
)
What Counts as Null:
const testData = [
{ value: null }, // isNull = true
{ value: undefined }, // isNull = true
{}, // isNull = true (missing property)
{ value: '' }, // isNull = false (empty string is not null)
{ value: 0 }, // isNull = false (zero is not null)
{ value: false }, // isNull = false (false is not null)
{ value: [] }, // isNull = false (empty array is not null)
{ value: {} }, // isNull = false (empty object is not null)
];
testData.forEach((data, index) => {
const result = engine.evaluateExpr(rules.isNull('value'), data);
console.log(`Test ${index}: ${result.success}`);
});
Nested Path Handling:
const data = {
user: {
profile: null,
settings: {
theme: 'dark',
},
},
};
rules.isNull('user.profile'); // true
rules.isNull('user.profile.name'); // true (profile is null)
rules.isNull('user.settings'); // false
rules.isNull('user.settings.theme'); // false
rules.isNull('user.settings.missing'); // true (property doesn't exist)
rules.isNull('user.nonexistent.path'); // true (path doesn't exist)
isNotNull
- Not Null CheckChecks if a value is not null, not undefined, and path exists.
Syntax:
{ "isNotNull": [path] }
rules.isNotNull(path)
Examples:
// Ensure required field exists
rules.isNotNull('user.email')
{ "isNotNull": ["user.email"] }
// Check if optional field is provided
rules.isNotNull('order.specialInstructions')
// Validate nested object exists
rules.isNotNull('user.profile.address')
// Combined validation
rules.and(
rules.isNotNull('user.email'),
rules.validation.email('user.email')
)
Practical Usage Patterns:
// Safe navigation pattern
rules.and(rules.isNotNull('user.profile'), rules.eq('user.profile.status', 'verified'));
// Optional field processing
rules.or(
rules.isNull('user.preferences'), // No preferences set
rules.and(rules.isNotNull('user.preferences'), rules.eq('user.preferences.notifications', true))
);
// Required vs optional validation
const userValidation = rules.and(
// Required fields
rules.isNotNull('user.email'),
rules.isNotNull('user.firstName'),
rules.isNotNull('user.lastName'),
// Optional fields (only validate if present)
rules.or(rules.isNull('user.phone'), rules.regex('user.phone', phonePattern)),
rules.or(rules.isNull('user.website'), rules.regex('user.website', urlPattern))
);
The validation helpers are pre-built rule combinations for common validation scenarios.
validation.email
- Email ValidationValidates email address format using regex pattern.
Syntax:
rules.validation.email(fieldPath);
Examples:
// Basic email validation
rules.validation.email('user.email');
// Multiple email validation
rules.and(
rules.validation.email('user.primaryEmail'),
rules.validation.email('user.recoveryEmail')
);
// Optional email validation
rules.or(rules.isNull('user.email'), rules.validation.email('user.email'));
Pattern Used:
// Internal pattern (equivalent to):
rules.regex('email', '^[\\w\\.-]+@[\\w\\.-]+\\.[a-zA-Z]{2,})
validation.required
- Required FieldEnsures field is not null, undefined, or empty string.
Syntax:
rules.validation.required(fieldPath);
Examples:
// Required field validation
rules.validation.required('user.name');
// Multiple required fields
rules.and(
rules.validation.required('firstName'),
rules.validation.required('lastName'),
rules.validation.required('email')
);
Equivalent Logic:
// Internal implementation (equivalent to):
rules.and(rules.isNotNull('fieldPath'), rules.neq('fieldPath', ''));
Whatβs Considered Empty:
const testData = [
{ name: 'John' }, // required = true
{ name: '' }, // required = false (empty string)
{ name: null }, // required = false (null)
{ name: undefined }, // required = false (undefined)
{}, // required = false (missing)
{ name: 0 }, // required = true (zero is valid)
{ name: false }, // required = true (false is valid)
{ name: [] }, // required = true (empty array is valid)
];
validation.minAge
/ validation.maxAge
- Age ValidationValidates minimum or maximum age requirements.
Syntax:
rules.validation.minAge(fieldPath, minimumAge);
rules.validation.maxAge(fieldPath, maximumAge);
Examples:
// Minimum age requirement
rules.validation.minAge('user.age', 18);
// Maximum age limit
rules.validation.maxAge('user.age', 65);
// Combined age validation
rules.and(rules.validation.minAge('user.age', 18), rules.validation.maxAge('user.age', 120));
Equivalent Logic:
// Internal implementation:
rules.validation.minAge = (path, minAge) => rules.gte(path, minAge);
rules.validation.maxAge = (path, maxAge) => rules.lte(path, maxAge);
validation.ageRange
- Age Range ValidationValidates age within a specific range.
Syntax:
rules.validation.ageRange(fieldPath, minimumAge, maximumAge);
Examples:
// Working age range
rules.validation.ageRange('user.age', 18, 65);
// School age range
rules.validation.ageRange('student.age', 5, 18);
// Senior citizen range
rules.validation.ageRange('user.age', 65, 120);
Equivalent Logic:
// Internal implementation:
rules.validation.ageRange = (path, minAge, maxAge) => rules.between(path, [minAge, maxAge]);
validation.oneOf
- Choice ValidationValidates that a value is one of the allowed options.
Syntax:
rules.validation.oneOf(fieldPath, allowedValues);
Examples:
// Status validation
rules.validation.oneOf('user.status', ['active', 'inactive', 'pending']);
// Role validation
rules.validation.oneOf('user.role', ['user', 'admin', 'moderator']);
// Country validation
rules.validation.oneOf('user.country', ['US', 'CA', 'UK', 'DE', 'FR']);
// Gender validation (optional)
rules.or(
rules.isNull('user.gender'),
rules.validation.oneOf('user.gender', ['male', 'female', 'other', 'prefer-not-to-say'])
);
Equivalent Logic:
// Internal implementation:
rules.validation.oneOf = (path, values) => rules.in(path, values);
User Eligibility:
const userEligibility = rules.and(
rules.validation.required('user.email'),
rules.validation.email('user.email'),
rules.validation.ageRange('user.age', 18, 65),
rules.validation.oneOf('user.status', ['active', 'verified']),
rules.notIn('user.role', ['banned', 'suspended'])
);
Form Validation:
const formValidation = rules.and(
// Required fields
rules.validation.required('firstName'),
rules.validation.required('lastName'),
rules.validation.required('email'),
// Format validation
rules.validation.email('email'),
rules.regex('phone', phonePattern),
// Password requirements
rules.and(
rules.gte('password.length', 8),
rules.regex('password', '(?=.*[A-Za-z])'), // Letter
rules.regex('password', '(?=.*\\d)'), // Number
rules.regex('password', '(?=.*[@$!%*?&])') // Special char
),
// Confirmation
rules.field.equals('password', 'confirmPassword'),
rules.isTrue('agreedToTerms')
);
Business Rules:
const discountEligibility = rules.or(
// VIP customers
rules.and(rules.eq('customer.tier', 'vip'), rules.gte('order.total', 100)),
// High loyalty points
rules.gte('customer.loyaltyPoints', 1000),
// Bulk orders
rules.and(rules.gte('order.quantity', 10), rules.in('order.category', ['electronics', 'books'])),
// First-time customers
rules.and(rules.isTrue('customer.firstTime'), rules.gte('order.total', 50)),
// Seasonal promotion
rules.and(
rules.between('currentDate', 'promotion.dateRange'),
rules.in('order.category', 'promotion.categories')
)
);
eq
with boolean valuesisNull
, isNotNull
gt
, gte
, lt
, lte
, between
in
, notIn
(depends on array size)contains
, startsWith
, endsWith
regex
(depends on pattern complexity)and
, or
, not
(depends on sub-expressions)Order Operations by Speed:
// β
Optimized: Fast checks first
const optimizedRule = rules.and(
rules.eq('user.active', true), // Fastest
rules.gte('user.age', 18), // Fast
rules.in('user.role', ['user', 'admin']), // Medium
rules.contains('user.email', '@company'), // Slower
rules.validation.email('user.email') // Slowest (regex)
);
// β Unoptimized: Slow checks first
const unoptimizedRule = rules.and(
rules.validation.email('user.email'), // Slowest first
rules.contains('user.email', '@company'), // Slower
rules.in('user.role', ['user', 'admin']), // Medium
rules.gte('user.age', 18), // Fast
rules.eq('user.active', true) // Fastest last
);
Use Specific Operators:
// β
Faster: Direct equality
rules.eq('status', 'active')
// β Slower: Regex for simple equality
rules.regex('status', '^active)
// β
Faster: Array membership
rules.in('role', ['admin', 'user'])
// β Slower: Multiple OR conditions
rules.or(
rules.eq('role', 'admin'),
rules.eq('role', 'user')
)
This comprehensive operator reference provides everything you need to build powerful, efficient rules with Rule Engine JS. Each operator is designed to handle common use cases while roviding the flexibility to build complex business logic.