npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@ivandt/json-rules

v2.2.0

Published

Rule parsing engine for JSON rules

Readme

npm version

| Statements | Functions | Lines | | --------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | Statements | Functions | Lines |

JsonRules Engine

A rule engine for JavaScript & TypeScript

Define business logic with JSON rules

TypeScript npm


Overview

JsonRules is a rule engine that allows you to define business logic as JSON and evaluate it against data. It provides a simple way to externalize decision-making logic from your application code.

Use Cases

  • E-commerce: Pricing rules, discount eligibility, shipping calculations
  • User Management: Access control, feature flags, user segmentation
  • Content: Filtering, moderation, recommendations
  • Workflows: Approval processes, notifications
  • Configuration: A/B testing, feature rollouts

Features

  • Type-safe with full TypeScript support
  • 40+ built-in operators for common operations
  • Support for complex nested conditions
  • Template variables for dynamic rules
  • Validation for rule structure and syntax
  • Works in Node.js and browsers

Installation

npm install @ivandt/json-rules

Dependencies

This library has one dependency:

  • validator - Used for advanced validation operators (email, URL, phone numbers, etc.)

Quick Start

import { JsonRules, Rule } from "@ivandt/json-rules";

// Define a rule
const rule: Rule = {
  conditions: {
    all: [
      { field: "age", operator: "is greater than or equal", value: 18 },
      { field: "country", operator: "is equal", value: "US" }
    ]
  }
};

// Evaluate against data
const user = { age: 25, country: "US" };
const result = JsonRules.evaluate(rule, user);
console.log(result); // true

Operators

JsonRules provides operators for common data operations:

Equality & Comparison

| Operator | Description | Accepts | Example | |----------|-------------|---------|---------| | is equal | Equal to | string \| number \| boolean \| Date \| null | { field: "status", operator: "is equal", value: "active" } | | is not equal | Not equal to | string \| number \| boolean \| Date \| null | { field: "status", operator: "is not equal", value: "banned" } | | is greater than | Greater than comparison | string \| number \| Date | { field: "age", operator: "is greater than", value: 18 } | | is less than | Less than comparison | string \| number \| Date | { field: "price", operator: "is less than", value: 100 } | | is greater than or equal | Greater than or equal | string \| number \| Date | { field: "score", operator: "is greater than or equal", value: 80 } | | is less than or equal | Less than or equal | string \| number \| Date | { field: "items", operator: "is less than or equal", value: 10 } |

Range & Between

| Operator | Description | Accepts | Example | |----------|-------------|---------|---------| | is between numbers | Number within range (inclusive) | [number, number] | { field: "age", operator: "is between numbers", value: [18, 65] } | | is not between numbers | Number outside range | [number, number] | { field: "temperature", operator: "is not between numbers", value: [32, 100] } | | is between dates | Date within range (inclusive) | [Date, Date] | { field: "eventDate", operator: "is between dates", value: [startDate, endDate] } | | is not between dates | Date outside range | [Date, Date] | { field: "blackoutDate", operator: "is not between dates", value: [holiday1, holiday2] } |

Collection & Array

| Operator | Description | Accepts | Example | |----------|-------------|---------|---------| | in | Value exists in array | (string \| number \| boolean \| object \| null)[] | { field: "country", operator: "in", value: ["US", "CA", "UK"] } | | not in | Value not in array | (string \| number \| boolean \| object \| null)[] | { field: "status", operator: "not in", value: ["banned", "suspended"] } | | array contains | Array field contains value | string \| number \| boolean \| object \| null | { field: "skills", operator: "array contains", value: "javascript" } | | array no contains | Array field doesn't contain value | string \| number \| boolean \| object \| null | { field: "permissions", operator: "array no contains", value: "admin" } |

String Operations

| Operator | Description | Accepts | Example | |----------|-------------|---------|---------| | contains | String contains substring | string | { field: "email", operator: "contains", value: "@company.com" } | | not contains | String doesn't contain substring | string | { field: "message", operator: "not contains", value: "spam" } | | contains any | String contains any substring | string[] | { field: "title", operator: "contains any", value: ["urgent", "critical"] } | | not contains any | String contains none of substrings | string[] | { field: "content", operator: "not contains any", value: ["spam", "scam"] } | | starts with | String starts with prefix | string | { field: "productCode", operator: "starts with", value: "PRD-" } | | ends with | String ends with suffix | string | { field: "filename", operator: "ends with", value: ".pdf" } |

Pattern Matching

| Operator | Description | Accepts | Example | |----------|-------------|---------|---------| | matches | Matches regex pattern | { regex: string, flags?: string } | { field: "email", operator: "matches", value: { regex: "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$" } } | | not matches | Doesn't match regex pattern | { regex: string, flags?: string } | { field: "username", operator: "not matches", value: { regex: "^(admin\|root)$", flags: "i" } } |

Date Operations

| Operator | Description | Accepts | Example | |----------|-------------|---------|---------| | is before | Date is before specified date | string \| number \| Date | { field: "expiry", operator: "is before", value: new Date('2024-12-31') } | | is after | Date is after specified date | string \| number \| Date | { field: "startDate", operator: "is after", value: new Date('2024-01-01') } | | is on or before | Date is on or before specified date | string \| number \| Date | { field: "deadline", operator: "is on or before", value: new Date() } | | is on or after | Date is on or after specified date | string \| number \| Date | { field: "validFrom", operator: "is on or after", value: new Date() } |

Math & Number Validation

| Operator | Description | Accepts | Example | |----------|-------------|---------|---------| | is even | Number is even | none | { field: "quantity", operator: "is even" } | | is odd | Number is odd | none | { field: "productId", operator: "is odd" } | | is positive | Number is positive (> 0) | none | { field: "balance", operator: "is positive" } | | is negative | Number is negative (< 0) | none | { field: "adjustment", operator: "is negative" } | | is empty | Value is null, undefined, or empty string/array | none | { field: "optionalField", operator: "is empty" } | | is not empty | Value is not empty | none | { field: "requiredField", operator: "is not empty" } |

Data Validation

| Operator | Description | Accepts | Example | |----------|-------------|---------|---------| | is valid email | Valid email address | EmailValidationConfig (optional) | { field: "email", operator: "is valid email" } | | is valid phone | Valid phone number | PhoneValidationConfig | { field: "phone", operator: "is valid phone", value: { locale: "us" } } | | is URL | Valid URL | URLValidationConfig | { field: "website", operator: "is URL", value: { requireTld: false } } | | is UUID | Valid UUID | UUIDValidationConfig | { field: "id", operator: "is UUID", value: { version: 4 } } | | is EAN | Valid EAN barcode | none | { field: "barcode", operator: "is EAN" } | | is IMEI | Valid IMEI number | IMEIValidationConfig | { field: "deviceId", operator: "is IMEI", value: { allowHyphens: true } } | | is unit | Valid unit of measurement | UnitType | { field: "distance", operator: "is unit", value: "length" } | | is country | Valid country identifier | CountryValidationConfig | { field: "country", operator: "is country", value: { format: "iso2" } } | | is domain | Valid domain name | DomainValidationConfig | { field: "domain", operator: "is domain", value: { requireTld: true } } |


Rule Structure

Basic Rule

interface Rule {
  conditions: Condition | Condition[];
  default?: any;
}

Conditions

Rules support three logical operators:

| Type | Logic | Description | |------|-------|-------------| | all | AND | All constraints must be true | | any | OR | At least one constraint must be true | | none | NOT | No constraints should be true |

Constraints

{
  field: string,           // Property path (supports dot notation)
  operator: string,        // Comparison operator
  value: any              // Expected value or template reference
}

Examples

Basic Example

const rule: Rule = {
  conditions: {
    all: [
      { field: "age", operator: "is greater than or equal", value: 21 },
      { field: "country", operator: "in", value: ["US", "CA"] }
    ]
  }
};

const user = { age: 25, country: "US" };
const result = JsonRules.evaluate(rule, user); // true

Complex Conditions

const complexRule: Rule = {
  conditions: {
    any: [
      {
        all: [
          { field: "membershipTier", operator: "is equal", value: "premium" },
          { field: "accountAge", operator: "is greater than", value: 365 }
        ]
      },
      {
        all: [
          { field: "totalSpent", operator: "is greater than", value: 1000 },
          { field: "lastPurchase", operator: "is after", value: new Date('2024-01-01') }
        ]
      }
    ]
  }
};

Validation Operators

const validationRule: Rule = {
  conditions: {
    all: [
      { field: "email", operator: "is valid email", value: null },
      { field: "phone", operator: "is valid phone", value: { locale: "us" } },
      { field: "website", operator: "is URL", value: { protocols: ["https"] } }
    ]
  }
};

Template Variables

const dynamicRule: Rule = {
  conditions: {
    all: [
      { field: "endDate", operator: "is after", value: "{startDate}" },
      { field: "price", operator: "is less than", value: "{maxBudget}" }
    ]
  }
};

API Reference

JsonRules.evaluate()

static evaluate<T>(
  rule: Rule, 
  criteria: object | object[], 
  trustRule?: boolean
): T | boolean

JsonRules.validate()

static validate(rule: Rule): ValidationResult

ValidationResult

interface ValidationResult {
  isValid: boolean;
  error?: ValidationError;
}

Phone Number Validation

To use phone validation, import the specific locale validators:

// Import specific locales
import "@ivandt/json-rules/validators/phone/us";
import "@ivandt/json-rules/validators/phone/gb";
import "@ivandt/json-rules/validators/phone/de";

const rule: Rule = {
  conditions: {
    all: [
      { field: "phone", operator: "is valid phone", value: { locale: "us" } }
    ]
  }
};

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/new-feature
  3. Make your changes with tests
  4. Run the test suite: npm test
  5. Submit a pull request

License

MIT License - see LICENSE file for details.