@slates/provider 1.0.0-rc.22 → 1.0.0-rc.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +180 -63
- package/dist/index.d.cts +160 -96
- package/dist/index.d.ts +160 -96
- package/dist/index.module.js +177 -63
- package/package.json +2 -2
- package/src/action/action.ts +6 -88
- package/src/action/builder.ts +50 -46
- package/src/action/index.ts +1 -0
- package/src/action/trigger.ts +17 -60
- package/src/action/triggerGroup.ts +332 -0
- package/src/adapter/index.test.ts +35 -14
- package/src/auth/types.ts +8 -0
- package/src/module/resolveDefaultExport.test.ts +3 -3
- package/src/specification/slate.test.ts +105 -0
- package/src/specification/slate.ts +31 -3
- package/src/webhook/graph.ts +2 -2
- package/src/webhook/meta.ts +2 -2
package/src/action/trigger.ts
CHANGED
|
@@ -3,17 +3,11 @@ import type { SlateSpecification } from '../specification/specification';
|
|
|
3
3
|
import {
|
|
4
4
|
SlateAction,
|
|
5
5
|
type SlateActionParameters,
|
|
6
|
-
type SlatePollingOptions,
|
|
7
6
|
type SlateTriggerMappingHandler,
|
|
8
|
-
type
|
|
9
|
-
type SlateTriggerWebhookAutoRegistrationHandler,
|
|
10
|
-
type SlateTriggerWebhookAutoUnregistrationHandler,
|
|
11
|
-
type SlateTriggerWebhookRequestHandler,
|
|
12
|
-
type SlateWebhookHttpOptions
|
|
7
|
+
type SlateTriggerMatchesHandler
|
|
13
8
|
} from './action';
|
|
14
9
|
import { SlateActionBuilder } from './builder';
|
|
15
|
-
|
|
16
|
-
export let SlateDefaultPollingIntervalSeconds = 60 * 10;
|
|
10
|
+
import type { SlateTriggerGroup } from './triggerGroup';
|
|
17
11
|
|
|
18
12
|
export interface SlateTriggerParameters<
|
|
19
13
|
ConfigType extends {},
|
|
@@ -24,14 +18,9 @@ export interface SlateTriggerParameters<
|
|
|
24
18
|
}
|
|
25
19
|
> extends SlateActionParameters {
|
|
26
20
|
type: 'trigger';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
handleRequest?: SlateTriggerWebhookRequestHandler<ConfigType, AuthType, InputType>;
|
|
31
|
-
http?: SlateWebhookHttpOptions;
|
|
32
|
-
pollEvents?: SlateTriggerPollingHandler<ConfigType, AuthType, InputType>;
|
|
33
|
-
autoRegisterWebhook?: SlateTriggerWebhookAutoRegistrationHandler<ConfigType, AuthType>;
|
|
34
|
-
autoUnregisterWebhook?: SlateTriggerWebhookAutoUnregistrationHandler<ConfigType, AuthType>;
|
|
21
|
+
triggerGroup: SlateTriggerGroup<ConfigType, AuthType>;
|
|
22
|
+
matches: SlateTriggerMatchesHandler;
|
|
23
|
+
map: SlateTriggerMappingHandler<ConfigType, AuthType, InputType, OutputType>;
|
|
35
24
|
}
|
|
36
25
|
|
|
37
26
|
export class SlateTrigger<
|
|
@@ -42,14 +31,9 @@ export class SlateTrigger<
|
|
|
42
31
|
type: string;
|
|
43
32
|
}
|
|
44
33
|
> extends SlateAction<'trigger', ConfigType, AuthType, InputType, OutputType> {
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#handleRequest?: SlateTriggerWebhookRequestHandler<ConfigType, AuthType, InputType>;
|
|
49
|
-
#http?: SlateWebhookHttpOptions;
|
|
50
|
-
#pollEvents?: SlateTriggerPollingHandler<ConfigType, AuthType, InputType>;
|
|
51
|
-
#autoRegisterWebhook?: SlateTriggerWebhookAutoRegistrationHandler<ConfigType, AuthType>;
|
|
52
|
-
#autoUnregisterWebhook?: SlateTriggerWebhookAutoUnregistrationHandler<ConfigType, AuthType>;
|
|
34
|
+
#triggerGroup: SlateTriggerGroup<ConfigType, AuthType>;
|
|
35
|
+
#matches: SlateTriggerMatchesHandler;
|
|
36
|
+
#map: SlateTriggerMappingHandler<ConfigType, AuthType, InputType, OutputType>;
|
|
53
37
|
|
|
54
38
|
private constructor(
|
|
55
39
|
spec: SlateSpecification<ConfigType, AuthType>,
|
|
@@ -59,16 +43,9 @@ export class SlateTrigger<
|
|
|
59
43
|
) {
|
|
60
44
|
super('trigger', spec, inputSchema, outputSchema, params);
|
|
61
45
|
|
|
62
|
-
this.#
|
|
63
|
-
this.#
|
|
64
|
-
|
|
65
|
-
};
|
|
66
|
-
this.#handleEvent = params.handleEvent;
|
|
67
|
-
this.#handleRequest = params.handleRequest;
|
|
68
|
-
this.#http = params.http;
|
|
69
|
-
this.#pollEvents = params.pollEvents;
|
|
70
|
-
this.#autoRegisterWebhook = params.autoRegisterWebhook;
|
|
71
|
-
this.#autoUnregisterWebhook = params.autoUnregisterWebhook;
|
|
46
|
+
this.#triggerGroup = params.triggerGroup;
|
|
47
|
+
this.#matches = params.matches;
|
|
48
|
+
this.#map = params.map;
|
|
72
49
|
}
|
|
73
50
|
|
|
74
51
|
static create<ConfigType extends {}, AuthType extends {}>(
|
|
@@ -81,36 +58,16 @@ export class SlateTrigger<
|
|
|
81
58
|
});
|
|
82
59
|
}
|
|
83
60
|
|
|
84
|
-
get
|
|
85
|
-
return this.#
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
get source() {
|
|
89
|
-
return this.#source;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
get handleEvent() {
|
|
93
|
-
return this.#handleEvent;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
get handleRequest() {
|
|
97
|
-
return this.#handleRequest;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
get http() {
|
|
101
|
-
return this.#http;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
get pollEvents() {
|
|
105
|
-
return this.#pollEvents;
|
|
61
|
+
get triggerGroup() {
|
|
62
|
+
return this.#triggerGroup;
|
|
106
63
|
}
|
|
107
64
|
|
|
108
|
-
get
|
|
109
|
-
return this.#
|
|
65
|
+
get matches() {
|
|
66
|
+
return this.#matches;
|
|
110
67
|
}
|
|
111
68
|
|
|
112
|
-
get
|
|
113
|
-
return this.#
|
|
69
|
+
get map() {
|
|
70
|
+
return this.#map;
|
|
114
71
|
}
|
|
115
72
|
}
|
|
116
73
|
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { SlateContext } from '../context';
|
|
3
|
+
import { SlateDeclarationError } from '../error';
|
|
4
|
+
import type { SlateSpecification } from '../specification/specification';
|
|
5
|
+
import type { SlateWebhookHttpResponseInit } from './action';
|
|
6
|
+
|
|
7
|
+
export let SlateDefaultPollingIntervalSeconds = 60 * 10;
|
|
8
|
+
|
|
9
|
+
export type SlateTriggerRoutingMatcher = Record<string, any>;
|
|
10
|
+
|
|
11
|
+
export type SlateWebhookTargetOwnership = 'single_user' | 'multi_user';
|
|
12
|
+
|
|
13
|
+
export interface SlateWebhookTarget {
|
|
14
|
+
webhookTargetIdentifier: string;
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
metadata: Record<string, any>;
|
|
18
|
+
webhookTargetPayload: any;
|
|
19
|
+
targetOwnership: SlateWebhookTargetOwnership;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type SlateTriggerGroupRoutingMatchersHandler<
|
|
23
|
+
ConfigType extends {},
|
|
24
|
+
AuthType extends {}
|
|
25
|
+
> = (context: SlateContext<ConfigType, AuthType, {}>) => Promise<SlateTriggerRoutingMatcher[]>;
|
|
26
|
+
|
|
27
|
+
export type SlateTriggerGroupPollHandler<ConfigType extends {}, AuthType extends {}> = (
|
|
28
|
+
context: SlateContext<ConfigType, AuthType, { state: any | null }>
|
|
29
|
+
) => Promise<{
|
|
30
|
+
events: { payload: any; idempotencyKey?: string }[];
|
|
31
|
+
updatedState?: any;
|
|
32
|
+
}>;
|
|
33
|
+
|
|
34
|
+
export type SlateWebhookTargetListHandler<ConfigType extends {}, AuthType extends {}> = (
|
|
35
|
+
context: SlateContext<ConfigType, AuthType, { pageToken: any | null }>
|
|
36
|
+
) => Promise<{
|
|
37
|
+
targets: SlateWebhookTarget[];
|
|
38
|
+
nextPageToken: any | null;
|
|
39
|
+
}>;
|
|
40
|
+
|
|
41
|
+
export type SlateWebhookRegisterHandler<ConfigType extends {}, AuthType extends {}> = (
|
|
42
|
+
context: SlateContext<
|
|
43
|
+
ConfigType,
|
|
44
|
+
AuthType,
|
|
45
|
+
{
|
|
46
|
+
webhookTargetIdentifier: string;
|
|
47
|
+
webhookTargetPayload: any;
|
|
48
|
+
webhookUrl: string;
|
|
49
|
+
}
|
|
50
|
+
>
|
|
51
|
+
) => Promise<{
|
|
52
|
+
webhookRegistrationIdentifier: string;
|
|
53
|
+
webhookRegistrationPayload: any;
|
|
54
|
+
}>;
|
|
55
|
+
|
|
56
|
+
export type SlateWebhookUnregisterHandler<ConfigType extends {}, AuthType extends {}> = (
|
|
57
|
+
context: SlateContext<
|
|
58
|
+
ConfigType,
|
|
59
|
+
AuthType,
|
|
60
|
+
{
|
|
61
|
+
webhookRegistrationIdentifier: string;
|
|
62
|
+
webhookRegistrationPayload: any;
|
|
63
|
+
}
|
|
64
|
+
>
|
|
65
|
+
) => Promise<unknown>;
|
|
66
|
+
|
|
67
|
+
export type SlateWebhookManualSetupHandler<
|
|
68
|
+
FullConfigSchema extends z.ZodType<any> = z.ZodType<any>
|
|
69
|
+
> = (context: SlateContext<{}, {}, { webhookUrl: string }>) => Promise<{
|
|
70
|
+
webhookSetupDocument: string;
|
|
71
|
+
partialWebhookRegistrationPayload: Partial<z.infer<FullConfigSchema>>;
|
|
72
|
+
}>;
|
|
73
|
+
|
|
74
|
+
export type SlateWebhookManualFinishHandler<
|
|
75
|
+
UserConfigSchema extends z.ZodType<any> = z.ZodType<any>,
|
|
76
|
+
FullConfigSchema extends z.ZodType<any> = z.ZodType<any>
|
|
77
|
+
> = (
|
|
78
|
+
context: SlateContext<
|
|
79
|
+
{},
|
|
80
|
+
{},
|
|
81
|
+
{
|
|
82
|
+
webhookUrl: string;
|
|
83
|
+
partialWebhookRegistrationPayload: Partial<z.infer<FullConfigSchema>>;
|
|
84
|
+
userWebhookRegistrationPayload: z.infer<UserConfigSchema>;
|
|
85
|
+
}
|
|
86
|
+
>
|
|
87
|
+
) => Promise<{
|
|
88
|
+
webhookRegistrationPayload: z.infer<FullConfigSchema>;
|
|
89
|
+
}>;
|
|
90
|
+
|
|
91
|
+
export type SlateWebhookProcessHandler = (
|
|
92
|
+
context: SlateContext<
|
|
93
|
+
{},
|
|
94
|
+
{},
|
|
95
|
+
{
|
|
96
|
+
request: Request;
|
|
97
|
+
webhookRegistrationPayload: any;
|
|
98
|
+
}
|
|
99
|
+
>
|
|
100
|
+
) => Promise<{
|
|
101
|
+
events: {
|
|
102
|
+
matchers: SlateTriggerRoutingMatcher[];
|
|
103
|
+
payload: any;
|
|
104
|
+
idempotencyKey?: string;
|
|
105
|
+
}[];
|
|
106
|
+
response?: Response | SlateWebhookHttpResponseInit;
|
|
107
|
+
}>;
|
|
108
|
+
|
|
109
|
+
export interface SlateTriggerGroupPollingParameters<
|
|
110
|
+
ConfigType extends {},
|
|
111
|
+
AuthType extends {}
|
|
112
|
+
> {
|
|
113
|
+
intervalSeconds: number;
|
|
114
|
+
pollEvents: SlateTriggerGroupPollHandler<ConfigType, AuthType>;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface SlateTriggerGroupWebhookAutoRegistrationParameters<
|
|
118
|
+
ConfigType extends {},
|
|
119
|
+
AuthType extends {}
|
|
120
|
+
> {
|
|
121
|
+
webhookTargetList: SlateWebhookTargetListHandler<ConfigType, AuthType>;
|
|
122
|
+
webhookRegister: SlateWebhookRegisterHandler<ConfigType, AuthType>;
|
|
123
|
+
webhookUnregister: SlateWebhookUnregisterHandler<ConfigType, AuthType>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface SlateTriggerGroupWebhookManualRegistrationParameters<
|
|
127
|
+
UserConfigSchema extends z.ZodType<any> = z.ZodType<any>,
|
|
128
|
+
FullConfigSchema extends z.ZodType<any> = z.ZodType<any>
|
|
129
|
+
> {
|
|
130
|
+
userConfigSchema: UserConfigSchema;
|
|
131
|
+
fullConfigSchema: FullConfigSchema;
|
|
132
|
+
setup: SlateWebhookManualSetupHandler<FullConfigSchema>;
|
|
133
|
+
finish?: SlateWebhookManualFinishHandler<UserConfigSchema, FullConfigSchema>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface SlateTriggerGroupWebhookParameters<
|
|
137
|
+
ConfigType extends {},
|
|
138
|
+
AuthType extends {}
|
|
139
|
+
> {
|
|
140
|
+
autoRegistration?: SlateTriggerGroupWebhookAutoRegistrationParameters<ConfigType, AuthType>;
|
|
141
|
+
manualRegistration?: SlateTriggerGroupWebhookManualRegistrationParameters<any, any>;
|
|
142
|
+
process: SlateWebhookProcessHandler;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface SlateTriggerGroupCreateParameters<
|
|
146
|
+
InputType extends {} = Record<string, unknown>
|
|
147
|
+
> {
|
|
148
|
+
key: string;
|
|
149
|
+
name: string;
|
|
150
|
+
description?: string;
|
|
151
|
+
metadata?: Record<string, any>;
|
|
152
|
+
eventSchema?: z.ZodType<InputType>;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface SlateTriggerGroupParameters<
|
|
156
|
+
ConfigType extends {},
|
|
157
|
+
AuthType extends {},
|
|
158
|
+
InputType extends {} = Record<string, unknown>
|
|
159
|
+
> extends SlateTriggerGroupCreateParameters<InputType> {
|
|
160
|
+
source: 'polling' | 'webhook';
|
|
161
|
+
polling?: SlateTriggerGroupPollingParameters<ConfigType, AuthType>;
|
|
162
|
+
webhook?: SlateTriggerGroupWebhookParameters<ConfigType, AuthType>;
|
|
163
|
+
routingMatchers: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export class SlateTriggerGroup<
|
|
167
|
+
ConfigType extends {},
|
|
168
|
+
AuthType extends {},
|
|
169
|
+
InputType extends {} = Record<string, unknown>
|
|
170
|
+
> {
|
|
171
|
+
private constructor(
|
|
172
|
+
private readonly _spec: SlateSpecification<ConfigType, AuthType>,
|
|
173
|
+
private readonly _params: SlateTriggerGroupParameters<ConfigType, AuthType, InputType>
|
|
174
|
+
) {}
|
|
175
|
+
|
|
176
|
+
static create<
|
|
177
|
+
ConfigType extends {},
|
|
178
|
+
AuthType extends {},
|
|
179
|
+
InputType extends {} = Record<string, unknown>
|
|
180
|
+
>(
|
|
181
|
+
spec: SlateSpecification<ConfigType, AuthType>,
|
|
182
|
+
params: SlateTriggerGroupCreateParameters<InputType>
|
|
183
|
+
) {
|
|
184
|
+
return new SlateTriggerGroupBuilder(spec, params, p => new SlateTriggerGroup(spec, p));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
get spec() {
|
|
188
|
+
return this._spec;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
get key() {
|
|
192
|
+
return this._params.key;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
get name() {
|
|
196
|
+
return this._params.name;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
get description() {
|
|
200
|
+
return this._params.description;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
get metadata() {
|
|
204
|
+
return this._params.metadata;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
get eventSchema() {
|
|
208
|
+
return this._params.eventSchema ?? (z.object({}).passthrough() as z.ZodType<InputType>);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
get source() {
|
|
212
|
+
return this._params.source;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
get polling() {
|
|
216
|
+
return this._params.polling;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
get webhook() {
|
|
220
|
+
return this._params.webhook;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
get routingMatchers() {
|
|
224
|
+
return this._params.routingMatchers;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export class SlateTriggerGroupBuilder<
|
|
229
|
+
ConfigType extends {},
|
|
230
|
+
AuthType extends {},
|
|
231
|
+
InputType extends {} = Record<string, unknown>
|
|
232
|
+
> {
|
|
233
|
+
#source: 'polling' | 'webhook' | null = null;
|
|
234
|
+
#polling: SlateTriggerGroupPollingParameters<ConfigType, AuthType> | null = null;
|
|
235
|
+
#webhook: SlateTriggerGroupWebhookParameters<ConfigType, AuthType> | null = null;
|
|
236
|
+
#routingMatchers: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType> | null =
|
|
237
|
+
null;
|
|
238
|
+
|
|
239
|
+
constructor(
|
|
240
|
+
private readonly spec: SlateSpecification<ConfigType, AuthType>,
|
|
241
|
+
private readonly params: SlateTriggerGroupCreateParameters<InputType>,
|
|
242
|
+
private readonly factory: (
|
|
243
|
+
params: SlateTriggerGroupParameters<ConfigType, AuthType, InputType>
|
|
244
|
+
) => SlateTriggerGroup<ConfigType, AuthType, InputType>
|
|
245
|
+
) {}
|
|
246
|
+
|
|
247
|
+
polling(props: {
|
|
248
|
+
intervalSeconds?: number;
|
|
249
|
+
pollEvents: SlateTriggerGroupPollHandler<ConfigType, AuthType>;
|
|
250
|
+
}): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType> {
|
|
251
|
+
if (this.#source) {
|
|
252
|
+
throw new SlateDeclarationError('Trigger group invocation is already defined');
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
this.#source = 'polling';
|
|
256
|
+
this.#polling = {
|
|
257
|
+
intervalSeconds: props.intervalSeconds ?? SlateDefaultPollingIntervalSeconds,
|
|
258
|
+
pollEvents: props.pollEvents
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
webhook<
|
|
265
|
+
UserConfigSchema extends z.ZodType<any> = z.ZodType<any>,
|
|
266
|
+
FullConfigSchema extends z.ZodType<any> = z.ZodType<any>
|
|
267
|
+
>(props: {
|
|
268
|
+
autoRegistration?: SlateTriggerGroupWebhookAutoRegistrationParameters<
|
|
269
|
+
ConfigType,
|
|
270
|
+
AuthType
|
|
271
|
+
>;
|
|
272
|
+
manualRegistration?: SlateTriggerGroupWebhookManualRegistrationParameters<
|
|
273
|
+
UserConfigSchema,
|
|
274
|
+
FullConfigSchema
|
|
275
|
+
>;
|
|
276
|
+
process: SlateWebhookProcessHandler;
|
|
277
|
+
}): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType> {
|
|
278
|
+
if (this.#source) {
|
|
279
|
+
throw new SlateDeclarationError('Trigger group invocation is already defined');
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (!!props.autoRegistration === !!props.manualRegistration) {
|
|
283
|
+
throw new SlateDeclarationError(
|
|
284
|
+
'Webhook trigger groups require exactly one of autoRegistration or manualRegistration'
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
this.#source = 'webhook';
|
|
289
|
+
this.#webhook = {
|
|
290
|
+
autoRegistration: props.autoRegistration,
|
|
291
|
+
manualRegistration: props.manualRegistration,
|
|
292
|
+
process: props.process
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
return this;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
routingMatchers(
|
|
299
|
+
handler: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>
|
|
300
|
+
): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType> {
|
|
301
|
+
this.#routingMatchers = handler;
|
|
302
|
+
return this;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
build(): SlateTriggerGroup<ConfigType, AuthType, InputType> {
|
|
306
|
+
if (!this.#source) {
|
|
307
|
+
throw new SlateDeclarationError(
|
|
308
|
+
'Trigger group invocation (polling or webhook) is not defined'
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
if (!this.#routingMatchers) {
|
|
312
|
+
throw new SlateDeclarationError('Trigger group routing matchers handler is not defined');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return this.factory({
|
|
316
|
+
...this.params,
|
|
317
|
+
source: this.#source,
|
|
318
|
+
polling: this.#polling ?? undefined,
|
|
319
|
+
webhook: this.#webhook ?? undefined,
|
|
320
|
+
routingMatchers: this.#routingMatchers
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export let triggerGroup = <
|
|
326
|
+
ConfigType extends {},
|
|
327
|
+
AuthType extends {},
|
|
328
|
+
InputType extends {} = Record<string, unknown>
|
|
329
|
+
>(
|
|
330
|
+
spec: SlateSpecification<ConfigType, AuthType>,
|
|
331
|
+
params: SlateTriggerGroupCreateParameters<InputType>
|
|
332
|
+
) => SlateTriggerGroup.create(spec, params);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { SlateTool } from '../action/tool';
|
|
4
|
+
import { SlateTriggerGroup } from '../action/triggerGroup';
|
|
4
5
|
import { SlateAuth } from '../auth';
|
|
5
6
|
import { SlateConfig } from '../config';
|
|
6
7
|
import { Slate } from '../specification/slate';
|
|
@@ -41,6 +42,16 @@ describe('SlateAdapterSpec', () => {
|
|
|
41
42
|
}))
|
|
42
43
|
.build();
|
|
43
44
|
|
|
45
|
+
let emailTriggerGroup = SlateTriggerGroup.create(spec, {
|
|
46
|
+
key: 'emails',
|
|
47
|
+
name: 'Emails'
|
|
48
|
+
})
|
|
49
|
+
.polling({
|
|
50
|
+
pollEvents: async () => ({ events: [] })
|
|
51
|
+
})
|
|
52
|
+
.routingMatchers(async () => [])
|
|
53
|
+
.build();
|
|
54
|
+
|
|
44
55
|
let emailReceivedTrigger = gmailAdapterSpec
|
|
45
56
|
.trigger(spec, {
|
|
46
57
|
key: 'email_received',
|
|
@@ -48,13 +59,13 @@ describe('SlateAdapterSpec', () => {
|
|
|
48
59
|
})
|
|
49
60
|
.input(z.object({ messageId: z.string() }))
|
|
50
61
|
.output(z.object({ type: z.literal('email.received') }))
|
|
51
|
-
.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
})
|
|
62
|
+
.triggerGroup(emailTriggerGroup)
|
|
63
|
+
.matches(() => true)
|
|
64
|
+
.map(async ctx => ({
|
|
65
|
+
type: 'email.received',
|
|
66
|
+
id: ctx.input.messageId,
|
|
67
|
+
output: { type: 'email.received' as const }
|
|
68
|
+
}))
|
|
58
69
|
.build();
|
|
59
70
|
|
|
60
71
|
expect(sendEmailTool.adapter).toBe('gmail');
|
|
@@ -218,6 +229,16 @@ describe('SlateAdapterSpec', () => {
|
|
|
218
229
|
}))
|
|
219
230
|
.build();
|
|
220
231
|
|
|
232
|
+
let sendEmailTriggerGroup = SlateTriggerGroup.create(spec, {
|
|
233
|
+
key: 'sent_emails',
|
|
234
|
+
name: 'Sent Emails'
|
|
235
|
+
})
|
|
236
|
+
.polling({
|
|
237
|
+
pollEvents: async () => ({ events: [] })
|
|
238
|
+
})
|
|
239
|
+
.routingMatchers(async () => [])
|
|
240
|
+
.build();
|
|
241
|
+
|
|
221
242
|
let sendEmailTrigger = gmailAdapterSpec
|
|
222
243
|
.trigger(spec, {
|
|
223
244
|
key: 'send_email',
|
|
@@ -225,13 +246,13 @@ describe('SlateAdapterSpec', () => {
|
|
|
225
246
|
})
|
|
226
247
|
.input(z.object({}))
|
|
227
248
|
.output(z.object({ type: z.string() }))
|
|
228
|
-
.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
})
|
|
249
|
+
.triggerGroup(sendEmailTriggerGroup)
|
|
250
|
+
.matches(() => true)
|
|
251
|
+
.map(async () => ({
|
|
252
|
+
type: 'email.sent',
|
|
253
|
+
id: '1',
|
|
254
|
+
output: { type: 'email.sent' }
|
|
255
|
+
}))
|
|
235
256
|
.build();
|
|
236
257
|
|
|
237
258
|
expect(() =>
|
package/src/auth/types.ts
CHANGED
|
@@ -22,6 +22,8 @@ export type SlateAuthWithOauth<
|
|
|
22
22
|
scope: string;
|
|
23
23
|
}[];
|
|
24
24
|
|
|
25
|
+
adapters?: string[];
|
|
26
|
+
|
|
25
27
|
docs?: SlateAuthDocsReference[];
|
|
26
28
|
|
|
27
29
|
inputSchema?: z.ZodType<InputType>;
|
|
@@ -92,6 +94,8 @@ export type SlateAuthWithToken<InputType extends {}, OutputType extends { token?
|
|
|
92
94
|
name: string;
|
|
93
95
|
key: string;
|
|
94
96
|
|
|
97
|
+
adapters?: string[];
|
|
98
|
+
|
|
95
99
|
inputSchema?: z.ZodType<InputType>;
|
|
96
100
|
|
|
97
101
|
docs?: SlateAuthDocsReference[];
|
|
@@ -124,6 +128,8 @@ export type SlateAuthWithServiceAccount<InputType extends {}, OutputType extends
|
|
|
124
128
|
name: string;
|
|
125
129
|
key: string;
|
|
126
130
|
|
|
131
|
+
adapters?: string[];
|
|
132
|
+
|
|
127
133
|
inputSchema?: z.ZodType<InputType>;
|
|
128
134
|
|
|
129
135
|
docs?: SlateAuthDocsReference[];
|
|
@@ -156,6 +162,8 @@ export type SlateAuthWithCustomData<InputType extends {}, OutputType extends {}>
|
|
|
156
162
|
name: string;
|
|
157
163
|
key: string;
|
|
158
164
|
|
|
165
|
+
adapters?: string[];
|
|
166
|
+
|
|
159
167
|
inputSchema?: z.ZodType<InputType>;
|
|
160
168
|
|
|
161
169
|
docs?: SlateAuthDocsReference[];
|
|
@@ -19,9 +19,9 @@ describe('resolveDefaultExport', () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it('unwraps nested default exports from double-bundling', () => {
|
|
22
|
-
expect(
|
|
23
|
-
|
|
24
|
-
)
|
|
22
|
+
expect(resolveDefaultExport<typeof Example>({ default: { default: Example } })).toBe(
|
|
23
|
+
Example
|
|
24
|
+
);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it('throws when the export is not a constructor', () => {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { SlateTrigger, SlateTriggerGroup } from '../action';
|
|
4
|
+
import { SlateAuth } from '../auth';
|
|
5
|
+
import { SlateConfig } from '../config';
|
|
6
|
+
import { Slate } from './slate';
|
|
7
|
+
import { SlateSpecification } from './specification';
|
|
8
|
+
|
|
9
|
+
let createTestSpec = () => {
|
|
10
|
+
let config = SlateConfig.create(z.object({}));
|
|
11
|
+
let auth = SlateAuth.create<{}>().output(z.object({}));
|
|
12
|
+
|
|
13
|
+
return SlateSpecification.create({
|
|
14
|
+
key: 'demo',
|
|
15
|
+
name: 'Demo',
|
|
16
|
+
config,
|
|
17
|
+
auth
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let createManualWebhookTriggerGroup = (spec: ReturnType<typeof createTestSpec>, key: string) =>
|
|
22
|
+
SlateTriggerGroup.create(spec, {
|
|
23
|
+
key,
|
|
24
|
+
name: key
|
|
25
|
+
})
|
|
26
|
+
.webhook({
|
|
27
|
+
manualRegistration: {
|
|
28
|
+
userConfigSchema: z.object({}),
|
|
29
|
+
fullConfigSchema: z.object({}),
|
|
30
|
+
setup: async () => ({
|
|
31
|
+
webhookSetupDocument: '',
|
|
32
|
+
partialWebhookRegistrationPayload: {}
|
|
33
|
+
})
|
|
34
|
+
},
|
|
35
|
+
process: async () => ({ events: [] })
|
|
36
|
+
})
|
|
37
|
+
.routingMatchers(async () => [])
|
|
38
|
+
.build();
|
|
39
|
+
|
|
40
|
+
let createAutoWebhookTriggerGroup = (spec: ReturnType<typeof createTestSpec>, key: string) =>
|
|
41
|
+
SlateTriggerGroup.create(spec, {
|
|
42
|
+
key,
|
|
43
|
+
name: key
|
|
44
|
+
})
|
|
45
|
+
.webhook({
|
|
46
|
+
autoRegistration: {
|
|
47
|
+
webhookTargetList: async () => ({ targets: [], nextPageToken: null }),
|
|
48
|
+
webhookRegister: async () => ({
|
|
49
|
+
webhookRegistrationIdentifier: 'reg',
|
|
50
|
+
webhookRegistrationPayload: {}
|
|
51
|
+
}),
|
|
52
|
+
webhookUnregister: async () => {}
|
|
53
|
+
},
|
|
54
|
+
process: async () => ({ events: [] })
|
|
55
|
+
})
|
|
56
|
+
.routingMatchers(async () => [])
|
|
57
|
+
.build();
|
|
58
|
+
|
|
59
|
+
describe('Slate.create', () => {
|
|
60
|
+
it('rejects more than one manual webhook trigger group', () => {
|
|
61
|
+
let spec = createTestSpec();
|
|
62
|
+
let first = createManualWebhookTriggerGroup(spec, 'manual_one');
|
|
63
|
+
let second = createManualWebhookTriggerGroup(spec, 'manual_two');
|
|
64
|
+
|
|
65
|
+
expect(() =>
|
|
66
|
+
Slate.create({
|
|
67
|
+
spec,
|
|
68
|
+
tools: [],
|
|
69
|
+
triggers: [],
|
|
70
|
+
triggerGroups: [first, second]
|
|
71
|
+
})
|
|
72
|
+
).toThrow(
|
|
73
|
+
'Only one trigger group may use manual webhook registration, but found: manual_one, manual_two'
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('allows a single manual webhook trigger group alongside other trigger groups', () => {
|
|
78
|
+
let spec = createTestSpec();
|
|
79
|
+
let manual = createManualWebhookTriggerGroup(spec, 'manual_group');
|
|
80
|
+
let auto = createAutoWebhookTriggerGroup(spec, 'auto_group');
|
|
81
|
+
|
|
82
|
+
let manualTrigger = SlateTrigger.create(spec, {
|
|
83
|
+
key: 'manual_trigger',
|
|
84
|
+
name: 'Manual Trigger'
|
|
85
|
+
})
|
|
86
|
+
.input(z.object({}))
|
|
87
|
+
.output(z.object({ type: z.literal('demo') }))
|
|
88
|
+
.triggerGroup(manual)
|
|
89
|
+
.matches(() => true)
|
|
90
|
+
.map(async () => ({ type: 'demo', id: '1', output: { type: 'demo' as const } }))
|
|
91
|
+
.build();
|
|
92
|
+
|
|
93
|
+
let slate = Slate.create({
|
|
94
|
+
spec,
|
|
95
|
+
tools: [],
|
|
96
|
+
triggers: [manualTrigger],
|
|
97
|
+
triggerGroups: [manual, auto]
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
expect(slate.triggerGroups.map(group => group.key)).toEqual([
|
|
101
|
+
'manual_group',
|
|
102
|
+
'auto_group'
|
|
103
|
+
]);
|
|
104
|
+
});
|
|
105
|
+
});
|