@anygpt/rules
v0.3.1
Published
Type-safe rule engine for matching and transforming objects
Maintainers
Readme
@anygpt/rules
⚠️ WORK IN PROGRESS: This package is under active development. Rule engine APIs may change significantly. Use at your own risk in production environments.
A simple, type-safe rule engine for matching and transforming objects.
Features
- ✅ Type-safe - Full TypeScript support
- ✅ Shortcut syntax - Direct values, regex, arrays
- ✅ Mixed arrays - Combine regex and exact matches
- ✅ Simple operators -
eq,in,match(regex/glob) - ✅ Logical composition -
and,or,not - ✅ Default values - Constructor-level defaults
- ✅ Array operations -
pushto append to arrays - ✅ Zero dependencies - Pure TypeScript implementation
- ✅ 100% test coverage - Production ready
Usage
import { RuleEngine, type Rule } from '@anygpt/rules';
interface Server {
name: string;
tools: string[];
tags: string[];
enabled?: boolean;
}
const engine = new RuleEngine(
[
{
// Shortcut: direct value (eq)
when: { name: 'github' },
set: { enabled: true, priority: 'high' },
push: { tags: ['verified'] },
},
{
// Shortcut: regex (match)
when: { name: /^github/ },
set: { enabled: true },
push: { tags: ['safe'] },
},
{
// Mixed array: regex OR exact match
when: { name: [/^gitlab/, 'bitbucket'] },
set: { enabled: true, priority: 'medium' },
},
{
// Pattern match: regex or glob
when: { name: { match: /^github/ } },
set: { enabled: true },
},
],
// Default values applied to all items
{ enabled: false, priority: 'low', tags: [] }
);
// Apply rules
const result = engine.apply({
name: 'github-official',
tools: [],
tags: ['fast'],
});
// Result:
// {
// name: 'github-official',
// enabled: true,
// priority: 'high',
// tags: ['fast', 'verified', 'safe'] // Appended!
// }Operators
Shortcut Syntax (Recommended)
For cleaner, more readable rules:
Direct value →
eqoperator{ name: 'github'; } // Same as { name: { eq: 'github' } } { count: 5; } // Same as { count: { eq: 5 } }RegExp →
matchoperator{ name: /^github/; } // Same as { name: { match: /^github/ } }Array →
inoperator (supports mixed types!){ name: ['github', 'gitlab']; } // Exact match any { name: [/^github/, 'gitlab']; } // Regex OR exact match { name: [/^github/, /^gitlab/]; } // Multiple regex patterns
Explicit Operators
eq- Exact match{ name: { eq: 'github'; } }in- Value is in array{ name: { in: ['github', 'gitlab'] } }match- Regex or glob pattern{ name: { match: /^github/; } } { name: { match: 'github-*'; } } { name: { match: ['github-*', 'gitlab-*']; } }
Logical Operators
and- All conditions must match{ and: [{ name: { eq: 'github' } }, { tags: { in: ['safe'] } }]; }or- Any condition must match{ or: [{ name: { eq: 'github' } }, { name: { eq: 'gitlab' } }]; }not- Negate condition{ not: { name: { in: ['docker', 'anygpt'] } } }
Pattern Matching
The match operator supports:
RegExp - Standard JavaScript regex
{ name: { match: /^github/; } }Glob patterns - Simple wildcard patterns
*- matches any characters?- matches single character
{ name: { match: 'github-*'; } } { name: { match: 'github-?'; } }Multiple patterns - Match any of the patterns
{ name: { match: [/^github/, 'gitlab-*']; } }
Type Safety
The rule engine is fully type-safe:
interface Server {
name: string;
count: number;
}
const rules: Rule<Server>[] = [
{
when: { name: { eq: 'github' } }, // ✅ OK
set: { count: 10 }, // ✅ OK
},
{
when: { invalid: { eq: 'test' } }, // ❌ Error: 'invalid' not in Server
set: { name: 'test' }, // ✅ OK
},
{
when: { name: { eq: 'github' } },
set: { invalid: true }, // ❌ Error: 'invalid' not in Server
},
];Installation
npm install @anygpt/rulesDevelopment
# Run tests
npx nx test rules
# Run tests with coverage (100% coverage required)
npx nx test rules --coverage
# Build package
npx nx build rules
# Lint
npx nx lint rules
# Type check
npx nx typecheck rules