New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@infitx/decision

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@infitx/decision

Decision tables engine

latest
Source
npmnpm
Version
1.4.4
Version published
Maintainers
1
Created
Source

Decision Library

A lightweight rule engine for evaluating facts against configurable rules and generating decisions. The library uses pattern matching to determine which rules apply to a given fact and returns corresponding decisions.

Features

  • Pattern Matching: Uses @infitx/match for flexible fact matching
  • Priority-based Evaluation: Rules can have explicit or implicit priorities
  • Multiple Decision Support: Can return first match or all matching rules
  • YAML Configuration: Define rules in human-readable YAML format
  • Type Safety: Built-in support for various data types including dates and timestamps

Installation

const decision = require('./');

Basic Usage

const decision = require('./');
const { decide, rules } = decision('./config.yaml');

const fact = { type: 'transfer', amount: 500 };
const result = decide(fact);
console.log(result);

Examples

Example 1: Single Decision with Implicit Priority

Rules are evaluated in the order they appear in the configuration. When rules are defined as an object, the key becomes the rule name and serves as the implicit priority (alphabetically sorted).

    • YAML Configuration
    rules:
      transfer-approval:
        when: { type: transfer, amount: { max: 1000 } }
        then: { expect: { approved: true, reason: approved } }
    
      transfer-rejection:
        when: { type: transfer, amount: { min: 1001 } }
        then: { expect: { approved: false, reason: limit } }
    
  • Decision Table

    RuleConditionDecision
    transfer-approvaltype=transfer AND amount ≤ 1000expect: approved=true, reason=approved
    transfer-rejectiontype=transfer AND amount ≥ 1001expect: approved=false, reason=limit
  • Code Example

    const decision = require('./');
    const { decide } = decision('./transfer-config.yaml');
    
    // Test case 1: Approved transfer
    const fact1 = { type: 'transfer', amount: 500 };
    console.log(decide(fact1));
    // Output: [{
    //    rule: 'transfer-approval',
    //    decision: 'expect',
    //    approved: true,
    //    reason: 'approved'
    //  }]
    
    // Test case 2: Rejected transfer
    const fact2 = { type: 'transfer', amount: 1500 };
    console.log(decide(fact2));
    // Output: [{
    //    rule: 'transfer-rejection',
    //    decision: 'expect',
    //    approved: false,
    //    reason: 'limit'
    //  }]
    

Example 2: Single Decision with Explicit Priority

When you need specific evaluation order, pass an array of rules with the required order.

  • YAML Configuration

    rules:
      - rule: high-value-check
        when: { type: transaction, amount: { min: 10000 } }
        then: { require: { manualReview: true, approvers: 2 } }
    
      - rule: standard-check
        when: { type: transaction, amount: { max: 9999 } }
        then: { allow: { automated: true, approvers: 0 } }
    
  • Decision Table

    RuleConditionDecision
    high-value-checktype=transaction AND amount ≥ 10000require: manualReview=true, approvers=2
    standard-checktype=transaction AND amount ≤ 9999allow: automated=true, approvers=0
  • Code Example

    const decision = require('./');
    const { decide, rules } = decision('./priority-config.yaml');
    
    console.log('Rules in evaluation order:', rules.map(r => ({ rule: r.rule })));
    // Output: [
    //   { rule: 'high-value-check' },
    //   { rule: 'standard-check }
    // ]
    
    const fact1 = { type: 'transaction', amount: 15000 };
    console.log(decide(fact1));
    // Output: [{
    //    rule: 'high-value-check',
    //    decision: 'require',
    //    manualReview: true,
    //    approvers: 2
    // }]
    
    const fact2 = { type: 'transaction', amount: 500 };
    console.log(decide(fact2));
    // Output: [{
    //    rule: 'standard-check',
    //    decision: 'allow',
    //    automated: true,
    //    approvers: 0
    // }]
    

Example 3: Multiple Decisions

A single fact can trigger multiple decisions from one rule. This is useful for scenarios where you need to take multiple actions based on a single condition.

  • YAML Configuration

    rules:
      withdrawal-high-amount:
        when: { type: withdrawal, amount: { min: 501 } }
        then:
          expect: { approved: false, reason: large }
          notification: { type: alert, recipient: manager }
          audit: { level: warning, message: "Large withdrawal attempted" }
    
      withdrawal-normal:
        when: { type: withdrawal, amount: { max: 500 } }
        then:
          expect: { approved: true, reason: small }
          audit: { level: info, message: "Withdrawal approved" }
    
  • Decision Table

    RuleConditionDecisions
    withdrawal-high-amounttype=withdrawal AND amount ≥ 5011. expect: approved=false, reason=large
    2. notification: type=alert, recipient=manager
    3. audit: level=warning, message=...
    withdrawal-normaltype=withdrawal AND amount ≤ 5001. expect: approved=true, reason=small
    2. audit: level=info, message=...
  • Code Example

    const decision = require('./');
    const { decide } = decision('./withdrawal-config.yaml');
    
    // Large withdrawal - triggers multiple decisions
    const fact1 = { type: 'withdrawal', amount: 700 };
    console.log(decide(fact1));
    // Output: [
    //   {
    //        rule: 'withdrawal-high-amount',
    //        decision: 'expect',
    //        approved: false,
    //        reason: 'large'
    //   }, {
    //        rule: 'withdrawal-high-amount',
    //        decision: 'notification',
    //        type: 'alert',
    //        recipient: 'manager'
    //   }, {
    //        rule: 'withdrawal-high-amount',
    //        decision: 'audit',
    //        level: 'warning',
    //        message: 'Large withdrawal attempted'
    //   }
    // ]
    
    // Normal withdrawal
    const fact2 = { type: 'withdrawal', amount: 300 };
    console.log(decide(fact2));
    // Output: [
    //   {
    //        rule: 'withdrawal-normal',
    //        decision: 'expect',
    //        approved: true,
    //        reason: 'small'
    //   }, {
    //        rule: 'withdrawal-normal',
    //        decision: 'audit',
    //        level: 'info',
    //        message: 'Withdrawal approved'
    //   }
    // ]
    

Example 4: All Matching Rules

By default, decide() returns only the first matching rule. Use the all parameter to get all matching rules.

  • YAML Configuration

    rules:
      fraud-check:
        when: { type: transaction, amount: { min: 5000 } }
        then: { verify: { fraudCheck: true } }
    
      compliance-check:
        when: { type: transaction, amount: { min: 3000 } }
        then: { verify: { amlCheck: true } }
    
      standard-process:
        when: { type: transaction }
        then: { process: { standard: true } }
    
  • Decision Table

    RuleConditionDecision
    fraud-checktype=transaction AND amount ≥ 5000verify: fraudCheck=true
    compliance-checktype=transaction AND amount ≥ 3000verify: amlCheck=true
    standard-processtype=transactionprocess: standard=true
  • Code Example

    const decision = require('./');
    const { decide } = decision('./all-rules-config.yaml');
    
    const fact = { type: 'transaction', amount: 6000 };
    
    // Get only first matching rule (default)
    console.log(decide(fact));
    // Output: [{ rule: 'fraud-check', decision: 'verify', fraudCheck: true }]
    
    // Get all matching rules
    console.log(decide(fact, true));
    // Output: [
    //   { rule: 'fraud-check', decision: 'verify', fraudCheck: true },
    //   { rule: 'compliance-check', decision: 'verify', amlCheck: true },
    //   { rule: 'standard-process', decision: 'process', standard: true }
    // ]
    

YAML Configuration Format

Basic Structure

rules:
  rule-name:
    when: <condition>
    then: <decision>
    priority: <number or string>  # Optional, defaults to rule name if omitted

Or as an array:

rules:
  - rule: rule-name
    when: <condition>
    then: <decision>

Components

  • rules

Can be either:

  • Object: Keys are rule names, values are rule definitions. Rules are sorted alphabetically by name (implicit priority) or by priority field if present.

  • Array: Rules definitions with explicit order. When an array is used, the processing order is the order of items in the array.

  • when (Condition)

A pattern matching object that defines when a rule applies. Supports:

  • Exact match: { type: transfer }

  • Range match: { amount: { min: 100, max: 1000 } }

  • Minimum: { amount: { min: 1000 } }

  • Maximum: { amount: { max: 1000 } }

  • Complex patterns: Nested objects, arrays, and any pattern supported by @infitx/match

  • then (Decision)

Defines the outcomes when a rule matches. Structure:

then:
  <decision-type>: <decision-value>
  <another-decision>: <another-value>

Each decision becomes an object in the result array:

{ rule: 'rule-name', decision: 'decision-type', ...decision-value }
  • priority (Optional)

  • Numeric: Lower numbers evaluated first

  • String: Lexicographic ordering

  • Implicit: If omitted, rule name is used as priority

Complete Example

# Object format with implicit priority
rules:
  high-priority-rule:
    when: { urgent: true }
    then: { action: { escalate: true } }

  low-priority-rule:
    when: { urgent: false }
    then: { action: { queue: true } }

---

# Array format with explicit priority
rules:
  - rule: critical
    when: { severity: critical }
    then:
      alert: { immediate: true }
      notify: { team: on call }
  - rule: warning
    when: { severity: warning }
    then:
      alert: { delayed: true }
  - rule: info
    when: { severity: info }
    then:
      log: { level: info }

API Reference

decision(config)

Creates a decision engine instance.

Parameters:

  • config (String | Object): Path to YAML file or configuration object

Returns: Object with:

  • rules: Array of rules in evaluation order
  • decide(fact, all): Function to evaluate facts
  • tests: Test cases from configuration (if present)

decide(fact, all = false)

Evaluates a fact against configured rules.

Parameters:

  • fact (Object): The fact to evaluate
  • all (Boolean): If true, returns all matching rules; if false, returns only first match

Returns: Array of decision objects:

[
  { rule: 'rule-name', decision: 'decision-type', ...decision-value }
]

Returns null (or empty array if all=true) if no rules match.

Testing

The library supports inline test definitions in YAML:

rules:
  # ... rule definitions

tests:
  - fact: { type: transfer, amount: 500 }
    expected:
      - approved: true
        reason: approved
        rule: transfer-approval
        decision: expect

Run tests with Jest:

const decision = require('./');
const { decide, tests } = decision('./config.yaml');

tests.forEach(({ fact, expected }) => {
  test(`fact: ${JSON.stringify(fact)}`, () => {
    expect(decide(fact)).toEqual(expected);
  });
});

FAQs

Package last updated on 14 Mar 2026

Did you know?

Socket

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.

Install

Related posts