{"id":22944701,"url":"https://github.com/erdemkosk/obey-the-rule","last_synced_at":"2025-08-12T22:32:35.813Z","repository":{"id":237746196,"uuid":"795164319","full_name":"erdemkosk/obey-the-rule","owner":"erdemkosk","description":"A lightweight rule engine implemented in TypeScript for managing conditional logic and automating decision-making processes.","archived":false,"fork":false,"pushed_at":"2024-05-04T19:17:33.000Z","size":299,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-21T21:12:30.250Z","etag":null,"topics":["json","rule-based","rule-engine","rules-engine","typescript","typescript-library"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/obey-the-rule","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erdemkosk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-02T17:52:17.000Z","updated_at":"2024-07-26T01:32:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"95b3bdb0-c8bc-472b-8c73-6ede572ab49e","html_url":"https://github.com/erdemkosk/obey-the-rule","commit_stats":null,"previous_names":["erdemkosk/obey-the-rule"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erdemkosk%2Fobey-the-rule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erdemkosk%2Fobey-the-rule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erdemkosk%2Fobey-the-rule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erdemkosk%2Fobey-the-rule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erdemkosk","download_url":"https://codeload.github.com/erdemkosk/obey-the-rule/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229711908,"owners_count":18112214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","rule-based","rule-engine","rules-engine","typescript","typescript-library"],"created_at":"2024-12-14T14:19:49.240Z","updated_at":"2024-12-14T14:19:49.707Z","avatar_url":"https://github.com/erdemkosk.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🫡 Obey The Rule\n\n![Logo](https://i.imgur.com/bC7sXDJ.png)\n\nThis project includes a minimalist rule engine implemented in TypeScript. It provides a lightweight solution for managing conditional logic and automating decision-making processes.\n\nThe and and or keys are used within the conditions object to combine specific conditions.\n\nand: This key indicates that all specified conditions must be met simultaneously. When and is used, all conditions in the list must be true for the entire expression to be true. If any single condition is false, the entire expression is considered false.\nor: This key indicates that at least one condition in the list must be true. When or is used, the expression is considered true if at least one condition in the list evaluates to true. Even if all other conditions are false, as long as one condition is true, the entire expression is true.\nThese keys are used to specify complex conditions. For example, they can be used to define a rule that must meet a specific condition and at the same time meet another condition or meet any of several other conditions. This allows rules to accommodate a wide range of scenarios.\n\n### How to install\n\n```bash\nnpm i obey-the-rule\n```\n\nIt is currently supported esm and common js.\n\n### Usage\n\nEsm:\n\n```typescript\nimport { RuleEngine, Operator } from 'obey-the-rule';\n```\n\nCommon Js:\n\n```typescript\nconst { RuleEngine, Operator } = require('obey-the-rule');\n```\n\n### Operator Types\n\n```typescript\nexport enum Operator {\n  /** Strict equal operator, checks if the values are exactly equal using strict comparison (===). */\n  STRICT_EQUAL = 'strictEqual',\n\n  /** Strict not equal operator, checks if the values are not equal using strict comparison (!==). */\n  STRICT_NOT_EQUAL = 'strictNotEqual',\n\n  /** Loose equal operator, checks if the values are equal using loose comparison (==). */\n  LOOSE_EQUAL = 'looseEqual',\n\n  /** Loose not equal operator, checks if the values are not equal using loose comparison (!=). */\n  LOOSE_NOT_EQUAL = 'looseNotEqual',\n\n  /** Greater than operator, checks if the value is greater than the comparison value. */\n  GREATER_THAN = 'greaterThan',\n\n  /** Less than operator, checks if the value is less than the comparison value. */\n  LESS_THAN = 'lessThan',\n\n  /** Greater than or equal operator, checks if the value is greater than or equal to the comparison value. */\n  GREATER_THAN_OR_EQUAL = 'greaterThanOrEqual',\n\n  /** Less than or equal operator, checks if the value is less than or equal to the comparison value. */\n  LESS_THAN_OR_EQUAL = 'lessThanOrEqual',\n\n  /** Contains operator, checks if the value contains the comparison value. */\n  CONTAINS = 'contains',\n\n  /** Not contains operator, checks if the value does not contain the comparison value. */\n  NOT_CONTAINS = 'notContains',\n\n  /** Starts with operator, checks if the value starts with the comparison value. */\n  STARTS_WITH = 'startsWith',\n\n  /** Ends with operator, checks if the value ends with the comparison value. */\n  ENDS_WITH = 'endsWith',\n\n  /** Regular expression match operator, checks if the value matches the provided regular expression. */\n  REGEX_MATCH = 'regexMatch',\n\n  /** Regular expression not match operator, checks if the value does not match the provided regular expression. */\n  REGEX_NOT_MATCH = 'regexNotMatch',\n\n  /** Check inside of value operator. It will check array is containts this value */\n  ARRAY_CONTAINS = 'arrayContains',\n\n  /** Array operator it will foreach all values */\n  EACH = 'each',\n}\n```\n\n## Warning\n\nThis project is currently in an early development stage\n\n## License\n\nLicensed under the APLv2. See the [LICENSE](https://github.com/erdemkosk/obey-the-rule/blob/master/LICENSE) file for details.\n\n### Basic Usage With constant\n\n```typescript\n// Example usage:\nimport { RuleEngine, Operator } from 'obey-the-rule';\nconst functions = {\n  helloWorld: helloWorld,\n};\n\nexport async function helloWorld(): Promise\u003cany\u003e {\n  console.log('Hello World');\n}\n\nconst testValue = 'This';\n\n// Example usage:\nconst engine = new RuleEngine(functions);\n\n//success rule example\nengine.addRule({\n  conditions: {\n    and: [\n      {\n        constant: testValue,\n        operator: Operator.STRICT_EQUAL,\n        value: 'This',\n      },\n    ],\n  },\n  after: {\n    func: 'helloWorld',\n    params: {\n      message: 'Rule work with success!',\n      success: true,\n    },\n  },\n});\n\nconst result: Result[] = await engine.obey();\n\nconsole.log(JSON.stringify(result));\n\n//Hello World\n//[{\"rule\":{\"conditions\":{\"and\":[{\"constant\":\"This\",\"operator\":\"strictEqual\",\"value\":\"This\"}]},\"after\":{\"func\":\"helloWorld\",\"params\":{\"message\":\"Rule work with success!\",\"success\":true}}},\"satisfied\":true}]\n```\n\n### Example Usage Add rule and Add rules\n\n```typescript\nconst functions = {\n  getCourier: getCourier,\n  logCourierInfo: logCourierInfo,\n};\n\nexport async function getCourier(params: any): Promise\u003cany\u003e {\n  return {\n    id: params?.courierId,\n    status: 200,\n    vehicle: 'Bike',\n    courierInfo: {\n      name: 'John Doe',\n      warehouse: 'Izmir',\n    },\n  };\n}\n\nexport async function logCourierInfo(courier: any, params: any): Promise\u003cany\u003e {\n  console.log(\n    JSON.stringify(\n      {\n        courierInfo: {\n          status: courier.status,\n          vehicle: courier.vehicle,\n        },\n        params,\n      },\n      null,\n      2,\n    ),\n  );\n}\n```\n\n```typescript\n// Example usage:\nimport { RuleEngine, Operator } from 'obey-the-rule';\n\nconst engine = new RuleEngine(functions);\n\n//success rule example\nengine.addRule({\n  before: {\n    func: 'getCourier',\n    params: {\n      courierId: '6633d4699c759c778ab5b399',\n    },\n  },\n  conditions: {\n    and: [\n      {\n        fact: 'status',\n        operator: Operator.STRICT_EQUAL,\n        value: 200,\n      },\n    ],\n    or: [\n      {\n        fact: 'vehicle',\n        operator: Operator.STRICT_EQUAL,\n        value: 'Bike',\n      },\n      {\n        fact: 'vehicle',\n        operator: Operator.STRICT_EQUAL,\n        value: 'Car',\n      },\n    ],\n  },\n  after: {\n    func: 'logCourierInfo',\n    params: {\n      message: 'Rule work with success!',\n      success: true,\n    },\n  },\n});\n\n//failed rule example\nengine.addRule({\n  before: {\n    func: 'getCourier',\n    params: {\n      courierId: '6633d4699c759c778ab5b399',\n    },\n  },\n  conditions: {\n    and: [\n      {\n        fact: 'status',\n        operator: Operator.STRICT_EQUAL,\n        value: 400,\n      },\n    ],\n  },\n  after: {\n    func: 'logCourierInfo',\n    params: {\n      message: 'Rule work with success!',\n      success: true,\n    },\n  },\n});\n\n// Adding multiple rules at once\nengine.addRules([\n  {\n    before: {\n      func: 'getCourier',\n      params: {\n        courierId: '6633d4699c759c778ab5b399',\n      },\n    },\n    conditions: {\n      and: [\n        {\n          fact: 'status',\n          operator: Operator.STRICT_EQUAL,\n          value: 200,\n        },\n      ],\n      or: [\n        {\n          fact: 'vehicle',\n          operator: Operator.STRICT_EQUAL,\n          value: 'Bike',\n        },\n        {\n          fact: 'vehicle',\n          operator: Operator.STRICT_EQUAL,\n          value: 'Car',\n        },\n      ],\n    },\n    after: {\n      func: 'logCourierInfo',\n      params: {\n        message: 'Rule work with success!',\n        success: true,\n      },\n    },\n  },\n\n  {\n    before: {\n      func: 'getCourier',\n      params: {\n        courierId: '6633d4699c759c778ab5b399',\n      },\n    },\n    conditions: {\n      and: [\n        {\n          fact: 'status',\n          operator: Operator.STRICT_EQUAL,\n          value: 400,\n        },\n      ],\n    },\n    after: {\n      func: 'logCourierInfo',\n      params: {\n        message: 'Rule work with success!',\n        success: true,\n      },\n    },\n  },\n]);\n\nconst result: Result[] = await engine.obey();\n\n//[{\"rule\":{\"before\":{\"func\":\"getCourier\",\"params\":{\"courierId\":\"6633d4699c759c778ab5b399\"}},\"conditions\":{\"and\":[{\"fact\":\"status\",\"operator\":\"strictEqual\",\"value\":200}],\"or\":[{\"fact\":\"vehicle\",\"operator\":\"strictEqual\",\"value\":\"Bike\"},{\"fact\":\"vehicle\",\"operator\":\"strictEqual\",\"value\":\"Car\"}]},\"after\":{\"func\":\"logCourierInfo\",\"params\":{\"message\":\"Rule work with success!\",\"success\":true}}},\"satisfied\":true},{\"rule\":{\"before\":{\"func\":\"getCourier\",\"params\":{\"courierId\":\"6633d4699c759c778ab5b399\"}},\"conditions\":{\"and\":[{\"fact\":\"status\",\"operator\":\"strictEqual\",\"value\":400}]},\"after\":{\"func\":\"logCourierInfo\",\"params\":{\"message\":\"Rule work with success!\",\"success\":true}}},\"satisfied\":false,\"reason\":\"Conditions not met\"}]\n```\n\n### Array and Inner Values\n\n$ it is represent current value\n\n```typescript\nengine.addRule({\n  before: {\n    func: 'getOrder',\n    params: {\n      orderId: '6633d4699c759c778ab5b399',\n    },\n  },\n  conditions: {\n    and: [\n      {\n        fact: 'basket.missingItems.array',\n        operator: Operator.EACH,\n        value: {\n          fact: '$',\n          operator: Operator.GREATER_THAN,\n          value: 0,\n        },\n      },\n    ],\n  },\n  after: {\n    func: 'logOrderInfo',\n    params: {\n      message: 'Rule work with success!',\n      success: true,\n    },\n  },\n});\n```\n\nFor more detail you can see [examples](https://github.com/erdemkosk/obey-the-rule/blob/master/examples) 🤓\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferdemkosk%2Fobey-the-rule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferdemkosk%2Fobey-the-rule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferdemkosk%2Fobey-the-rule/lists"}