{"version":3,"sources":["../src/index.ts","../src/Operator.ts","../src/RuleEngine.ts"],"sourcesContent":["'use strict';\n\nimport { Result } from './IResult.js';\nimport { Operator } from './Operator.js';\nimport { RuleEngine } from './RuleEngine.js';\n\nexport { RuleEngine, Operator, Result };\n","/**\n * Enum for condition operators in rule conditions.\n * These operators are used to define the type of comparison that should be applied\n * to a fact in a rule's condition.\n *\n * @enum {string}\n */\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","/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Rule } from './IRule.js';\nimport { Condition } from './ICondition.js';\nimport { Action } from './IAction.js';\nimport { Operator } from './Operator.js';\nimport { Result } from './IResult.js';\nimport _ from 'lodash';\n\n/**\n * Rule engine class to manage and execute rules.\n */\nexport class RuleEngine {\n  rules: Rule[];\n  functions: any;\n\n  /**\n   * Creates an instance of a RuleEngine.\n   * @param {any} functions - An object containing functions that can be called by the rule engine.\n   */\n  constructor(functions: any) {\n    this.rules = [];\n    this.functions = functions;\n  }\n\n  /**\n   * Adds a rule to the rule engine.\n   * @param {Rule} rule - The rule to add.\n   */\n  public addRule(rule: Rule): void {\n    this.rules.push(rule);\n  }\n\n  /**\n   * Adds a rules to the rule engine.\n   * @param {Rule[]} rules - The rules to add.\n   */\n  public addRules(rules: Rule[]): void {\n    this.rules.push(...rules);\n  }\n\n  /**\n\n  /**\n   * Evaluates all added rules in sequence and returns an array of objects containing\n   * information about whether each rule's conditions are met and the reason if not.\n   * @returns {Promise<Result[]>} - An array of objects containing information\n   * about whether each rule's conditions are met and the reason if not.\n   */\n  public async obey(): Promise<Result[]> {\n    const results: Result[] = [];\n\n    for (const rule of this.rules) {\n      const result = await this.obeyRule(rule);\n      results.push(result);\n    }\n\n    return results;\n  }\n\n  private async obeyRule(rule: Rule): Promise<Result> {\n    try {\n      let beforeResult: any = null;\n\n      if (rule.before) {\n        beforeResult = await this.callFunction(rule.before);\n      }\n\n      const satisfied = this.evaluateConditions(rule.conditions, beforeResult);\n      const result: Result = {\n        rule,\n        satisfied,\n        reason: satisfied ? undefined : 'Conditions not met',\n      };\n\n      if (satisfied && rule.after) {\n        await this.callFunction(rule.after, beforeResult);\n      }\n\n      return result;\n    } catch (error) {\n      return {\n        rule,\n        satisfied: false,\n        reason: `An error occurred: ${error.message}`,\n      };\n    }\n  }\n\n  /**\n   * Evaluates the conditions of a rule.\n   * @param {Rule['conditions']} conditions - The conditions to evaluate.\n   * @param {any} value - The result from the 'before' function, used for condition evaluation.\n   * @returns {boolean} - True if conditions are met, otherwise false.\n   */\n  private evaluateConditions(\n    conditions: Rule['conditions'],\n    value?: any,\n  ): boolean {\n    let status = false;\n\n    if ('and' in conditions) {\n      status = conditions.and.every((condition) =>\n        this.evaluateSingleCondition(condition, value),\n      );\n    }\n\n    if ('or' in conditions) {\n      status = conditions.or.some((condition) =>\n        this.evaluateSingleCondition(condition, value),\n      );\n    }\n\n    return status;\n  }\n\n  /**\n   * Evaluates a single condition against the provided value.\n   * @param {Condition} condition - The condition to evaluate.\n   * @param {any} value - The value to check the condition against.\n   * @returns {boolean} - True if the condition is met, otherwise false.\n   */\n  private evaluateSingleCondition(condition: Condition, value?: any): boolean {\n    if (!value && !condition.constant) {\n      throw Error(`Value does not contain '${condition.fact}'.`);\n    }\n\n    let factValue;\n\n    if (condition.fact === '$') {\n      factValue = value;\n    } else if (condition.constant) {\n      factValue = condition.constant;\n    } else {\n      const factExpression = condition.fact.split('.');\n      factValue = this.getValueFromFactExpression(factExpression, value);\n    }\n\n    switch (condition.operator) {\n      case Operator.LOOSE_EQUAL:\n        return factValue == condition.value;\n      case Operator.STRICT_EQUAL:\n        return factValue === condition.value;\n      case Operator.LOOSE_NOT_EQUAL:\n        return factValue != condition.value;\n      case Operator.STRICT_NOT_EQUAL:\n        return factValue !== condition.value;\n      case Operator.GREATER_THAN:\n        return factValue > condition.value;\n      case Operator.LESS_THAN:\n        return factValue < condition.value;\n      case Operator.GREATER_THAN_OR_EQUAL:\n        return factValue >= condition.value;\n      case Operator.LESS_THAN_OR_EQUAL:\n        return factValue <= condition.value;\n      case Operator.CONTAINS:\n        if (Array.isArray(factValue) || typeof factValue === 'string') {\n          return factValue.includes(condition.value);\n        } else {\n          throw new Error(\n            `Invalid data type for ${condition.fact}. Expected array or string.`,\n          );\n        }\n      case Operator.NOT_CONTAINS:\n        if (Array.isArray(factValue) || typeof factValue === 'string') {\n          return !factValue.includes(condition.value);\n        } else {\n          throw new Error(\n            `Invalid data type for ${condition.fact}. Expected array or string.`,\n          );\n        }\n      case Operator.STARTS_WITH:\n        if (typeof factValue === 'string') {\n          return factValue.startsWith(condition.value);\n        } else {\n          throw new Error(\n            `Invalid data type for ${condition.fact}. Expected string.`,\n          );\n        }\n      case Operator.ENDS_WITH:\n        if (typeof factValue === 'string') {\n          return factValue.endsWith(condition.value);\n        } else {\n          throw new Error(\n            `Invalid data type for ${condition.fact}. Expected string.`,\n          );\n        }\n      case Operator.REGEX_MATCH:\n        if (typeof factValue === 'string') {\n          const regex = new RegExp(condition.value);\n          return regex.test(factValue);\n        } else {\n          throw new Error(\n            `Invalid data type for ${condition.fact}. Expected string.`,\n          );\n        }\n      case Operator.REGEX_NOT_MATCH:\n        if (typeof factValue === 'string') {\n          const regex = new RegExp(condition.value);\n          return !regex.test(factValue);\n        } else {\n          throw new Error(\n            `Invalid data type for ${condition.fact}. Expected string.`,\n          );\n        }\n      case Operator.ARRAY_CONTAINS:\n        if (Array.isArray(factValue)) {\n          return factValue.some((item) => item === condition.value);\n        } else {\n          throw new Error(\n            `Invalid data type for ${condition.fact}. Expected array.`,\n          );\n        }\n      case Operator.EACH:\n        if (Array.isArray(factValue)) {\n          return factValue.every((item) =>\n            this.evaluateSingleCondition(condition.value, item),\n          );\n        } else {\n          throw new Error(\n            `Invalid data type for ${condition.fact}. Expected array.`,\n          );\n        }\n\n      default:\n        throw new Error(`Invalid operator: ${condition.operator}`);\n    }\n  }\n\n  private getValueFromFactExpression(\n    factExpression: string[],\n    value: any,\n  ): any {\n    const path = factExpression.map((segment) =>\n      segment.replace(/\\[(\\d+)\\]/g, '[$1]'),\n    );\n    return _.get(value, path.join('.'));\n  }\n\n  /**\n   * Calls a function defined in the functions object.\n   * @param {Action} action - The action to perform which includes the function name and parameters.\n   * @param {any} beforeResult - The result from the 'before' function that can be passed to the 'after' function.\n   * @returns {Promise<any>} - The result of the function call.\n   */\n  private async callFunction(action: Action, beforeResult?: any): Promise<any> {\n    if (\n      action.func in this.functions &&\n      typeof this.functions[action.func] === 'function'\n    ) {\n      return await this.functions[action.func](beforeResult, action.params);\n    } else {\n      throw Error(`Function '${action.func}' not found or not a function.`);\n    }\n  }\n}\n"],"mappings":"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","names":["Operator","_"]}