-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcombineAccessRules.js
49 lines (42 loc) · 1.44 KB
/
combineAccessRules.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Creates a single access rule from multiple where ALL conditions are met
const combineAccessRules = (rules, operationIsOr) => auth => {
// Resolve the rules by passing auth to each
// "resolved" is now either true, false or {}
const resolved = rules.map(rule => {
// Resolve functions
if (!!(rule && rule.constructor && rule.call && rule.apply)) {
return rule(auth);
}
return rule;
});
// For AND: if every rule is true, we return true
// For OR: if any rule is true, we return true
const checkedRules = operationIsOr
? resolved.some(rule => {
return rule === true;
})
: resolved.every(rule => {
return rule === true;
});
// If checkedRules is "true" either:
// - All AND rules were true
// - Some OR rules were true
if (checkedRules) {
return operationIsOr;
}
// If checkedRules is "false" either:
// - Some AND rules are false or {}
// - All OR rules are false
const graphQLWhereRules = resolved.filter(rule => typeof rule === "object");
// If we have where clauses, combine them and return a single where clause
if (graphQLWhereRules.length) {
return operationIsOr
? { OR: graphQLWhereRules }
: { AND: graphQLWhereRules };
}
// If no where clauses, All OR rules must be false
return false;
};
const and = (...rules) => combineAccessRules(rules, false);
const or = (...rules) => combineAccessRules(rules, true);
module.exports = { and, or };