Skip to content

Commit

Permalink
enhance type checking
Browse files Browse the repository at this point in the history
  • Loading branch information
regevbr committed Jun 9, 2018
1 parent 29d700f commit 749976f
Show file tree
Hide file tree
Showing 17 changed files with 131 additions and 134 deletions.
67 changes: 45 additions & 22 deletions dist/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function isGtOp(op, key) {
return op[key].gt !== undefined;
}
function isGteOp(op, key) {
return op[key].gte !== undefined;
}
function isLteOp(op, key) {
return op[key].lte !== undefined;
}
function isLtOp(op, key) {
return op[key].lt !== undefined;
}
function isEqOp(op, key) {
return op[key].eq !== undefined;
}
function isNeqOp(op, key) {
return op[key].neq !== undefined;
}
function isAndOp(expression) {
return expression.and !== undefined;
}
Expand All @@ -9,35 +27,40 @@ function isOrOp(expression) {
function isNotOp(expression) {
return expression.not !== undefined;
}
function isFuncOp(expression, key, functionsTable) {
return key in functionsTable;
}
const _isObject = (obj) => {
const type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
const _evaluateCompareOp = (op, param) => {
if (!_isObject(op)) {
return param === op;
const _evaluateCompareOp = (op, key, param) => {
if (!_isObject(op[key])) {
return param === op[key];
}
const keys = Object.keys(op);
const keys = Object.keys(op[key]);
if (keys.length !== 1) {
throw new Error('Invalid expression - too may keys');
}
const key = keys[0];
const value = op[key];
switch (key) {
case 'gt':
return param > value;
case 'gte':
return param >= value;
case 'lt':
return param < value;
case 'lte':
return param <= value;
case 'eq':
return param === value;
case 'neq':
return param !== value;
if (isGtOp(op, key)) {
return param > op[key].gt;
}
else if (isGteOp(op, key)) {
return param >= op[key].gte;
}
else if (isLteOp(op, key)) {
return param <= op[key].lte;
}
else if (isLtOp(op, key)) {
return param < op[key].lt;
}
else if (isEqOp(op, key)) {
return param === op[key].eq;
}
else if (isNeqOp(op, key)) {
return param !== op[key].neq;
}
throw new Error(`Invalid expression - unknown op ${key}`);
throw new Error(`Invalid expression - unknown op ${keys[0]}`);
};
exports.evaluate = (expression, context, functionsTable) => {
const _evaluate = (_expression) => {
Expand Down Expand Up @@ -74,11 +97,11 @@ exports.evaluate = (expression, context, functionsTable) => {
const notExpression = _expression.not;
return !_evaluate(notExpression);
}
else if (key in functionsTable) {
else if (isFuncOp(_expression, key, functionsTable)) {
return functionsTable[key](_expression[key], context);
}
else if (key in context) {
return _evaluateCompareOp(_expression[key], context[key]);
return _evaluateCompareOp(_expression, key, context[key]);
}
throw new Error(`Invalid expression - unknown function ${key}`);
};
Expand Down
2 changes: 1 addition & 1 deletion example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let context = {
times: 3
};
let expression = {
user: '[email protected]'
user: '[email protected]',
};
run(expression, context);
expression = {
Expand Down
2 changes: 1 addition & 1 deletion example/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ let context: ExpressionContext = {
};

let expression: Expression = {
user: '[email protected]'
user: '[email protected]',
};

run(expression, context);
Expand Down
2 changes: 1 addition & 1 deletion example/lib/evaluator.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Expression } from "../../dist";
import { Expression } from '../../dist';
export interface ExpressionContext {
userId: string;
times: number;
Expand Down
4 changes: 2 additions & 2 deletions example/lib/evaluator.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const functionsFactory_1 = require("./functionsFactory");
const index_1 = require("./../../dist/index");
const dist_1 = require("../../dist");
exports.evaluate = (expression, context) => {
return index_1.evaluate(expression, context, functionsFactory_1.functionsTable);
return dist_1.evaluate(expression, context, functionsFactory_1.functionsTable);
};
6 changes: 2 additions & 4 deletions example/lib/evaluator.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"use strict";

import {Expression} from "../../dist";

import { functionsTable } from './functionsFactory';
import { evaluate as _evaluate } from './../../dist/index';
import {functionsTable} from './functionsFactory';
import {evaluate as _evaluate, Expression} from '../../dist';

export interface ExpressionContext {
userId: string;
Expand Down
5 changes: 3 additions & 2 deletions example/lib/functions/counterFunc.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import { FuncFactory } from "../functionsFactory";
export declare const factory: FuncFactory;
export declare const counterFunc: (maxCount: number, context: {
times: number;
}) => boolean;
10 changes: 2 additions & 8 deletions example/lib/functions/counterFunc.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const desc = {
name: 'maxCount',
evaluate: (maxCount, context) => {
return context.times < maxCount;
},
};
exports.factory = () => {
return desc;
exports.counterFunc = (maxCount, context) => {
return context.times < maxCount;
};
12 changes: 2 additions & 10 deletions example/lib/functions/counterFunc.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
'use strict';

import {FuncFactory, FunctionDescription} from "../functionsFactory";

const desc = {
name: 'maxCount',
evaluate: (maxCount: number, context: { times: number }): boolean => {
return context.times < maxCount;
},
export const counterFunc = (maxCount: number, context: { times: number }): boolean => {
return context.times < maxCount;
};

export const factory: FuncFactory = (): FunctionDescription => {
return desc;
};
5 changes: 3 additions & 2 deletions example/lib/functions/userFunc.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import { FuncFactory } from "../functionsFactory";
export declare const factory: FuncFactory;
export declare const userFunc: (user: string, context: {
userId: string;
}) => boolean;
10 changes: 2 additions & 8 deletions example/lib/functions/userFunc.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const desc = {
name: 'user',
evaluate: (user, context) => {
return context.userId === user;
},
};
exports.factory = () => {
return desc;
exports.userFunc = (user, context) => {
return context.userId === user;
};
12 changes: 2 additions & 10 deletions example/lib/functions/userFunc.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
'use strict';

import {FuncFactory, FunctionDescription} from "../functionsFactory";

const desc = {
name: 'user',
evaluate: (user: string, context: { userId: string }): boolean => {
return context.userId === user;
},
export const userFunc = (user: string, context: { userId: string }): boolean => {
return context.userId === user;
};

export const factory: FuncFactory = (): FunctionDescription => {
return desc;
};
7 changes: 1 addition & 6 deletions example/lib/functionsFactory.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import { Func, FunctionsTable } from "../../dist";
import { FunctionsTable } from "../../dist";
import { ExpressionContext } from "./evaluator";
export interface FunctionDescription {
name: string;
evaluate: Func<ExpressionContext>;
}
export declare type FuncFactory = () => FunctionDescription;
declare const functionsTable: FunctionsTable<ExpressionContext>;
export { functionsTable };
13 changes: 4 additions & 9 deletions example/lib/functionsFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@
Object.defineProperty(exports, "__esModule", { value: true });
const userFunc_1 = require("./functions/userFunc");
const counterFunc_1 = require("./functions/counterFunc");
const functionsTable = {};
exports.functionsTable = functionsTable;
const _addFunction = (description) => {
if (functionsTable[description.name]) {
throw new Error(`Function with name ${description.name} already exists`);
}
functionsTable[description.name] = description.evaluate;
const functionsTable = {
user: userFunc_1.userFunc,
maxCount: counterFunc_1.counterFunc,
};
_addFunction(userFunc_1.factory());
_addFunction(counterFunc_1.factory());
exports.functionsTable = functionsTable;
27 changes: 7 additions & 20 deletions example/lib/functionsFactory.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
'use strict';

import {Func, FunctionsTable} from "../../dist";
import {FunctionsTable} from "../../dist";
import {ExpressionContext} from "./evaluator";
import {factory as userFuncFactory} from './functions/userFunc';
import {factory as counterFuncFactory} from './functions/counterFunc';
import {userFunc} from './functions/userFunc';
import {counterFunc} from './functions/counterFunc';

export interface FunctionDescription {
name: string;
evaluate: Func<ExpressionContext>;
}

export type FuncFactory = () => FunctionDescription;

const functionsTable: FunctionsTable<ExpressionContext> = {};

const _addFunction = (description: FunctionDescription) : void => {
if (functionsTable[description.name]) {
throw new Error(`Function with name ${description.name} already exists`);
}
functionsTable[description.name] = description.evaluate;
const functionsTable: FunctionsTable<ExpressionContext> = {
user: userFunc,
maxCount: counterFunc,
};

_addFunction(userFuncFactory());
_addFunction(counterFuncFactory());

export { functionsTable };
export {functionsTable};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "json-expression-eval",
"version": "1.1.2",
"version": "1.1.3",
"description": "evaluate a json described boolean expression using dynamic functions",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
Loading

0 comments on commit 749976f

Please sign in to comment.