kantime-rule-engine
Version:
A library for custom validation in the form based on the user defined json schema.
443 lines (402 loc) • 11.7 kB
JavaScript
let _ = require("lodash");
let _JQ = require("jsonq");
let RetVal;
let operators = {
/* Returns the length of a string or collection (object/array) */
LENGTH: {
name: "LENGTH",
numParameters: 1,
apply: function (valueArr) {
try {
return _.size((valueArr[0] == null ? "" : valueArr[0]));
} catch (error) {
throw "LENGTHOperatorException: " + error;
}
}
},
/* Returns the result of applying an input regular expression against the input */
REGEX_MATCH: {
name: "REGEX_MATCH",
numParameters: 2,
apply: function (valueArr) {
try {
return new RegExp(valueArr[1]).test((valueArr[0] == null ? "" : valueArr[0]));
} catch (error) {
throw "REGEX_MATCHOperatorException: " + error;
}
}
},
/* Returns the result of applying an input regular expression against the input */
REGEX_NOT_MATCH: {
name: "REGEX_NOT_MATCH",
numParameters: 2,
apply: function (valueArr) {
try {
return !new RegExp(valueArr[1]).test((valueArr[0] == null ? "" : valueArr[0]));
} catch (error) {
throw "REGEX_NOT_MATCHOperatorException: " + error;
}
}
},
/*
Performs an equality check between two items.
If the first parameter is a string or number, the second parameter will be converted as such.
As a fallback, it performs a strict equality (===)
*/
EQ: {
name: "EQ",
numParameters: 2,
apply: function (valueArr) {
try {
if (_.isObject(valueArr[0])) {
RetVal = true;
let ret = iterateJson(valueArr[0]);
return valueArr[1] == "" ? ret : !ret;
}
let left = (valueArr[0] == null ? "" : valueArr[0]);
let right = (valueArr[1] == null ? "" : valueArr[1]);
left = left == "true" ? true : left;
left = left == "false" ? false : left;
right = right == "true" ? true : right;
right = right == "false" ? false : right;
if (_.isString(left)) {
right = String(right);
} else if (_.isNumber(left)) {
right = Number(right);
}
return left === right;
} catch (error) {
throw "EQOperatorException: " + error;
}
}
},
/*
Performs an equality check between two items.
If the first parameter is a string or number, the second parameter will be converted as such.
As a fallback, it performs a strict equality (===)
*/
NEQ: {
name: "NEQ",
numParameters: 2,
apply: function (valueArr) {
try {
if (_.isObject(valueArr[0])) {
RetVal = true;
let ret = iterateJson(valueArr[0]);
return valueArr[1] == "" ? !ret : ret;
}
let left = (valueArr[0] == null ? "" : valueArr[0]);
let right = (valueArr[1] == null ? "" : valueArr[1]);
left = left == "true" ? true : left;
left = left == "false" ? false : left;
right = right == "true" ? true : right;
right = right == "false" ? false : right;
if (_.isString(left)) {
right = String(right);
} else if (_.isNumber(left)) {
right = Number(right);
}
return left != right;
} catch (error) {
throw "NEQOperatorException: " + error;
}
}
},
/* Performs a greater than check between two numbers */
GT: {
name: "GT",
numParameters: 2,
apply: function (valueArr) {
try {
let val1 = (valueArr[0] == null ? "0" : valueArr[0]);
let val2 = (valueArr[1] == null ? "0" : valueArr[1]);
if (_.isNumber(val1)) {
return Number(val1) > Number(val2);
} else {
return new Date(val1) > new Date(val2);
}
} catch (error) {
throw "GTOperatorException: " + error;
}
}
},
/* Performs a greater than equal check between two numbers */
GTEQ: {
name: "GTEQ",
numParameters: 2,
apply: function (valueArr) {
try {
let val1 = (valueArr[0] == null ? "0" : valueArr[0]);
let val2 = (valueArr[1] == null ? "0" : valueArr[1]);
if (_.isNumber(val1)) {
return Number(val1) >= Number(val2);
} else {
return new Date(val1) >= new Date(val2);
}
} catch (error) {
throw "GTEQOperatorException: " + error;
}
}
},
/* Performs a less than check between two numbers */
LT: {
name: "LT",
numParameters: 2,
apply: function (valueArr) {
try {
let val1 = (valueArr[0] == null ? "0" : valueArr[0]);
let val2 = (valueArr[1] == null ? "0" : valueArr[1]);
if (_.isNumber(val1)) {
return Number(val1) < Number(val2);
} else {
return new Date(val1) < new Date(val2);
}
} catch (error) {
throw "LTOperatorException: " + error;
}
}
},
/* Performs a less than equal check between two numbers */
LTEQ: {
name: "LTEQ",
numParameters: 2,
apply: function (valueArr) {
try {
let val1 = (valueArr[0] == null ? "0" : valueArr[0]);
let val2 = (valueArr[1] == null ? "0" : valueArr[1]);
if (_.isNumber(val1)) {
return Number(val1) <= Number(val2);
} else {
return new Date(val1) <= new Date(val2);
}
} catch (error) {
throw "LTEQOperatorException: " + error;
}
}
},
/*
Performs a logical OR amongst items in an array.
Does not semantically continue evaluation once true is found.
*/
OR: {
name: "OR",
numParameters: -1,
apply: function (valueArr) {
try {
for (let i = 0; i < valueArr.length; i++) {
if (_.isBoolean(valueArr[i]) && valueArr[i]) {
return true;
}
}
return false;
} catch (error) {
throw "OROperatorException: " + error;
}
}
},
/*
Performs a logical AND amongst items in an array.
Does not senamtically continue evaluation once false is found.
*/
AND: {
name: "AND",
numParameters: -1,
apply: function (valueArr) {
try {
let ruleOut=false;
for (let i = 0; i < valueArr.length; i++) {
if (_.isBoolean(valueArr[i]) && !valueArr[i]) {
ruleOut=false;
break;
}
else{
ruleOut=true;
}
}
return ruleOut;
} catch (error) {
throw "ANDOperatorException: " + error;
}
}
},
/*
Performs a IN amongst search items in an array.
Does not semantically continue evaluation once true is found.
*/
IN: {
name: "IN",
numParameters: 2,
apply: function (valueArr) {
try {
var eleexists = false;
_.each(_.split(valueArr[1], ','), function (ele) {
if (valueArr[0] == ele) eleexists = true;
});
return eleexists;
} catch (error) {
throw "INOperatorException: " + error;
}
}
},
/*
Performs a Not IN amongst search items in an array.
Does not semantically continue evaluation once true is found.
*/
NOTIN: {
name: "NOTIN",
numParameters: 2,
apply: function (valueArr) {
try {
var eleexists = false;
_.each(_.split(valueArr[1], ','), function (ele) {
if (valueArr[0] == ele) eleexists = true;
});
return !eleexists;
} catch (error) {
throw "NOTINOperatorException: " + error;
}
}
},
/*
Performs a Not IN amongst search items in an array.
Does not semantically continue evaluation once true is found.
*/
/*
Performs a CONTAIN amongst search items in an array.
Does not semantically continue evaluation once true is found.
*/
CONTAIN: {
name: "CONTAIN",
numParameters: 2,
apply: function (valueArr) {
try {
var eleexists = false;
_.each(valueArr[1], (item) => {
if (valueArr[0] == item) eleexists = true;
});
return eleexists;
} catch (error) {
throw "CONTAINOperatorException: " + error;
}
}
},
/*
Performs a CONTAIN amongst search items in an array.
Does not semantically continue evaluation once true is found.
*/
/*
Performs a NOTCONTAIN amongst search items in an array.
Does not semantically continue evaluation once true is found.
*/
NOTCONTAIN: {
name: "NOTCONTAIN",
numParameters: 2,
apply: function (valueArr) {
try {
console.log({valueArr});
var eleexists = false;
_.each(valueArr[1], (item) => {
if (valueArr[0] == item) eleexists = true;
});
return !eleexists;
} catch (error) {
throw "NOTCONTAINOperatorException: " + error;
}
}
},
/*
Performs a NOTCONTAIN amongst search items in an array.
Does not semantically continue evaluation once true is found.
*/
SUBSTRING: {
name: "SUBSTRING",
numParameters: 2,
apply: function (valueArr) {
try {
if (valueArr[0] == null || valueArr[0] == "")
return "";
let Data = valueArr[1].split(",");
return valueArr[0].substr(Data[0], Data[1]);
} catch (error) {
throw "SUBSTRINGOperatorException: " + error;
}
}
},
/*
Performs a NOT BETWEEN.
*/
NOTBETWEEN: {
name: "NOTBETWEEN",
numParameters: 1,
apply: function (valueArr) {
try {
let Data = valueArr[1].split(",");
if (Number(Data[0]) > Number(valueArr[0]) || Number(Data[1]) < Number(valueArr[0]))
return true;
else
return false;
} catch (error) {
throw "NOTBETWEENOperatorException: " + error;
}
}
},
/*
Performs a date difference between two dates.
*/
DATEDIFF: {
name: "DATEDIFF",
numParameters: 2,
apply: function (valueArr) {
try {
var Days = parseInt((new Date(valueArr[0]) - new Date(valueArr[1])) / (1000 * 60 * 60 * 24));
return Days;
} catch (error) {
throw "DATEDIFFOperatorException: " + error;
}
}
},
/*
Performs a Duplicate check from give input array
Does not semantically continue evaluation once true is found.
*/
HASDUPLICATE: {
name: "HASDUPLICATE",
numParameters: 1,
apply: function (valueArr) {
try {
let Data = [];
for (let i = 0; i < valueArr.length; i++) {
if (valueArr[i] != '')
Data.push(valueArr[i]);
}
return new Set(Data).size !== Data.length;
} catch (error) {
throw "HASDUPLICATEOperatorException: " + error;
}
}
}
};
function iterateJson(Jsonobject) {
try{
_JQ.each(Jsonobject, function (key, value) {
if (_JQ.objType(value) == 'object') {
iterateJson(value);
} else {
if (_.isString(value)) {
if (value != "")
RetVal = false;
} else if (_.isBoolean(value)) {
if (value != false)
RetVal = false;
} else if (_.isArray(value)) {
if (value.length > 0)
RetVal = false;
}
}
});
return RetVal;
} catch(error){
throw "iterateJsonException: " + error;
}
}
module.exports = operators;