Skip to content

Commit 0b25980

Browse files
committed
1 parent cf6ffe0 commit 0b25980

File tree

2 files changed

+67
-23
lines changed

2 files changed

+67
-23
lines changed

src/validation.js

+37-23
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ import {
88
} from "./utils";
99
import { OR, AND, NOT } from "./constants";
1010

11+
const UNSUPPORTED_PREDICATES = [
12+
"and",
13+
"or",
14+
"ternary",
15+
"every",
16+
"some",
17+
"curry",
18+
"partial",
19+
"complement",
20+
"mod",
21+
];
22+
1123
export function predicatesFromRule(rule, schema) {
1224
if (isObject(rule)) {
1325
return flatMap(Object.keys(rule), p => {
@@ -80,18 +92,6 @@ export function listAllPredicates(conditions, schema) {
8092
return allPredicates.filter((v, i, a) => allPredicates.indexOf(v) === i);
8193
}
8294

83-
const UNSUPPORTED_PREDICATES = [
84-
"and",
85-
"or",
86-
"ternary",
87-
"every",
88-
"some",
89-
"curry",
90-
"partial",
91-
"complement",
92-
"mod",
93-
];
94-
9595
export function listInvalidPredicates(conditions, schema) {
9696
let refPredicates = listAllPredicates(conditions, schema);
9797
return refPredicates.filter(
@@ -106,30 +106,44 @@ export function validatePredicates(conditions, schema) {
106106
}
107107
}
108108

109+
export function fieldsFromPredicates(predicate) {
110+
if (Array.isArray(predicate)) {
111+
return flatMap(predicate, fieldsFromPredicates);
112+
} else if (isObject(predicate)) {
113+
return flatMap(Object.keys(predicate), field => {
114+
let predicateValue = predicate[field];
115+
return fieldsFromPredicates(predicateValue);
116+
});
117+
} else if (typeof predicate === "string" && predicate.startsWith("$")) {
118+
return [predicate.substr(1)];
119+
} else {
120+
return [];
121+
}
122+
}
123+
109124
export function fieldsFromCondition(condition) {
110125
return flatMap(Object.keys(condition), ref => {
126+
let refCondition = condition[ref];
111127
if (ref === OR || ref === AND) {
112-
return flatMap(condition[ref], w => fieldsFromCondition(w));
128+
return flatMap(refCondition, fieldsFromCondition);
113129
} else if (ref === NOT) {
114-
return fieldsFromCondition(condition[ref]);
115-
} else if (ref.indexOf(".") === -1) {
116-
return [ref];
130+
return fieldsFromCondition(refCondition);
117131
} else {
118-
return [];
132+
return [ref].concat(fieldsFromPredicates(refCondition));
119133
}
120134
});
121135
}
122136

123137
export function listAllFields(conditions) {
124-
let allFields = flatMap(conditions, condition =>
125-
fieldsFromCondition(condition)
126-
);
127-
return allFields.filter((v, i, a) => allFields.indexOf(v) === i);
138+
let allFields = flatMap(conditions, fieldsFromCondition);
139+
return allFields
140+
.filter(field => field.indexOf(".") === -1)
141+
.filter((v, i, a) => allFields.indexOf(v) === i);
128142
}
129143

130144
export function listInvalidFields(conditions, schema) {
131-
let ruleFields = listAllFields(conditions);
132-
return ruleFields.filter(field => schema.properties[field] === undefined);
145+
let allFields = listAllFields(conditions);
146+
return allFields.filter(field => schema.properties[field] === undefined);
133147
}
134148

135149
export function validateConditionFields(conditions, schema) {

test/issues/14.test.js

+30
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,33 @@ test("complicated rules work", () => {
3535
expect(events[0]).toEqual({ type: "match" });
3636
});
3737
});
38+
39+
test("validation rel fields work", () => {
40+
let rules = [
41+
{
42+
conditions: {
43+
a: { less: "$b" },
44+
},
45+
event: "some",
46+
},
47+
];
48+
49+
let invSchema = {
50+
type: "object",
51+
properties: {
52+
a: { type: "object" },
53+
},
54+
};
55+
56+
expect(() => new Engine(rules, invSchema)).toThrow();
57+
58+
let valSchema = {
59+
type: "object",
60+
properties: {
61+
a: { type: "object" },
62+
b: { type: "number" },
63+
},
64+
};
65+
66+
expect(() => new Engine(rules, valSchema)).not.toBeUndefined();
67+
});

0 commit comments

Comments
 (0)