@hbtgmbh/dmn-eval-js
Advanced tools
Comparing version 1.4.4 to 1.4.5
{ | ||
"name": "@hbtgmbh/dmn-eval-js", | ||
"version": "1.4.4", | ||
"version": "1.4.5", | ||
"description": "Evaluation of DMN 1.1 decision tables, limited to S-FEEL (Simple Friendly Enough Expression Language)", | ||
@@ -45,2 +45,3 @@ "license": "MIT", | ||
"chai": "^4.1.2", | ||
"chai-arrays": "^2.0.0", | ||
"chalk": "^1.1.3", | ||
@@ -47,0 +48,0 @@ "eslint": "^3.19.0", |
@@ -147,6 +147,6 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) | ||
dmn-eval-js supports the following built-in functions from DMN 1.1: | ||
- string functions: starts with, ends with, contains, upper case, lower case | ||
- boolean functions: not | ||
- string functions: ```starts with, ends with, contains, upper case, lower case``` | ||
- boolean functions: ```not``` | ||
- list functions: ```list contains, count, min, max, sum, mean, and, or, append, concatenate, insert before, remove, reverse, index of, union, distinct values, flatten``` | ||
### Input entries | ||
@@ -205,3 +205,3 @@ | ||
![DMN example](https://github.com/HBTGmbH/dmn-eval-js/blob/master/dmn-input-variables.png "Derive the project name from the prefix of an issue ID.") | ||
![Functions in input entries](https://github.com/HBTGmbH/dmn-eval-js/blob/master/dmn-input-variables.png "Derive the project name from the prefix of an issue ID.") | ||
@@ -208,0 +208,0 @@ The ```starts with(string, substring)``` function allows to test if a string starts with a given prefix, |
@@ -11,7 +11,12 @@ /* | ||
const listContains = (list, element) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (element === undefined || element === null) { | ||
return false; | ||
} | ||
if (!Array.isArray(list)) { | ||
throw new Error('operation unsupported on element of this type'); | ||
} else { | ||
if (list.indexOf(element) > -1) { return true; } | ||
return false; | ||
return list.indexOf(element) > -1; | ||
} | ||
@@ -21,3 +26,8 @@ }; | ||
const count = (list) => { | ||
if (!Array.isArray(list)) { throw new Error('operation unsupported on element of this type'); } else { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
throw new Error('operation unsupported on element of this type'); | ||
} else { | ||
return list.length; | ||
@@ -28,2 +38,5 @@ } | ||
const min = (list) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
@@ -37,2 +50,5 @@ throw new Error('operation unsupported on element of this type'); | ||
const max = (list) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
@@ -46,2 +62,5 @@ throw new Error('operation unsupported on element of this type'); | ||
const sum = (list) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
@@ -55,10 +74,18 @@ throw new Error('operation unsupported on element of this type'); | ||
const mean = (list) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
let result; | ||
if (!Array.isArray(list)) { | ||
throw new Error('operation unsupported on element of this type'); | ||
} else { | ||
return (_.sum(list)) / (list.length); | ||
} else if (list.length > 0) { | ||
result = (_.sum(list)) / (list.length); | ||
} | ||
return result; | ||
}; | ||
const and = (list) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
@@ -72,2 +99,5 @@ throw new Error('operation unsupported on element of this type'); | ||
const or = (list) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
@@ -80,19 +110,43 @@ throw new Error('operation unsupported on element of this type'); | ||
const append = (element, list) => { | ||
const append = (list, element) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
throw new Error('operation unsupported on element of this type'); | ||
} else if (element === undefined) { | ||
return list; | ||
} else if (Array.isArray(element)) { | ||
return list.concat(element); | ||
} else { | ||
return list.push(element); | ||
return list.concat([element]); | ||
} | ||
}; | ||
const concatenate = (...args) => args.reduce((result, next) => Array.prototype.concat(result, next), []); | ||
const concatenate = (...args) => | ||
args.reduce((result, next) => { | ||
if (Array.isArray(next)) { | ||
return Array.prototype.concat(result, next); | ||
} | ||
return result; | ||
}, []); | ||
const insertBefore = (list, position, newItem) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (position === undefined || position === null) { | ||
return position; | ||
} | ||
if (newItem === undefined) { | ||
return newItem; | ||
} | ||
if (!Array.isArray(list)) { | ||
throw new Error('operation unsupported on element of this type'); | ||
} else if (position > list.length || position < 0) { | ||
throw new Error('invalid position'); | ||
throw new Error(`cannot insert ${newItem} at position ${position} in list ${list}`); | ||
} else { | ||
return list.splice(position - 1, 0, newItem); | ||
const newList = [].concat(list); | ||
newList.splice(position, 0, newItem); | ||
return newList; | ||
} | ||
@@ -102,8 +156,16 @@ }; | ||
const remove = (list, position) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (position === undefined || position === null) { | ||
return position; | ||
} | ||
if (!Array.isArray(list)) { | ||
throw new Error('operation unsupported on element of this type'); | ||
} else if (position > list.length - 1) { | ||
throw new Error('invalid position'); | ||
throw new Error(`cannot remove element at position ${position} in list ${list}`); | ||
} else { | ||
return list.splice(position, 1); | ||
const newList = [].concat(list); | ||
newList.splice(position, 1); | ||
return newList; | ||
} | ||
@@ -113,2 +175,5 @@ }; | ||
const reverse = (list) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
@@ -122,12 +187,31 @@ throw new Error('operation unsupported on element of this type'); | ||
const indexOf = (list, match) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (match === undefined) { | ||
return match; | ||
} | ||
if (!Array.isArray(list)) { | ||
throw new Error('operation unsupported on element of this type'); | ||
} else { | ||
return _.indexOf(list, match); | ||
const indexes = []; | ||
const remainingList = [].concat(list); | ||
let offset = 0; | ||
let nextIndex = remainingList.indexOf(match); | ||
while (nextIndex >= 0) { | ||
indexes.push(nextIndex + offset); | ||
remainingList.splice(0, nextIndex + 1); | ||
offset += nextIndex + 1; | ||
nextIndex = remainingList.indexOf(match); | ||
} | ||
return indexes; | ||
} | ||
}; | ||
const union = (...args) => _.union(args); | ||
const union = (...args) => _.union(...args); | ||
const distinctValues = (list) => { | ||
if (list === undefined || list === null) { | ||
return list; | ||
} | ||
if (!Array.isArray(list)) { | ||
@@ -140,6 +224,14 @@ throw new Error('operation unsupported on element of this type'); | ||
const flatten = (...args) => _.flatten(args); | ||
const flatten = (...args) => { | ||
// remove context from args array (last element) | ||
const array = [].concat(args); | ||
array.splice(array.length - 1, 1); | ||
if (array.length === 1 && (array[0] === null || array[0] === undefined)) { | ||
return array[0]; | ||
} | ||
return _.flattenDeep(array); | ||
}; | ||
module.exports = { | ||
listContains, | ||
'list contains': listContains, | ||
count, | ||
@@ -154,9 +246,9 @@ min, | ||
concatenate, | ||
insertBefore, | ||
'insert before': insertBefore, | ||
remove, | ||
reverse, | ||
indexOf, | ||
'index of': indexOf, | ||
union, | ||
distinctValues, | ||
'distinct values': distinctValues, | ||
flatten, | ||
}; |
@@ -20,16 +20,18 @@ /* | ||
const parsedRule = { number: idx + 1, input: [], inputValues: [], output: [], outputValues: [] }; | ||
rule.inputEntry.forEach((inputEntry) => { | ||
let text = inputEntry.text; | ||
if (text === '') { | ||
text = '-'; | ||
} | ||
try { | ||
parsedRule.input.push(feel.parse(text, { | ||
startRule: 'SimpleUnaryTests', | ||
})); | ||
parsedRule.inputValues.push(text); | ||
} catch (err) { | ||
throw new Error(`Failed to parse input entry: ${text} ${err}`); | ||
} | ||
}); | ||
if (rule.inputEntry) { | ||
rule.inputEntry.forEach((inputEntry) => { | ||
let text = inputEntry.text; | ||
if (text === '') { | ||
text = '-'; | ||
} | ||
try { | ||
parsedRule.input.push(feel.parse(text, { | ||
startRule: 'SimpleUnaryTests', | ||
})); | ||
parsedRule.inputValues.push(text); | ||
} catch (err) { | ||
throw new Error(`Failed to parse input entry: ${text} ${err}`); | ||
} | ||
}); | ||
} | ||
rule.outputEntry.forEach((outputEntry) => { | ||
@@ -70,20 +72,22 @@ if (!outputEntry.text) { | ||
// parse input expressions | ||
decisionTable.input.forEach((input) => { | ||
let inputExpression; | ||
if (input.inputExpression && input.inputExpression.text) { | ||
inputExpression = input.inputExpression.text; | ||
} else if (input.inputVariable) { | ||
inputExpression = input.inputVariable; | ||
} else { | ||
throw new Error(`No input variable or expression set for input '${input.id}'`); | ||
} | ||
parsedDecisionTable.inputExpressions.push(inputExpression); | ||
try { | ||
parsedDecisionTable.parsedInputExpressions.push(feel.parse(inputExpression, { | ||
startRule: 'SimpleExpressions', | ||
})); | ||
} catch (err) { | ||
throw new Error(`Failed to parse input expression '${inputExpression}': ${err}`); | ||
} | ||
}); | ||
if (decisionTable.input) { | ||
decisionTable.input.forEach((input) => { | ||
let inputExpression; | ||
if (input.inputExpression && input.inputExpression.text) { | ||
inputExpression = input.inputExpression.text; | ||
} else if (input.inputVariable) { | ||
inputExpression = input.inputVariable; | ||
} else { | ||
throw new Error(`No input variable or expression set for input '${input.id}'`); | ||
} | ||
parsedDecisionTable.inputExpressions.push(inputExpression); | ||
try { | ||
parsedDecisionTable.parsedInputExpressions.push(feel.parse(inputExpression, { | ||
startRule: 'SimpleExpressions', | ||
})); | ||
} catch (err) { | ||
throw new Error(`Failed to parse input expression '${inputExpression}': ${err}`); | ||
} | ||
}); | ||
} | ||
@@ -90,0 +94,0 @@ // parse output names |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6321
290066
25
39