1 |
|
2 | let evaluate = (instance, field, props) => {
|
3 | let evaluator = instance[field.type];
|
4 | return typeof evaluator === 'function' && evaluator.call(instance, field, props);
|
5 | };
|
6 |
|
7 | /**
|
8 | * @typedef LogicalOperator
|
9 | * @property {string} type
|
10 | * @property {Array.<LogicalOperator|ComparisonOperator>} fields
|
11 | */
|
12 |
|
13 | /**
|
14 | * @typedef ComparisonOperator
|
15 | * @property {string} type
|
16 | * @property {string} key
|
17 | * @property {string|number|boolean} value
|
18 | */
|
19 |
|
20 | /**
|
21 | * expression evaluator will parse logical and comparison operators
|
22 | */
|
23 | class ExpressionEvaluator {
|
24 |
|
25 | /**
|
26 | * expects a single logical operator or comparison operator
|
27 | * @param {ComparisonOperator|LogicalOperator} q
|
28 | * @param {*} props
|
29 | */
|
30 | evaluate(q, props) {
|
31 | if (q === null || q === undefined) {
|
32 | return true;
|
33 | }
|
34 | if (q.hasOwnProperty('type')) {
|
35 | return evaluate(this, q, props);
|
36 | } else {
|
37 | return true;
|
38 | }
|
39 | }
|
40 |
|
41 | /**
|
42 | *
|
43 | * @param {LogicalOperator} query
|
44 | * @param {*} props
|
45 | * @returns {boolean}
|
46 | */
|
47 | and(query, props) {
|
48 | return query.fields.every(field => evaluate(this, field, props));
|
49 | }
|
50 | /**
|
51 | *
|
52 | * @param {LogicalOperator} query
|
53 | * @param {*} props
|
54 | * @returns {boolean}
|
55 | */
|
56 | or(query, props) {
|
57 | return query.fields.some(field => evaluate(this, field, props));
|
58 | }
|
59 | /**
|
60 | *
|
61 | * @param {ComparisonOperator} field
|
62 | * @param {*} props
|
63 | * @returns {boolean}
|
64 | */
|
65 | eq(field, props) {
|
66 | return field.value === props[field.key];
|
67 | }
|
68 |
|
69 | /**
|
70 | *
|
71 | * @param {ComparisonOperator} field
|
72 | * @param {*} props
|
73 | * @returns {boolean}
|
74 | */
|
75 | neq(field, props) {
|
76 | return field.value !== props[field.key];
|
77 | }
|
78 | }
|
79 |
|
80 | module.exports = new ExpressionEvaluator();
|