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 🙏

© 2024 – Pkg Stats / Ryan Hefner

kenolo

v2.2.2

Published

A lightweight JSON-based business rules engine

Downloads

8

Readme

KENOLO KENOLO

A lightweight JSON-based business rules engine

npm version

Consider Using KENOLO, If:

  • You want non-programmers to be able to understand and modify the rules themselves
    KENOLO ruleset is simple yet powerful thanks to the operators which are supported
  • You need to apply different rules and conditions per environment
    Use npm configuration packages, such as config or nconf, to store your ruleset per environment.
  • Rules are frequently changed, but you strive to keep source code modifications and consequently tedious QA cycles to the minimum
    Simply modify an external JSON file to update your ruleset.
  • Security, size & performance concern you
    KENOLO is a 22KB eval-free npm package.

Installation

npm i kenolo -S

Ruleset Structure

{
  "NAME_OF_RULE_1": {
    // mandatory - object of one or more conditions to check whether rule should apply:
    "include":
      // condition 1:
      { "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "eq", "value": "VALUE_TO_COMPARE_WITH" },
    // optional - object of one or more conditions to check whether rule should NOT apply:
    "exclude": {
      // array of conditions which should all be truthy for rule to apply:
      "and": [
        // condition 1:
        { "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "gt", "value": "VALUE_TO_COMPARE_WITH" },
        // condition 2:
        { "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "neq", "value": "VALUE_TO_COMPARE_WITH" },
        // more conditions:
        //...
      ],
      // array of conditions from which at least one of them should be truthy for rule to apply:
      "or": [
        // condition 1:
        { "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "eq", "value": "VALUE_TO_COMPARE_WITH" },
        // condition 2:
        { "name": "CONDITION_NAME", "property": "PROPERTY_PATH_TO_EXTRACT_DATA_FROM", "operator": "eq", "value": "VALUE_TO_COMPARE_WITH" },
        // more conditions:
        //...
      ]
    }
  },
  "NAME_OF_RULE_2": {
    "include": [
      // ...
    ]
  }
}

Basic Example

const kenolo = require('kenolo');

const data = {
  order: {
    status: 2,
    user: {
      email: '[email protected]'
    }
  }
};

const SHOULD_REVIEW = {
  include: {
    and: [
      { name: 'STATUS_PENDING', property: 'order.status', operator: 'eq', value: 2 },
      {
        or: [
          { name: 'HIGH_RISK_USER_EMAILS', property: 'order.user.email', operator: 'in', value: ['[email protected]', '[email protected]'] },
          { name: 'MAX_PRICE_EXCEEDED', property: 'order.price', operator: 'gt', value: 500 }
        ]
      }
    ]
  }
};

kenolo(SHOULD_REVIEW, data);
// -> { apply: true, conditions: [ 'STATUS_PENDING', 'HIGH_RISK_USER_EMAILS' ] }

See tests directory for more examples

Response Object

{
  // {Boolean} apply - Should rule apply?
  apply: true,
  // {String[]} conditions - Truthy condition names
  conditions: ['CONDITION_NAME_1', 'CONDITION_NAME_2']
}

Supported Operators

  • ex - Property exists
    { "property": "a", "operator": "ex" }

  • nex - Property doesn't exists
    { "property": "a", "operator": "nex" }

  • eq - Equals to (a single value)
    { "property": "a", "operator": "eq", "value": "a" }

  • neq - Not equals to (a single value)
    { "property": "a", "operator": "neq", "value": "b" }

  • weq - Weak equals to (a single value)
    { "property": "2", "operator": "weq", "value": 2 }

  • nweq - Not weak equals to (a single value)
    { "property": "a", "operator": "nweq", "value": "b" }

  • in - In (an array of values)
    { "property": "a", "operator": "in", "value": ["a", "b", "c"] }

  • nin - Not in (an array of values)
    { "property": "d", "operator": "nin", "value": ["a", "b", "c"] }

  • gt - Greater than (a single value)
    { "property": 100, "operator": "gt", "value": 80 }

  • gte - Greater than or equals to (a single value)
    { "property": 100, "operator": "gte", "value": 100 }

  • lt - Lower than (a single value)
    { "property": 100, "operator": "lt", "value": 120 }

  • lte - Lower than or equals to (a single value)
    { "property": 100, "operator": "lte", "value": 100 }

  • sw - Starts with (an array of values)
    { "property": "+1 40 9871625", "operator": "sw", "value": ["+1", "+40"] }

  • nsw - Not starts with (an array of values)
    { "property": "+1 40 9871625", "operator": "nsw", "value": ["+1", "+40"] }

  • ew - Ends with (an array of values)
    { "property": "[email protected]", "operator": "ew", "value": ["@hacker.com", "@hazard.com"] }

  • new - Not ends with (an array of values)
    { "property": "[email protected]", "operator": "new", "value": ["@hacker.com", "@hazard.com"] }

  • inc - Includes (an array of values)
    { "property": "John", "operator": "inc", "value": ["oh", "bla"] }

  • ninc - Not includes (an array of values)
    { "property": "John", "operator": "ninc", "value": ["oh", "bla"] }

  • sl - Sounds like (an array of values)
    { "property": "John", "operator": "sl", "value": ["Jon", "David"] }

  • re - Regular expression (an array of values)
    { "property": "New York", "operator": "re", "value": [/New/i] }
    { "property": "New York", "operator": "re", "value": ["\\w+"] }

Array properties

  • some - Some are included (an array of values)
    { "property": [1, 2, 3], "operator": "some", "value": [1, 5, 8] }
  • every - All are included (an array of values)
    { "property": [1, 2, 3], "operator": "every", "value": [1, 2, 3, 4, 5] }
  • none - None are included (an array of values)
    { "property": [1, 2, 3], "operator": "none", "value": [4, 5, 7, 8] }