-
Notifications
You must be signed in to change notification settings - Fork 230
Expand file tree
/
Copy pathand.ts
More file actions
127 lines (103 loc) · 3.73 KB
/
and.ts
File metadata and controls
127 lines (103 loc) · 3.73 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
117
118
119
120
121
122
123
124
125
126
127
import { z } from "zod";
import { AutomodTriggerBlueprint, AutomodTriggerMatchResult, automodTrigger } from "../helpers.js";
import type { AutomodContext } from "../types.js";
interface AndTriggerMatchPart {
triggerName: string;
triggerConfig: unknown;
matchResult: AutomodTriggerMatchResult;
}
interface AndTriggerMatchResultExtra {
matches: AndTriggerMatchPart[];
}
interface CreateAndTriggerOpts {
getAvailableTriggers: () => Record<string, AutomodTriggerBlueprint<any, any>>;
}
export function createAndTrigger({ getAvailableTriggers }: CreateAndTriggerOpts) {
const triggerConfigSchema = z.lazy(() => {
const triggers = getAvailableTriggers();
const schemaShape: Record<string, z.ZodTypeAny> = {};
for (const [triggerName, trigger] of Object.entries(triggers)) {
schemaShape[triggerName] = trigger.configSchema;
}
return z
.strictObject(schemaShape)
.partial()
.refine((val) => Object.values(val).some((v) => v !== undefined), {
message: "Each sub-trigger must specify at least one trigger",
});
});
return automodTrigger<AndTriggerMatchResultExtra>()({
configSchema: z.object({
triggers: z.array(triggerConfigSchema).min(1),
}),
async match({ ruleName, pluginData, context, triggerConfig }) {
const matches: AndTriggerMatchPart[] = [];
for (const subTriggerItem of triggerConfig.triggers) {
const definedEntries = Object.entries(subTriggerItem).filter(([, v]) => v !== undefined);
if (definedEntries.length < 1) {
return null;
}
let matchedEntry: AndTriggerMatchPart | null = null;
for (const [subTriggerName, subTriggerConfig] of definedEntries) {
const subTrigger = getAvailableTriggers()[subTriggerName];
if (!subTrigger) {
continue;
}
const subMatch = await subTrigger.match({
ruleName,
pluginData,
context,
triggerConfig: subTriggerConfig,
});
if (subMatch) {
matchedEntry = {
triggerName: subTriggerName,
triggerConfig: subTriggerConfig,
matchResult: subMatch,
};
break;
}
}
if (!matchedEntry) {
return null;
}
matches.push(matchedEntry);
}
if (matches.length === 0) {
return null;
}
const extraContexts = matches.flatMap((match) => match.matchResult.extraContexts ?? []);
const silentClean = matches.some((match) => match.matchResult.silentClean);
return {
extraContexts: extraContexts.length > 0 ? extraContexts : undefined,
silentClean: silentClean || undefined,
extra: { matches },
};
},
async renderMatchInformation({ ruleName, pluginData, contexts, matchResult }) {
const availableTriggers = getAvailableTriggers();
const parts = await Promise.all(
matchResult.extra.matches.map(async (match) => {
const trigger = availableTriggers[match.triggerName];
if (!trigger) {
return match.triggerName;
}
const triggerContexts: AutomodContext[] = [contexts[0], ...(match.matchResult.extraContexts ?? [])];
return (
(await trigger.renderMatchInformation({
ruleName,
pluginData,
contexts: triggerContexts,
triggerConfig: match.triggerConfig as never,
matchResult: match.matchResult,
})) ?? match.triggerName
);
}),
);
if (parts.length === 1) {
return parts[0];
}
return `All ${parts.length} triggers matched:\n${parts.map((part) => `- ${part}`).join("\n")}`;
},
});
}