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.1.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1.8K
decreased by-0.39%
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 loglevel for logging. By default, warning and error messages are shown only. For additional log output, you need to configure a logger namend 'dmn-eval-js' as follows:

...
var loglevel = require('loglevel');
...
 
var logger = loglevel.getLogger('dmn-eval-js');
logger.setLevel('info');

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.

Parsing decision tables

dmn-eval-js parses DMN from XML content. It is up to you to obtain the XML content, e.g. from file system or service call. Parsing is asynchronous using a Promise, while evaluation (execution) of a decision is synchronous.

const xmlContent = ... // wherever it may come from
 
decisionTable.parseDmnXml(xmlContent)
    .then((decisions) => {
        // DMN was successfully parsed
        const context = {
            // your input for decision execution goes in here
        };

        try {
            const data = decisionTable.evaluateDecision('decide-approval', decisions, context);
            // data is the output of the decision execution
            // it is an array for hit policy COLLECT and RULE ORDER, and an object else
            
            ... // do something with the data
            
        } catch (err) {
            // failed to evaluate rule, maybe the context is missing some data?
            console.log(err)
        };
    })
    .catch(err => {
         // failed to parse DMN XML: either invalid XML or valid XML but invalid DMN
         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, and 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 value 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 16 Feb 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