> ## Documentation Index
> Fetch the complete documentation index at: https://crafts69guy.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Rule Helpers API

> Fluent API for building rules programmatically

## Overview

Rule Helpers provide a fluent API to build rules programmatically instead of writing JSON.

```javascript theme={null}
import { createRuleHelpers } from 'rule-engine-js';

const rules = createRuleHelpers();
```

***

## Comparison Operators

### eq()

```javascript theme={null}
rules.eq(field, value)
// { eq: [field, value] }
```

### neq()

```javascript theme={null}
rules.neq(field, value)
// { neq: [field, value] }
```

***

## Numeric Operators

### gt(), gte(), lt(), lte()

```javascript theme={null}
rules.gt('age', 18)
// { gt: ['age', 18] }

rules.gte('score', 70)
rules.lt('price', 100)
rules.lte('quantity', 50)
```

***

## Logical Operators

### and()

```javascript theme={null}
rules.and(...conditions)
// { and: [conditions] }
```

**Example:**

```javascript theme={null}
rules.and(
  rules.gte('age', 18),
  rules.eq('role', 'admin'),
  rules.in('write', 'permissions')
)
// {
//   and: [
//     { gte: ['age', 18] },
//     { eq: ['role', 'admin'] },
//     { in: ['write', 'permissions'] }
//   ]
// }
```

### or()

```javascript theme={null}
rules.or(...conditions)
// { or: [conditions] }
```

### not()

```javascript theme={null}
rules.not(condition)
// { not: [condition] }
```

***

## String Operators

### contains()

```javascript theme={null}
rules.contains('email', '@company.com')
// { contains: ['email', '@company.com'] }
```

### startsWith()

```javascript theme={null}
rules.startsWith('filename', 'report_')
// { startsWith: ['filename', 'report_'] }
```

### endsWith()

```javascript theme={null}
rules.endsWith('filename', '.pdf')
// { endsWith: ['filename', '.pdf'] }
```

### regex()

```javascript theme={null}
rules.regex('email', '^[a-z]+@example\\.com$')
// { regex: ['email', '^[a-z]+@example\\.com$'] }
```

***

## Array Operators

### in()

```javascript theme={null}
rules.in('role', ['admin', 'moderator', 'user'])
// { in: ['role', ['admin', 'moderator', 'user']] }

// Or check value in array field
rules.in('write', 'permissions')
// { in: ['write', 'permissions'] }
```

### notIn()

```javascript theme={null}
rules.notIn('status', ['banned', 'suspended'])
// { notIn: ['status', ['banned', 'suspended']] }
```

***

## Special Operators

### between()

```javascript theme={null}
rules.between('age', [18, 65])
// { between: ['age', [18, 65]] }
```

### isNull()

```javascript theme={null}
rules.isNull('middleName')
// { isNull: ['middleName'] }
```

### isNotNull()

```javascript theme={null}
rules.isNotNull('email')
// { isNotNull: ['email'] }
```

***

## State Operators

### changed()

```javascript theme={null}
rules.changed('temperature')
// { changed: ['temperature'] }
```

### changedBy()

```javascript theme={null}
rules.changedBy('price', 10)
// { changedBy: ['price', 10] }
```

### changedFrom(), changedTo()

```javascript theme={null}
rules.changedFrom('status', 'pending')
rules.changedTo('status', 'completed')
```

### increased(), decreased()

```javascript theme={null}
rules.increased('score')
rules.decreased('stock')
```

***

## Field Comparison

Compare two fields:

```javascript theme={null}
rules.field.equals('password', 'confirmPassword')
// { eq: ['password', 'confirmPassword'] }

rules.field.lessThan('price', 'maxPrice')
// { lt: ['price', 'maxPrice'] }

rules.field.greaterThan('score', 'minScore')
// { gt: ['score', 'minScore'] }
```

***

## Validation Helpers

### email()

```javascript theme={null}
rules.validation.email('email')
// { regex: ['email', '^[\\w\\.-]+@[\\w\\.-]+\\.[a-zA-Z]{2,}$'] }
```

### required()

```javascript theme={null}
rules.validation.required('username')
// { isNotNull: ['username'] }
```

### ageRange()

```javascript theme={null}
rules.validation.ageRange('age', 18, 120)
// { between: ['age', [18, 120]] }
```

### isTrue(), isFalse()

```javascript theme={null}
rules.isTrue('acceptedTerms')
// { eq: ['acceptedTerms', true] }

rules.isFalse('isBlocked')
// { eq: ['isBlocked', false] }
```

***

## Complete Example

```javascript theme={null}
import { createRuleEngine, createRuleHelpers } from 'rule-engine-js';

const engine = createRuleEngine();
const rules = createRuleHelpers();

// Build complex rule
const canAccessAdminPanel = rules.and(
  // Must be adult
  rules.gte('age', 18),

  // Must be admin or moderator
  rules.or(
    rules.eq('role', 'admin'),
    rules.eq('role', 'moderator')
  ),

  // Must have valid email
  rules.validation.email('email'),

  // Must have write permission
  rules.in('write', 'permissions'),

  // Must not be banned
  rules.not(
    rules.eq('status', 'banned')
  )
);

// Evaluate
const user = {
  age: 25,
  role: 'admin',
  email: 'admin@company.com',
  permissions: ['read', 'write', 'delete'],
  status: 'active'
};

const result = engine.evaluateExpr(canAccessAdminPanel, user);
console.log(result.success); // true
```

***

## Comparison: JSON vs Helpers

<Tabs>
  <Tab title="JSON">
    ```javascript theme={null}
    // Verbose JSON
    const rule = {
      and: [
        { gte: ['age', 18] },
        { eq: ['role', 'admin'] },
        {
          or: [
            { contains: ['email', '@company.com'] },
            { contains: ['email', '@admin.com'] }
          ]
        }
      ]
    };
    ```
  </Tab>

  <Tab title="Helpers">
    ```javascript theme={null}
    // Cleaner with helpers
    const rule = rules.and(
      rules.gte('age', 18),
      rules.eq('role', 'admin'),
      rules.or(
        rules.contains('email', '@company.com'),
        rules.contains('email', '@admin.com')
      )
    );
    ```
  </Tab>
</Tabs>

***

## TypeScript

### Basic Usage

```typescript theme={null}
import { createRuleHelpers } from 'rule-engine-js';
import type { RuleExpression } from 'rule-engine-js';

const rules = createRuleHelpers();
const rule: RuleExpression = rules.and(
  rules.gte('age', 18),
  rules.eq('role', 'admin')
);
```

### Typed Path Autocomplete <Badge>v1.0.7+</Badge>

Get IDE autocomplete for object paths by passing a type parameter:

```typescript theme={null}
// 1. Define your context type
interface UserContext {
  user: {
    name: string;
    age: number;
    email: string;
  };
  order: {
    total: number;
    status: 'pending' | 'paid' | 'shipped';
  };
}

// 2. Pass type to createRuleHelpers
const rules = createRuleHelpers<UserContext>();

// 3. Get autocomplete!
const rule = rules.and(
  rules.gte('user.age', 18),      // IDE suggests: user.age, order.total
  rules.eq('order.status', 'paid') // IDE suggests: pending, paid, shipped
);
```

<Info>
  **How it works**: The generic type `T` enables TypeScript to infer all valid paths in your object structure and provide autocomplete suggestions.
</Info>

### Type-Safe Operators

Numeric operators only accept numeric paths:

```typescript theme={null}
interface Context {
  user: { name: string; age: number };
  score: number;
}

const rules = createRuleHelpers<Context>();

rules.gte('user.age', 18);  // ✓ age is number
rules.gte('score', 100);    // ✓ score is number
rules.gte('user.name', 5);  // ✗ TypeScript error: name is string
```

### Dynamic Array Lookup

Use string paths to reference arrays in your context:

```typescript theme={null}
interface Context {
  value: string;
  allowedValues: string[];
}

const rules = createRuleHelpers<Context>();

// Check if 'value' exists in 'allowedValues' array
rules.in('value', 'allowedValues');
```

### Backward Compatibility

Untyped usage works exactly as before:

```typescript theme={null}
// No type parameter = any path allowed
const rules = createRuleHelpers();
rules.eq('any.path.here', 'value'); // ✓ works
```

***

## Related

<CardGroup cols={2}>
  <Card title="RuleEngine API" icon="gear" href="/api-reference/rule-engine">
    Engine API reference
  </Card>

  <Card title="Operators" icon="list" href="/operators/overview">
    All available operators
  </Card>

  <Card title="Examples" icon="code" href="/examples/basic-rules">
    Practical examples
  </Card>

  <Card title="Quick Start" icon="rocket" href="/quickstart">
    Get started guide
  </Card>
</CardGroup>
