forked from CopilotKit/CopilotKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconditions.ts
More file actions
116 lines (103 loc) · 3.06 KB
/
Copy pathconditions.ts
File metadata and controls
116 lines (103 loc) · 3.06 KB
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
export type ComparisonRule =
| "EQUALS"
| "NOT_EQUALS"
| "GREATER_THAN"
| "LESS_THAN"
| "CONTAINS"
| "NOT_CONTAINS"
| "MATCHES"
| "STARTS_WITH"
| "ENDS_WITH";
export type LogicalRule = "AND" | "OR" | "NOT";
export type ExistenceRule = "EXISTS" | "NOT_EXISTS";
export type Rule = ComparisonRule | LogicalRule | ExistenceRule;
export interface BaseCondition {
rule: Rule;
path?: string;
}
export interface ComparisonCondition extends BaseCondition {
rule: ComparisonRule;
value: any;
}
export interface LogicalCondition extends BaseCondition {
rule: LogicalRule;
conditions: Condition[];
}
export interface ExistenceCondition extends BaseCondition {
rule: ExistenceRule;
}
export type Condition =
| ComparisonCondition
| LogicalCondition
| ExistenceCondition;
export function executeConditions({
conditions,
value,
}: {
conditions?: Condition[];
value: any;
}): boolean {
// If no conditions, consider it a pass
if (!conditions?.length) return true;
// Run all conditions (implicit AND)
return conditions.every((condition) => executeCondition(condition, value));
}
function executeCondition(condition: Condition, value: any): boolean {
const targetValue = condition.path
? getValueFromPath(value, condition.path)
: value;
switch (condition.rule) {
// Logical
case "AND":
return (condition as LogicalCondition).conditions.every((c) =>
executeCondition(c, value),
);
case "OR":
return (condition as LogicalCondition).conditions.some((c) =>
executeCondition(c, value),
);
case "NOT":
return !(condition as LogicalCondition).conditions.every((c) =>
executeCondition(c, value),
);
// Comparison
case "EQUALS":
return targetValue === (condition as ComparisonCondition).value;
case "NOT_EQUALS":
return targetValue !== (condition as ComparisonCondition).value;
case "GREATER_THAN":
return targetValue > (condition as ComparisonCondition).value;
case "LESS_THAN":
return targetValue < (condition as ComparisonCondition).value;
case "CONTAINS":
return (
Array.isArray(targetValue) &&
targetValue.includes((condition as ComparisonCondition).value)
);
case "NOT_CONTAINS":
return (
Array.isArray(targetValue) &&
!targetValue.includes((condition as ComparisonCondition).value)
);
case "MATCHES":
return new RegExp((condition as ComparisonCondition).value).test(
String(targetValue),
);
case "STARTS_WITH":
return String(targetValue).startsWith(
(condition as ComparisonCondition).value,
);
case "ENDS_WITH":
return String(targetValue).endsWith(
(condition as ComparisonCondition).value,
);
// Existence
case "EXISTS":
return targetValue !== undefined && targetValue !== null;
case "NOT_EXISTS":
return targetValue === undefined || targetValue === null;
}
}
function getValueFromPath(obj: any, path: string): any {
return path.split(".").reduce((acc, part) => acc?.[part], obj);
}