
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@ivandt/json-rules
Advanced tools
| Statements | Functions | Lines |
|---|---|---|
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.
npm install @ivandt/json-rules
This library has one dependency:
validator - Used for advanced validation operators (email, URL, phone numbers, etc.)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
JsonRules provides operators for common data operations:
| 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 } |
| 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] } |
| 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" } |
| 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" } |
| 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" } } |
| 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() } |
| 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" } |
| 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 } } |
interface Rule {
conditions: Condition | Condition[];
default?: any;
}
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 |
{
field: string, // Property path (supports dot notation)
operator: string, // Comparison operator
value: any // Expected value or template reference
}
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
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') }
]
}
]
}
};
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"] } }
]
}
};
const dynamicRule: Rule = {
conditions: {
all: [
{ field: "endDate", operator: "is after", value: "{startDate}" },
{ field: "price", operator: "is less than", value: "{maxBudget}" }
]
}
};
static evaluate<T>(
rule: Rule,
criteria: object | object[],
trustRule?: boolean
): T | boolean
static validate(rule: Rule): ValidationResult
interface ValidationResult {
isValid: boolean;
error?: ValidationError;
}
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" } }
]
}
};
git checkout -b feature/new-featurenpm testMIT License - see LICENSE file for details.
FAQs
Rule parsing engine for JSON rules
We found that @ivandt/json-rules demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.