You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

json-expression-eval

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-expression-eval - npm Package Compare versions

Comparing version

to
5.0.0

4

dist/lib/engine.d.ts
import { RuleFunctionsTable, Rule, FunctionsTable, Context, ResolvedConsequence, ValidationContext } from '../types';
export declare const evaluateRules: <ConsequencePayload, C extends Context, RF extends RuleFunctionsTable<C, ConsequencePayload>, F extends FunctionsTable<C>, Ignore = never>(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], context: C, functionsTable: F, ruleFunctionsTable: RF, haltOnFirstMatch: boolean) => void | ResolvedConsequence<ConsequencePayload>[];
export declare const validateRules: <ConsequencePayload, C extends Context, RF extends RuleFunctionsTable<C, ConsequencePayload>, F extends FunctionsTable<C>, Ignore = never>(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], validationContext: import("../types").NonNullable<C, Ignore>, functionsTable: F, ruleFunctionsTable: RF) => void;
export declare const evaluateRules: <ConsequencePayload, C extends Context, RF extends RuleFunctionsTable<C, ConsequencePayload>, F extends FunctionsTable<C>, Ignore = never>(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], context: C, functionsTable: F, ruleFunctionsTable: RF, haltOnFirstMatch: boolean) => Promise<void | ResolvedConsequence<ConsequencePayload>[]>;
export declare const validateRules: <ConsequencePayload, C extends Context, RF extends RuleFunctionsTable<C, ConsequencePayload>, F extends FunctionsTable<C>, Ignore = never>(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], validationContext: import("../types").NonNullable<C, Ignore>, functionsTable: F, ruleFunctionsTable: RF) => Promise<void>;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -9,33 +18,35 @@ exports.validateRules = exports.evaluateRules = void 0;

function run(rules, context, functionsTable, ruleFunctionsTable, haltOnFirstMatch, validation) {
const errors = [];
for (const rule of rules) {
const keys = (0, helpers_1.objectKeys)(rule);
const key = keys[0];
if (keys.length === 1 && key && (0, typeGuards_1.isRuleFunction)(rule, ruleFunctionsTable, key)) {
const consequence = ruleFunctionsTable[key](rule[key], context);
if (consequence) {
errors.push(consequence);
if (haltOnFirstMatch && !validation) {
return errors;
return __awaiter(this, void 0, void 0, function* () {
const errors = [];
for (const rule of rules) {
const keys = (0, helpers_1.objectKeys)(rule);
const key = keys[0];
if (keys.length === 1 && key && (0, typeGuards_1.isRuleFunction)(rule, ruleFunctionsTable, key)) {
const consequence = yield ruleFunctionsTable[key](rule[key], context);
if (consequence) {
errors.push(consequence);
if (haltOnFirstMatch && !validation) {
return errors;
}
}
}
}
else {
if (!rule.condition) {
throw new Error(`Missing condition for rule`);
}
if (!rule.consequence) {
throw new Error(`Missing consequence for rule`);
}
if (validation) {
(0, evaluator_1.validate)(rule.condition, context, functionsTable);
(0, engineConsequenceEvaluator_1.evaluateEngineConsequence)(context, rule.consequence);
}
else {
const ruleApplies = (0, evaluator_1.evaluate)(rule.condition, context, functionsTable);
if (ruleApplies) {
const consequence = (0, engineConsequenceEvaluator_1.evaluateEngineConsequence)(context, rule.consequence);
errors.push(consequence);
if (haltOnFirstMatch) {
return errors;
if (!rule.condition) {
throw new Error(`Missing condition for rule`);
}
if (!rule.consequence) {
throw new Error(`Missing consequence for rule`);
}
if (validation) {
yield (0, evaluator_1.validate)(rule.condition, context, functionsTable);
yield (0, engineConsequenceEvaluator_1.evaluateEngineConsequence)(context, rule.consequence);
}
else {
const ruleApplies = yield (0, evaluator_1.evaluate)(rule.condition, context, functionsTable);
if (ruleApplies) {
const consequence = yield (0, engineConsequenceEvaluator_1.evaluateEngineConsequence)(context, rule.consequence);
errors.push(consequence);
if (haltOnFirstMatch) {
return errors;
}
}

@@ -45,13 +56,13 @@ }

}
}
return errors.length ? errors : undefined;
return errors.length ? errors : undefined;
});
}
const evaluateRules = (rules, context, functionsTable, ruleFunctionsTable, haltOnFirstMatch) => {
const evaluateRules = (rules, context, functionsTable, ruleFunctionsTable, haltOnFirstMatch) => __awaiter(void 0, void 0, void 0, function* () {
return run(rules, context, functionsTable, ruleFunctionsTable, haltOnFirstMatch, false);
};
});
exports.evaluateRules = evaluateRules;
const validateRules = (rules, validationContext, functionsTable, ruleFunctionsTable) => {
run(rules, validationContext, functionsTable, ruleFunctionsTable, false, true);
};
const validateRules = (rules, validationContext, functionsTable, ruleFunctionsTable) => __awaiter(void 0, void 0, void 0, function* () {
yield run(rules, validationContext, functionsTable, ruleFunctionsTable, false, true);
});
exports.validateRules = validateRules;
//# sourceMappingURL=engine.js.map
import { ResolvedConsequence, Context, RuleConsequence } from '../types';
export declare const evaluateEngineConsequence: <ConsequencePayload, C extends Context, Ignore = never>(context: C, consequence: RuleConsequence<ConsequencePayload, C, Ignore>) => ResolvedConsequence<ConsequencePayload>;
export declare const evaluateEngineConsequence: <ConsequencePayload, C extends Context, Ignore = never>(context: C, consequence: RuleConsequence<ConsequencePayload, C, Ignore>) => Promise<ResolvedConsequence<ConsequencePayload>>;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.evaluateEngineConsequence = void 0;
const helpers_1 = require("./helpers");
const evaluateEngineConsequence = (context, consequence) => {
const evaluateEngineConsequence = (context, consequence) => __awaiter(void 0, void 0, void 0, function* () {
let messageParts;

@@ -26,4 +35,4 @@ if (typeof consequence.message === 'string') {

};
};
});
exports.evaluateEngineConsequence = evaluateEngineConsequence;
//# sourceMappingURL=engineConsequenceEvaluator.js.map
import { Context, Expression, FunctionsTable, ValidationContext } from '../types';
export declare const evaluate: <C extends Context, F extends FunctionsTable<C>, Ignore = never>(expression: import("ts-toolbelt/out/Object/Either").Either<import("../types").FullExpression<C, F, Ignore>, "not" | "or" | "and" | import("ts-toolbelt/out/String/Join").Join<import("../types").Paths<C, [], any[] | Ignore, string>, "."> | keyof F, 1>, context: C, functionsTable: F) => boolean;
export declare const validate: <C extends Context, F extends FunctionsTable<C>, Ignore = never>(expression: import("ts-toolbelt/out/Object/Either").Either<import("../types").FullExpression<C, F, Ignore>, "not" | "or" | "and" | import("ts-toolbelt/out/String/Join").Join<import("../types").Paths<C, [], any[] | Ignore, string>, "."> | keyof F, 1>, validationContext: import("../types").NonNullable<C, Ignore>, functionsTable: F) => void;
export declare const evaluate: <C extends Context, F extends FunctionsTable<C>, Ignore = never>(expression: import("ts-toolbelt/out/Object/Either").Either<import("../types").FullExpression<C, F, Ignore>, "not" | "or" | "and" | import("ts-toolbelt/out/String/Join").Join<import("../types").Paths<C, [], any[] | Ignore, string>, "."> | keyof F, 1>, context: C, functionsTable: F) => Promise<boolean>;
export declare const validate: <C extends Context, F extends FunctionsTable<C>, Ignore = never>(expression: import("ts-toolbelt/out/Object/Either").Either<import("../types").FullExpression<C, F, Ignore>, "not" | "or" | "and" | import("ts-toolbelt/out/String/Join").Join<import("../types").Paths<C, [], any[] | Ignore, string>, "."> | keyof F, 1>, validationContext: import("../types").NonNullable<C, Ignore>, functionsTable: F) => Promise<void>;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -20,137 +29,145 @@ exports.validate = exports.evaluate = void 0;

function evaluateCompareOp(expressionValue, expressionKey, contextValue, context, validation) {
if (!(0, typeGuards_1._isObject)(expressionValue)) {
return contextValue === expressionValue;
}
const compareKeys = (0, helpers_1.objectKeys)(expressionValue);
if (compareKeys.length !== 1) {
throw new Error('Invalid expression - too may keys');
}
if ((0, typeGuards_1.isEqualCompareOp)(expressionValue)) {
return contextValue === extractValueOrRef(context, validation, expressionValue.eq);
}
else if ((0, typeGuards_1.isNotEqualCompareOp)(expressionValue)) {
return contextValue !== extractValueOrRef(context, validation, expressionValue.neq);
}
else if ((0, typeGuards_1.isInqCompareOp)(expressionValue)) {
return expressionValue.inq.map((value) => extractValueOrRef(context, validation, value))
.indexOf(contextValue) >= 0;
}
else if ((0, typeGuards_1.isNinCompareOp)(expressionValue)) {
return expressionValue.nin.map((value) => extractValueOrRef(context, validation, value))
.indexOf(contextValue) < 0;
}
else if ((0, typeGuards_1.isRegexCompareOp)(expressionValue)) {
(0, helpers_1.contextStringAssertion)(expressionKey, contextValue);
const regexpValue = extractValueOrRef(context, validation, expressionValue.regexp);
(0, helpers_1.expressionStringAssertion)(expressionKey, regexpValue);
return Boolean(contextValue.match(new RegExp(regexpValue)));
}
else if ((0, typeGuards_1.isRegexiCompareOp)(expressionValue)) {
(0, helpers_1.contextStringAssertion)(expressionKey, contextValue);
const regexpiValue = extractValueOrRef(context, validation, expressionValue.regexpi);
(0, helpers_1.expressionStringAssertion)(expressionKey, regexpiValue);
return Boolean(contextValue.match(new RegExp(regexpiValue, `i`)));
}
else if ((0, typeGuards_1.isGtCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
const gtValue = extractValueOrRef(context, validation, expressionValue.gt);
(0, helpers_1.expressionNumberAssertion)(expressionKey, gtValue);
return contextValue > gtValue;
}
else if ((0, typeGuards_1.isGteCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
const gteValue = extractValueOrRef(context, validation, expressionValue.gte);
(0, helpers_1.expressionNumberAssertion)(expressionKey, gteValue);
return contextValue >= gteValue;
}
else if ((0, typeGuards_1.isLteCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
const lteValue = extractValueOrRef(context, validation, expressionValue.lte);
(0, helpers_1.expressionNumberAssertion)(expressionKey, lteValue);
return contextValue <= lteValue;
}
else if ((0, typeGuards_1.isLtCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
const ltValue = extractValueOrRef(context, validation, expressionValue.lt);
(0, helpers_1.expressionNumberAssertion)(expressionKey, ltValue);
return contextValue < ltValue;
}
else if ((0, typeGuards_1.isBetweenCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
if (expressionValue.between.length !== 2) {
throw new Error(`Invalid expression - ${expressionKey}.length must be 2`);
return __awaiter(this, void 0, void 0, function* () {
if (!(0, typeGuards_1._isObject)(expressionValue)) {
return contextValue === expressionValue;
}
const [lowRaw, highRaw] = expressionValue.between;
const low = extractValueOrRef(context, validation, lowRaw);
const high = extractValueOrRef(context, validation, highRaw);
(0, helpers_1.expressionNumberAssertion)(`${expressionKey}[0]`, low);
(0, helpers_1.expressionNumberAssertion)(`${expressionKey}[1]`, high);
if (low > high) {
throw new Error(`Invalid expression - ${expressionKey} first value is higher than second value`);
const compareKeys = (0, helpers_1.objectKeys)(expressionValue);
if (compareKeys.length !== 1) {
throw new Error('Invalid expression - too may keys');
}
return contextValue >= low && contextValue <= high;
}
else {
return (0, helpers_1.assertUnreachable)(expressionValue, `Invalid expression - unknown op ${compareKeys[0]}`);
}
if ((0, typeGuards_1.isEqualCompareOp)(expressionValue)) {
return contextValue === extractValueOrRef(context, validation, expressionValue.eq);
}
else if ((0, typeGuards_1.isNotEqualCompareOp)(expressionValue)) {
return contextValue !== extractValueOrRef(context, validation, expressionValue.neq);
}
else if ((0, typeGuards_1.isInqCompareOp)(expressionValue)) {
return expressionValue.inq.map((value) => extractValueOrRef(context, validation, value))
.indexOf(contextValue) >= 0;
}
else if ((0, typeGuards_1.isNinCompareOp)(expressionValue)) {
return expressionValue.nin.map((value) => extractValueOrRef(context, validation, value))
.indexOf(contextValue) < 0;
}
else if ((0, typeGuards_1.isRegexCompareOp)(expressionValue)) {
(0, helpers_1.contextStringAssertion)(expressionKey, contextValue);
const regexpValue = extractValueOrRef(context, validation, expressionValue.regexp);
(0, helpers_1.expressionStringAssertion)(expressionKey, regexpValue);
return Boolean(contextValue.match(new RegExp(regexpValue)));
}
else if ((0, typeGuards_1.isRegexiCompareOp)(expressionValue)) {
(0, helpers_1.contextStringAssertion)(expressionKey, contextValue);
const regexpiValue = extractValueOrRef(context, validation, expressionValue.regexpi);
(0, helpers_1.expressionStringAssertion)(expressionKey, regexpiValue);
return Boolean(contextValue.match(new RegExp(regexpiValue, `i`)));
}
else if ((0, typeGuards_1.isGtCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
const gtValue = extractValueOrRef(context, validation, expressionValue.gt);
(0, helpers_1.expressionNumberAssertion)(expressionKey, gtValue);
return contextValue > gtValue;
}
else if ((0, typeGuards_1.isGteCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
const gteValue = extractValueOrRef(context, validation, expressionValue.gte);
(0, helpers_1.expressionNumberAssertion)(expressionKey, gteValue);
return contextValue >= gteValue;
}
else if ((0, typeGuards_1.isLteCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
const lteValue = extractValueOrRef(context, validation, expressionValue.lte);
(0, helpers_1.expressionNumberAssertion)(expressionKey, lteValue);
return contextValue <= lteValue;
}
else if ((0, typeGuards_1.isLtCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
const ltValue = extractValueOrRef(context, validation, expressionValue.lt);
(0, helpers_1.expressionNumberAssertion)(expressionKey, ltValue);
return contextValue < ltValue;
}
else if ((0, typeGuards_1.isBetweenCompareOp)(expressionValue)) {
(0, helpers_1.contextNumberAssertion)(expressionKey, contextValue);
if (expressionValue.between.length !== 2) {
throw new Error(`Invalid expression - ${expressionKey}.length must be 2`);
}
const [lowRaw, highRaw] = expressionValue.between;
const low = extractValueOrRef(context, validation, lowRaw);
const high = extractValueOrRef(context, validation, highRaw);
(0, helpers_1.expressionNumberAssertion)(`${expressionKey}[0]`, low);
(0, helpers_1.expressionNumberAssertion)(`${expressionKey}[1]`, high);
if (low > high) {
throw new Error(`Invalid expression - ${expressionKey} first value is higher than second value`);
}
return contextValue >= low && contextValue <= high;
}
else {
return (0, helpers_1.assertUnreachable)(expressionValue, `Invalid expression - unknown op ${compareKeys[0]}`);
}
});
}
function handleAndOp(andExpression, context, functionsTable, validation) {
if (andExpression.length === 0) {
throw new Error('Invalid expression - and operator must have at least one expression');
}
for (const currExpression of andExpression) {
const result = run(currExpression, context, functionsTable, validation);
if (!validation && !result) {
return false;
return __awaiter(this, void 0, void 0, function* () {
if (andExpression.length === 0) {
throw new Error('Invalid expression - and operator must have at least one expression');
}
}
return true;
for (const currExpression of andExpression) {
const result = yield run(currExpression, context, functionsTable, validation);
if (!validation && !result) {
return false;
}
}
return true;
});
}
function handleOrOp(orExpression, context, functionsTable, validation) {
if (orExpression.length === 0) {
throw new Error('Invalid expression - or operator must have at least one expression');
}
for (const currExpression of orExpression) {
const result = run(currExpression, context, functionsTable, validation);
if (!validation && result) {
return true;
return __awaiter(this, void 0, void 0, function* () {
if (orExpression.length === 0) {
throw new Error('Invalid expression - or operator must have at least one expression');
}
}
return false;
for (const currExpression of orExpression) {
const result = yield run(currExpression, context, functionsTable, validation);
if (!validation && result) {
return true;
}
}
return false;
});
}
function run(expression, context, functionsTable, validation) {
const expressionKeys = (0, helpers_1.objectKeys)(expression);
if (expressionKeys.length !== 1) {
throw new Error('Invalid expression - too may keys');
}
const expressionKey = expressionKeys[0];
if ((0, typeGuards_1.isAndCompareOp)(expression)) {
return handleAndOp(expression.and, context, functionsTable, validation);
}
else if ((0, typeGuards_1.isOrCompareOp)(expression)) {
return handleOrOp(expression.or, context, functionsTable, validation);
}
else if ((0, typeGuards_1.isNotCompareOp)(expression)) {
return !run(expression.not, context, functionsTable, validation);
}
else if ((0, typeGuards_1.isFunctionCompareOp)(expression, functionsTable, expressionKey)) {
return validation ? true : functionsTable[expressionKey](expression[expressionKey], context);
}
else {
const { value: contextValue, exists } = (0, helpers_1.getFromPath)(context, expressionKey);
if (validation && !exists) {
throw new Error(`Invalid expression - unknown context key ${expressionKey}`);
return __awaiter(this, void 0, void 0, function* () {
const expressionKeys = (0, helpers_1.objectKeys)(expression);
if (expressionKeys.length !== 1) {
throw new Error('Invalid expression - too may keys');
}
return evaluateCompareOp(expression[expressionKey], expressionKey, contextValue, context, validation);
}
const expressionKey = expressionKeys[0];
if ((0, typeGuards_1.isAndCompareOp)(expression)) {
return handleAndOp(expression.and, context, functionsTable, validation);
}
else if ((0, typeGuards_1.isOrCompareOp)(expression)) {
return handleOrOp(expression.or, context, functionsTable, validation);
}
else if ((0, typeGuards_1.isNotCompareOp)(expression)) {
return !(yield run(expression.not, context, functionsTable, validation));
}
else if ((0, typeGuards_1.isFunctionCompareOp)(expression, functionsTable, expressionKey)) {
return validation ? true : yield functionsTable[expressionKey](expression[expressionKey], context);
}
else {
const { value: contextValue, exists } = (0, helpers_1.getFromPath)(context, expressionKey);
if (validation && !exists) {
throw new Error(`Invalid expression - unknown context key ${expressionKey}`);
}
return evaluateCompareOp(expression[expressionKey], expressionKey, contextValue, context, validation);
}
});
}
const evaluate = (expression, context, functionsTable) => {
const evaluate = (expression, context, functionsTable) => __awaiter(void 0, void 0, void 0, function* () {
return run(expression, context, functionsTable, false);
};
});
exports.evaluate = evaluate;
// Throws in case of validation error. Does not run functions or compare fields
const validate = (expression, validationContext, functionsTable) => {
run(expression, validationContext, functionsTable, true);
};
const validate = (expression, validationContext, functionsTable) => __awaiter(void 0, void 0, void 0, function* () {
yield run(expression, validationContext, functionsTable, true);
});
exports.validate = validate;
//# sourceMappingURL=evaluator.js.map

@@ -6,4 +6,4 @@ import { Context, Expression, FunctionsTable, ValidationContext } from '../types';

constructor(expression: Expression<C, F, Ignore>, functionsTable: F);
evaluate(context: C): boolean;
validate(validationContext: ValidationContext<C, Ignore>): void;
evaluate(context: C): Promise<boolean>;
validate(validationContext: ValidationContext<C, Ignore>): Promise<void>;
}
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -11,6 +20,10 @@ exports.ExpressionHandler = void 0;

evaluate(context) {
return (0, evaluator_1.evaluate)(this.expression, context, this.functionsTable);
return __awaiter(this, void 0, void 0, function* () {
return (0, evaluator_1.evaluate)(this.expression, context, this.functionsTable);
});
}
validate(validationContext) {
(0, evaluator_1.validate)(this.expression, validationContext, this.functionsTable);
return __awaiter(this, void 0, void 0, function* () {
yield (0, evaluator_1.validate)(this.expression, validationContext, this.functionsTable);
});
}

@@ -17,0 +30,0 @@ }

@@ -6,5 +6,5 @@ import { Context, FunctionsTable, ValidationContext, RuleFunctionsTable, Rule, ResolvedConsequence } from '../types';

constructor(functionsTable: F, ruleFunctionsTable: RF);
evaluate(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], context: C): void | ResolvedConsequence<ConsequencePayload>;
evaluateAll(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], context: C): void | ResolvedConsequence<ConsequencePayload>[];
validate(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], validationContext: ValidationContext<C, Ignore>): void;
evaluate(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], context: C): Promise<void | ResolvedConsequence<ConsequencePayload>>;
evaluateAll(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], context: C): Promise<void | ResolvedConsequence<ConsequencePayload>[]>;
validate(rules: Rule<ConsequencePayload, RF, C, F, Ignore>[], validationContext: ValidationContext<C, Ignore>): Promise<void>;
}
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -12,9 +21,15 @@ exports.RulesEngine = void 0;

var _a;
return (_a = (0, engine_1.evaluateRules)(rules, context, this.functionsTable, this.ruleFunctionsTable, true)) === null || _a === void 0 ? void 0 : _a[0];
return __awaiter(this, void 0, void 0, function* () {
return (_a = (yield (0, engine_1.evaluateRules)(rules, context, this.functionsTable, this.ruleFunctionsTable, true))) === null || _a === void 0 ? void 0 : _a[0];
});
}
evaluateAll(rules, context) {
return (0, engine_1.evaluateRules)(rules, context, this.functionsTable, this.ruleFunctionsTable, false);
return __awaiter(this, void 0, void 0, function* () {
return (0, engine_1.evaluateRules)(rules, context, this.functionsTable, this.ruleFunctionsTable, false);
});
}
validate(rules, validationContext) {
(0, engine_1.validateRules)(rules, validationContext, this.functionsTable, this.ruleFunctionsTable);
return __awaiter(this, void 0, void 0, function* () {
yield (0, engine_1.validateRules)(rules, validationContext, this.functionsTable, this.ruleFunctionsTable);
});
}

@@ -21,0 +36,0 @@ }

@@ -18,5 +18,5 @@ import { Context, FunctionsTable, Expression, StringPaths, RequireOnlyOne } from './evaluator';

}
export declare type RuleFunc<C, ConsequencePayload> = (param: any, context: C) => (void | ResolvedConsequence<ConsequencePayload>);
export declare type RuleFunc<C, ConsequencePayload> = (param: any, context: C) => void | ResolvedConsequence<ConsequencePayload> | Promise<(void | ResolvedConsequence<ConsequencePayload>)>;
export declare type RuleFunctionsTable<C, ConsequencePayload> = Record<string, RuleFunc<C, ConsequencePayload>>;
export declare type RuleFunctionParam<ConsequencePayload, C extends Context, RF extends RuleFunctionsTable<C, ConsequencePayload>, K extends keyof RF> = Parameters<RF[K]>[0];
export declare type RuleFunctionParam<ConsequencePayload, C extends Context, RF extends RuleFunctionsTable<C, ConsequencePayload>, K extends keyof RF> = Awaited<Parameters<RF[K]>[0]>;
export declare type RuleFunctionsParams<ConsequencePayload, C extends Context, RF extends RuleFunctionsTable<C, ConsequencePayload>> = {

@@ -23,0 +23,0 @@ [K in keyof RF]: RuleFunctionParam<ConsequencePayload, C, RF, K>;

import { Object, String, Union } from 'ts-toolbelt';
import { Paths } from './paths';
import { NonNullable } from './required';
export declare type FuncCompareOp<C extends Context, F extends FunctionsTable<C>, K extends keyof F> = Parameters<F[K]>[0];
export declare type FuncCompareOp<C extends Context, F extends FunctionsTable<C>, K extends keyof F> = Awaited<Parameters<F[K]>[0]>;
export declare type StringPaths<O extends object, Ignore> = String.Join<Paths<O, [], Ignore | any[], string>, '.'>;

@@ -70,5 +70,5 @@ export declare type Primitive = string | number | boolean;

export declare type Expression<C extends Context, F extends FunctionsTable<C>, Ignore = never> = RequireOnlyOne<FullExpression<C, F, Ignore>>;
export declare type Func<T> = (param: any, context: T) => boolean;
export declare type Func<T> = (param: any, context: T) => boolean | Promise<boolean>;
export declare type FunctionsTable<T> = Record<string, Func<T>>;
export declare type Context = Record<string, any>;
export declare type ValidationContext<C extends Context, Ignore = never> = NonNullable<C, Ignore>;
{
"name": "json-expression-eval",
"version": "4.3.0",
"version": "5.0.0",
"description": "json serializable rule engine / boolean expression evaluator",

@@ -52,2 +52,3 @@ "main": "dist/index.js",

"@types/chai": "^4.2.16",
"@types/chai-as-promised": "^7.1.5",
"@types/mocha": "^8.2.2",

@@ -57,2 +58,3 @@ "@types/node": "^14.14.37",

"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"mocha": "^6.2.3",

@@ -59,0 +61,0 @@ "moment": "^2.29.1",

@@ -85,3 +85,3 @@ [![Npm Version](https://img.shields.io/npm/v/json-expression-eval.svg?style=popout)](https://www.npmjs.com/package/json-expression-eval)

const functionsTable: IExampleFunctionTable = {
countRange: ([min, max]: [min: number, max: number], ctx: { times: number | undefined }): boolean => {
countRange: async ([min, max]: [min: number, max: number], ctx: { times: number | undefined }): Promise<boolean> => {
return ctx.times === undefined ? false : ctx.times >= min && ctx.times < max;

@@ -119,8 +119,8 @@ },

new ExpressionHandler<IExampleContext, IExampleFunctionTable, IExampleContextIgnore>(expression, functionsTable);
handler.validate(validationContext); // Should not throw
console.log(handler.evaluate(context)); // true
await handler.validate(validationContext); // Should not throw
console.log(await handler.evaluate(context)); // true
// Example usage 2
validate<IExampleContext, IExampleFunctionTable, IExampleContextIgnore>(expression, validationContext, functionsTable); // Should not throw
console.log(evaluate<IExampleContext, IExampleFunctionTable, IExampleContextIgnore>(expression, context, functionsTable)); // true
await validate<IExampleContext, IExampleFunctionTable, IExampleContextIgnore>(expression, validationContext, functionsTable); // Should not throw
console.log(await evaluate<IExampleContext, IExampleFunctionTable, IExampleContextIgnore>(expression, context, functionsTable)); // true
```

@@ -134,3 +134,3 @@

- `not` - accepts another expressions
- `<user defined funcs>` - accepts any type of argument and evaluated by the user defined functions and the given context.
- `<user defined funcs>` - accepts any type of argument and evaluated by the user defined functions and the given context. Can be async.
- `<compare funcs>` - operates on one of the context properties and compares it to a given value.

@@ -214,3 +214,3 @@ - `{property: {op: value}}`

type IExampleRuleFunctionTable = {
userRule: (user: string, ctx: IExampleContext) => void | ResolvedConsequence<IExamplePayload>;
userRule: (user: string, ctx: IExampleContext) => Promise<void | ResolvedConsequence<IExamplePayload>>;
}

@@ -254,3 +254,3 @@

const ruleFunctionsTable: IExampleRuleFunctionTable = {
userRule: (user: string, ctx: IExampleContext): void | ResolvedConsequence<number> => {
userRule: async (user: string, ctx: IExampleContext): Promise<void | ResolvedConsequence<number>> => {
if (ctx.userId === user) {

@@ -299,10 +299,10 @@ return {

IExampleFunctionTable, IExampleContextIgnore>(functionsTable, ruleFunctionsTable);
engine.validate(rules, validationContext); // Should not throw
console.log(JSON.stringify(engine.evaluateAll(rules, context))); // [{"message":"user a@b.com should not equal a@b.com","custom":579}]
await engine.validate(rules, validationContext); // Should not throw
console.log(JSON.stringify(await engine.evaluateAll(rules, context))); // [{"message":"user a@b.com should not equal a@b.com","custom":579}]
// Example usage 2
validateRules<IExamplePayload, IExampleContext, IExampleRuleFunctionTable,
await validateRules<IExamplePayload, IExampleContext, IExampleRuleFunctionTable,
IExampleFunctionTable, IExampleContextIgnore>(rules, validationContext, functionsTable, ruleFunctionsTable); // Should not throw
console.log(JSON.stringify(evaluateRules<IExamplePayload, IExampleContext, IExampleRuleFunctionTable,
console.log(JSON.stringify(await evaluateRules<IExamplePayload, IExampleContext, IExampleRuleFunctionTable,
IExampleFunctionTable, IExampleContextIgnore>(rules, context, functionsTable, ruleFunctionsTable, false))); // [{"message":"user a@b.com should not equal a@b.com","custom":579}]
```

Sorry, the diff of this file is not supported yet