UNPKG

js-feel

Version:

FEEL(Friendly Enough Expression Language) based on DMN specification 1.1 for conformance level 3

194 lines (133 loc) 6.13 kB
[![Build Status](https://travis-ci.org/EdgeVerve/feel.svg?branch=master)](https://travis-ci.org/EdgeVerve/feel) [![Coverage Status](https://coveralls.io/repos/github/EdgeVerve/feel/badge.svg?branch=master)](https://coveralls.io/github/EdgeVerve/feel?branch=master) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![npm](https://img.shields.io/npm/v/js-feel.svg)](https://npmjs.org/package/js-feel) [![NPM](https://nodei.co/npm/js-feel.png?compact=true)](https://npmjs.org/package/js-feel) # About [FEEL](https://github.com/EdgeVerve/feel/wiki/What-is-FEEL%3F) is an expression language based on DMN specification conformance level 3. Written using [PEG.js](https://pegjs.org/) - JavaScript Parser Generator. FEEL is a very powerful language built with the purpose of defining rules in Business Rule Engines. FEEL also offers an API to implement and execute Decision Table defined in excel (.xlsx) # Getting Started FEEL is a completely flexible library which can be used with any project to add support for *Decision Table*. It also comes with a powerful expression language termed *FEEL* built-in to define a multitude of decision rules. ## Installation ### Development ```sh # npm install npm install js-feel --save ``` ### Contribution ```sh # clone repo git clone https://github.com/EdgeVerve/feel.git # or fork repo # install dependencies npm install # run test cases npm test # watch for changes in source and grammar gulp watch # generate parser from grammar gulp generate # lint source files npm run lint # lint-fix source files npm run lintfix ``` # Usage ## Using [Decision Table](https://github.com/EdgeVerve/feel/wiki/Decision-Table#what-is-decision-table) Decision tables are defined in excel (.xlsx). Please check [Sample Rules](README.md#sample-rules). Each cell in the body of the decision table has to be a valid FEEL expression. The following make use of FEEL parser to parse and execute expressions and hence the decision logic. ### Excel to Decision Table ```javascript const { decisionTable } = require('feel')(); const csv = decisionTable.xls_to_csv('./test/StudentFinancialPackageEligibility.xlsx'); const decision_table = decisionTable.csv_to_decision_table(csv[0]); ``` ### Execute Decision Table The Decision Table (decision_table) created in the previous step can be executed using; *decisionTable.execute_decision_table* ```javascript const payload = {"Student GPA" : 3.6,"Student Extra-Curricular Activities Count" : 4,"Student National Honor Society Membership" : "Yes"}; decisionTable.execute_decision_table("StudentFinancialPackageEligibility", decision_table,payload, (results)=> { console.log(results) }); ``` ## Using [FEEL](https://github.com/EdgeVerve/feel/wiki/What-is-FEEL%3F) Standalone ```javascript const {feel} = require('feel')(); const rule = 'a + b - c'; const context = { a: 10, b: 20, c: 5 }; const parsedGrammar = feel.parse(rule); parsedGrammar.build(context).then(result => { console.log(result); }).catch(err => console.error(err)); ``` # Sample FEEL Expressions Some valid FEEL expressions (logically categorized): ### Arithmetic - a + b - c - ((a + b)/c - (d + e*2))**f - 1-(1+rate/12)**-term - (a + b)**-c - date("2012-12-25") + date("2012-12-24") - time("T13:10:06") - time("T13:10:05") - date and time("2012-12-24T23:59:00") + duration("P1Y") ### Comparision - 5 in (<= 5) - 5 in ((5..10]) - 5 in ([5..10]) - 5 in (4,5,6) - 5 in (<5,>5) - (a + 5) >= (7 + g) - (a+b) between (c + d) and (e - f) - date("2012-12-25") > date("2012-12-24") - date and time("2012-12-24T23:59:00") < date and time("2012-12-25T00:00:00") ### Conjunction - a or b - a and b - ((a or b) and (b or c)) or (a and d) - ((a > b) and (a > c)) and (b > c) - ((a + b) > (c - d)) and (a > b) - a or b or a > b - (x(i, j) = y) and (a > b) - (a + b) > (c - d) and (a > b) ### For - for a in [1,2,3] return a * a - for age in [18..40], name in ["george", "mike", "bob"] return status ### Function Definition - function(age) age < 21 - function(rate, term, amount) (amount*rate/12)/(1-(1+rate/12)**-term) ### If - if applicant.maritalStatus in ("M", "S") then "valid" else "not valid" - if Pre-Bureau Risk Category = "DECLINE" or Installment Affordable = false or Age < 18 or Monthly Income < 100 then "INELIGIBLE" else "ELIGIBLE" - if "Pre-Bureau Risk Category" = "DECLINE" or "Installment Affordable" = false or Age < 18 or "Monthly Income" < 100 then "INELIGIBLE" else "ELIGIBLE" ### Quantified - some ch in credit history satisfies ch.event = "bankruptcy" ### Date Time Semantics - time("13:10:05@Etc/UTC").hour - time("13:10:05@Etc/UTC").minute - time("13:01:05+05:30").second - date and time("2012-12-24T23:59:00").year - date("2017-06-10").month - date("2017-06-10").day - duration("P13M").years - duration("P1Y11M").months - duration("P5DT12H10M").days - duration("P5DT12H10M").hours - duration("P5DT12H10M").minutes - duration("P5DT12H10M25S").seconds ### Date Time Conversion and Equality - date("2012-12-25") – date("2012-12-24") = duration("P1D") - date and time("2012-12-24T23:59:00") + duration("PT1M") = date and time("2012-12-25T00:00:00") - time("23:59:00z") + duration("PT2M") = time("00:01:00@Etc/UTC") - date and time("2012-12-24T23:59:00") - date and time("2012-12-22T03:45:00") = duration("P2DT20H14M") - duration("P2Y2M") = duration("P26M") ***Please note: This is not a complete list of FEEL Expressions. Please refer [DMN Specification Document](http://www.omg.org/spec/DMN/1.1/) for detailed documentation on FEEL grammar.*** # Sample Rules [Validation.xlsx](/test/data/Validation.xlsx) [PostBureauRiskCategory.xlsx](/test/data/PostBureauRiskCategory.xlsx) [ElectricityBill.xlsx](/test/data/ElectricityBill.xlsx) # Reference For comprehensive set of documentation on DMN, you can refer to : [DMN Specification Document](http://www.omg.org/spec/DMN/1.1/)