Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@hbtgmbh/dmn-eval-js

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hbtgmbh/dmn-eval-js

Evaluation of DMN 1.1 decision tables, limited to S-FEEL (Simple Friendly Enough Expression Language)

  • 1.0.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
2.1K
increased by41.85%
Maintainers
1
Weekly downloads
 
Created
Source

License: MIT

About

dmn-eval-js is a Javascript engine to execute decision tables according to the DMN standard. This implementation is based on FEEL by EdgeVerve. It is tailored to evaluation of simple expression language (S-FEEL), plus some cherry-picked parts of FEEL.

dmn-eval-js allows to load and execute DMN decision tables from XML. DRGs are supported. Evaluation of decision tables is currently limited to those of hit policy FIRST (F), UNIQUEE (U), RULE ORDER (R), and COLLECT (C) without aggregation.

Usage

Import

var { decisionTable, dateTime } = require('@hbtgmbh/dmn-eval-js');

Logging

dmn-eval-js uses log4js for logging. Since only the log4js API is used, you need to define a dependency on log4js by yourself if you want to get log output from dmn-eval-js. If you don't, any log statements are safely suppressed.

To see log output, do as follows:

In package.json:

...
"dependencies": {
  ...
  "log4js": "2.4.1",
  ...
},
...

In your code:

...
var log4js = require('log4js');
...
 
var logger = log4js.getLogger('dmn-eval-js');
logger.level = 'debug';

With loglevel 'info', you will see a few short log statements per decision call. With log level 'debug', you will additionally see what input was passed to each decision call (including nested decisions in DRGs), this might be verbose depending on what input values you pass for decision evaluation. Use loglevel 'error' to limit log statements to exceptional cases only. If you do not specify a loglevel, no output statements are shown (this is the same as loglevel 'off');

Parsing decision tables

dmn-eval-js parses XML content. It is up to you to obtain it, e.g. from file system or service call.

const xmlContent = ... // wherever it may come from
decisionTable.readDmnXml(xmlContent, function(err, dmnContent) {
  
  const decisions = decisionTable.parseDecisions(dmnContent.drgElements);
  const context = {
      // your input for decision execution goes in here
  };
  
  decisionTable.evaluateDecision('decide-approval', decisions, context)
    .then(data => {
        // data is the output of the decision execution
        // it is an array for hit policy COLLECT and RULE ORDER,
        // and an object else
    })
    .catch(err => console.log(err));
});

Supported content in decision tables

Heads up! Undefined (in a Javascript sense) values are not supported. All variables that are referenced in input expressions, input entries, or output entries must not resolved to "undefined". If there is no value for them, they should be null, not undefined.

Input expressions

Input expressions are commonly (qualified) names, like so:

  • customerAge
  • customer.age

In the "context" object which is the input for decision execution, the corresponding properties / nested objects must exist. Example:

const context = {
  customer: {
    age: 18;
  }
};

Input expressions are however not restricted to qualified names. You can use any expression according to S-FEEL, any additionally even function invocations, too, like so:

  • employee.salary * 12
  • convertToUSD(employee.salary)

In the case of functions, you need to define these in the given context object:

const context = {
  employee: {
    salary: 100000;
  },
  convertToUSD: (valueInEUR) => [
     // your conversion logic here
  };
};

Function implementation should be free of side-effects. Date and time instances that are arguments to functions are moment-js instances.

Input entries

As input entries, simple unary tests according to the DMN specification are supported, with some additions:

  • an endpoint can also be arithmetic expression
  • a simple values can also be function invocation
  • a simple literal can also be a null literal
  • a date time literal can also be "date and time"
  • brackets in arithmetic expressions are supported
  • additional name symbols are not supported

Examples (the list is not complete though):

Input entrymatches if the input expression evaluates to...
42the numeric value 42
< 42a value less than 42
[41 .. 50]a value between 41 and 50 (inclusive)
10, 20either 10 or 20
<10, >20a value either less than 10 or greater than 20
"A"the string "A"
"A", "B"the string "A" or "B"
truethe boolean value true
-any value
any value (sams as -)
nullthe value null
not(null)any value other than null
propertythe same value as the property (must be given in the context)
object.propertythe same value as the property of the object
f(a)the same value as the function evaluated with the property (function and property must be given in the context)
limit - 10the same value as the limit minus 10
limit * 2the same value as the limit times 2
[limit.upper, limit.lower]a value between the value of two given properties of object limit
date("2017-05-01")the date value Mai 1st, 2017
duration(d)the duration specified by d, which must be an ISO 8601 duration string like P3D for three days
duration(d) * 2twice the duration
duration(begin, end)the duration between the specified begin and end date
date(begin) + duration(d)the date that results by adding the given duration to the given date
< date(begin) + duration(d)any date before the date that results by adding the given duration to the given date

Most combinations of the syntax elements above are valid, too. For example the following is a valid input entry (although it probably does not make any sense):

not(f(a + 1), [ date(b) + duration(c.d) .. g(d) ]) 

Output entries

A simple expression according to the DMN specification is supported as output entry, with the same additions as mentioned for input entries. Since output entries are expressions, not comparisons, values like the following are not allowed:

  • < 1
  • [1 .. 2]
  • not("A")
  • empty values (this includes the dash -)

Passing dates as input

To create date, time, date and time, and duration object instances as input for decision execution, do as follows:

const someJavascriptDate = new Date(...);

const context = {

  dateFromString: dateTime.date('2017-03-19'),
  dateFromJavascriptDate: dateTime.date(someJavascriptDate),
  dateFromYearMonthDay: dateTime.date(2018, 0, 1), // January 1st, 2018

  timeFromString: dateTime.time('03:45:00'),
  timeFromJavascriptDate: dateTime.time(someJavascriptDate), // only the time part is taken
  timeFromHourMinuteSecond: dateTime.time(3, 45, 0), // same as above

  dateAndTimeFromString: dateTime['date and time']('2012-12-22T03:45:00'),
  dateAndTimeFromJavascriptDate: dateTime['date and time'](someJavascriptDate),
  dateAndTimeFromIndividualDateAndTime: dateTime['date and time'](dateTime.date(...), dateTime.time(...)),

  yearsMonthDurationFromString: dateTime.duration('P1Y2M'), // one year, 2 months (=14 months)
  daysAndTimeDurationFromString: dateTime.duration('P3DT4H'), // 3 days, 4 hours (=76 hours)
  durationAsDateDifference: dateTime.duration(dateTime.date(...), dateTime.date(...))
};

(to come: describe how timezones are specified)

Development

# 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

Reference

For comprehensive set of documentation on DMN, you can refer to :

DMN Specification Document

Keywords

FAQs

Package last updated on 22 Jan 2018

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc