@slates/test 1.0.0-rc.27 → 1.0.0-rc.28
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 +28 -7
- package/dist/index.d.cts +140 -6
- package/dist/index.d.ts +140 -6
- package/dist/index.module.js +25 -7
- package/package.json +4 -4
- package/src/runtime.ts +45 -14
- package/src/triggerLifecycle.test.ts +561 -0
package/dist/index.cjs
CHANGED
|
@@ -20,10 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
authenticateSlateTriggerGroupWebhookDelivery: () => authenticateSlateTriggerGroupWebhookDelivery,
|
|
23
24
|
connectSlateTriggerGroupGateway: () => connectSlateTriggerGroupGateway,
|
|
24
25
|
createLocalSlateTestClient: () => createLocalSlateTestClient,
|
|
25
26
|
createSlatesTestClient: () => createSlatesTestClient,
|
|
26
27
|
describeMcpCompatibleToolSchemas: () => describeMcpCompatibleToolSchemas,
|
|
28
|
+
expandSlateTriggerGroupWebhook: () => expandSlateTriggerGroupWebhook,
|
|
27
29
|
expectMcpCompatibleToolSchema: () => expectMcpCompatibleToolSchema,
|
|
28
30
|
expectSlateContract: () => expectSlateContract,
|
|
29
31
|
expectSlateError: () => expectSlateError,
|
|
@@ -38,6 +40,7 @@ __export(index_exports, {
|
|
|
38
40
|
processSlateTriggerGroupWebhook: () => processSlateTriggerGroupWebhook,
|
|
39
41
|
receiveSlateTriggerGroupGatewayFrames: () => receiveSlateTriggerGroupGatewayFrames,
|
|
40
42
|
registerSlateTriggerGroupWebhook: () => registerSlateTriggerGroupWebhook,
|
|
43
|
+
renewSlateTriggerGroupWebhook: () => renewSlateTriggerGroupWebhook,
|
|
41
44
|
unregisterSlateTriggerGroupWebhook: () => unregisterSlateTriggerGroupWebhook,
|
|
42
45
|
withSlateProfile: () => withSlateProfile
|
|
43
46
|
});
|
|
@@ -255,17 +258,24 @@ var expectSlateContract = async (d) => {
|
|
|
255
258
|
}
|
|
256
259
|
return contract;
|
|
257
260
|
};
|
|
258
|
-
var registerSlateTriggerGroupWebhook = async (d) =>
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
261
|
+
var registerSlateTriggerGroupWebhook = async (d) => {
|
|
262
|
+
let { client, ...input } = d;
|
|
263
|
+
return client.registerTriggerGroupWebhook(input);
|
|
264
|
+
};
|
|
265
|
+
var renewSlateTriggerGroupWebhook = async (d) => {
|
|
266
|
+
let { client, ...input } = d;
|
|
267
|
+
return client.renewTriggerGroupWebhook(input);
|
|
268
|
+
};
|
|
269
|
+
var expandSlateTriggerGroupWebhook = async (d) => {
|
|
270
|
+
let { client, ...input } = d;
|
|
271
|
+
return client.expandTriggerGroupWebhook(input);
|
|
272
|
+
};
|
|
264
273
|
var pollSlateTriggerGroupEvents = async (d) => {
|
|
265
274
|
d.client.ensureSession();
|
|
266
275
|
return d.client.pollTriggerGroup({
|
|
267
276
|
triggerGroupId: d.triggerGroupId,
|
|
268
|
-
state: d.state ?? null
|
|
277
|
+
state: d.state ?? null,
|
|
278
|
+
selection: d.selection
|
|
269
279
|
});
|
|
270
280
|
};
|
|
271
281
|
var connectSlateTriggerGroupGateway = async (d) => {
|
|
@@ -292,6 +302,14 @@ var processSlateTriggerGroupWebhook = async (d) => d.client.processTriggerGroupW
|
|
|
292
302
|
body: d.body,
|
|
293
303
|
webhookRegistrationPayload: d.webhookRegistrationPayload ?? null
|
|
294
304
|
});
|
|
305
|
+
var authenticateSlateTriggerGroupWebhookDelivery = async (d) => d.client.authenticateTriggerGroupWebhookDelivery({
|
|
306
|
+
triggerGroupId: d.triggerGroupId,
|
|
307
|
+
url: d.url,
|
|
308
|
+
method: d.method ?? "POST",
|
|
309
|
+
headers: d.headers,
|
|
310
|
+
body: d.body,
|
|
311
|
+
deliveryConfig: d.deliveryConfig
|
|
312
|
+
});
|
|
295
313
|
var unregisterSlateTriggerGroupWebhook = async (d) => d.client.unregisterTriggerGroupWebhook({
|
|
296
314
|
triggerGroupId: d.triggerGroupId,
|
|
297
315
|
webhookRegistrationIdentifier: d.webhookRegistrationIdentifier,
|
|
@@ -14885,10 +14903,12 @@ var describeMcpCompatibleToolSchemas = (name, source) => {
|
|
|
14885
14903
|
};
|
|
14886
14904
|
// Annotate the CommonJS export names for ESM import in node:
|
|
14887
14905
|
0 && (module.exports = {
|
|
14906
|
+
authenticateSlateTriggerGroupWebhookDelivery,
|
|
14888
14907
|
connectSlateTriggerGroupGateway,
|
|
14889
14908
|
createLocalSlateTestClient,
|
|
14890
14909
|
createSlatesTestClient,
|
|
14891
14910
|
describeMcpCompatibleToolSchemas,
|
|
14911
|
+
expandSlateTriggerGroupWebhook,
|
|
14892
14912
|
expectMcpCompatibleToolSchema,
|
|
14893
14913
|
expectSlateContract,
|
|
14894
14914
|
expectSlateError,
|
|
@@ -14903,6 +14923,7 @@ var describeMcpCompatibleToolSchemas = (name, source) => {
|
|
|
14903
14923
|
processSlateTriggerGroupWebhook,
|
|
14904
14924
|
receiveSlateTriggerGroupGatewayFrames,
|
|
14905
14925
|
registerSlateTriggerGroupWebhook,
|
|
14926
|
+
renewSlateTriggerGroupWebhook,
|
|
14906
14927
|
unregisterSlateTriggerGroupWebhook,
|
|
14907
14928
|
withSlateProfile
|
|
14908
14929
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -246,14 +246,22 @@ declare let getSlateContract: (client: SlatesTestClient) => Promise<{
|
|
|
246
246
|
type: "webhook";
|
|
247
247
|
registration: {
|
|
248
248
|
mode: "auto";
|
|
249
|
+
deliveryConfig?: {
|
|
250
|
+
userConfigSchema: Record<string, any>;
|
|
251
|
+
fullConfigSchema: Record<string, any>;
|
|
252
|
+
} | undefined;
|
|
249
253
|
} | {
|
|
250
254
|
mode: "manual";
|
|
251
255
|
userConfigSchema: Record<string, any>;
|
|
252
256
|
fullConfigSchema: Record<string, any>;
|
|
253
257
|
};
|
|
258
|
+
supportsExpansion?: boolean | undefined;
|
|
259
|
+
supportsRenewal?: boolean | undefined;
|
|
260
|
+
reconcileIntervalSeconds?: number | undefined;
|
|
254
261
|
};
|
|
255
262
|
description?: string | undefined;
|
|
256
263
|
metadata?: Record<string, any> | undefined;
|
|
264
|
+
selectionSchema?: Record<string, any> | undefined;
|
|
257
265
|
}[];
|
|
258
266
|
authMethods: {
|
|
259
267
|
id: string;
|
|
@@ -445,14 +453,22 @@ declare let expectSlateContract: (d: {
|
|
|
445
453
|
type: "webhook";
|
|
446
454
|
registration: {
|
|
447
455
|
mode: "auto";
|
|
456
|
+
deliveryConfig?: {
|
|
457
|
+
userConfigSchema: Record<string, any>;
|
|
458
|
+
fullConfigSchema: Record<string, any>;
|
|
459
|
+
} | undefined;
|
|
448
460
|
} | {
|
|
449
461
|
mode: "manual";
|
|
450
462
|
userConfigSchema: Record<string, any>;
|
|
451
463
|
fullConfigSchema: Record<string, any>;
|
|
452
464
|
};
|
|
465
|
+
supportsExpansion?: boolean | undefined;
|
|
466
|
+
supportsRenewal?: boolean | undefined;
|
|
467
|
+
reconcileIntervalSeconds?: number | undefined;
|
|
453
468
|
};
|
|
454
469
|
description?: string | undefined;
|
|
455
470
|
metadata?: Record<string, any> | undefined;
|
|
471
|
+
selectionSchema?: Record<string, any> | undefined;
|
|
456
472
|
}[];
|
|
457
473
|
authMethods: {
|
|
458
474
|
id: string;
|
|
@@ -495,13 +511,87 @@ declare let expectSlateContract: (d: {
|
|
|
495
511
|
}>;
|
|
496
512
|
declare let registerSlateTriggerGroupWebhook: (d: {
|
|
497
513
|
client: SlatesTestClient;
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
514
|
+
} & Parameters<SlatesTestClient["registerTriggerGroupWebhook"]>[0]) => Promise<{
|
|
515
|
+
webhookRegistrationIdentifier: string;
|
|
516
|
+
webhookRegistrationPayload: any;
|
|
517
|
+
expiresAt?: string | null | undefined;
|
|
518
|
+
renewAfter?: string | null | undefined;
|
|
519
|
+
routingKeys?: string[] | undefined;
|
|
520
|
+
requestTraces?: {
|
|
521
|
+
startedAt: string;
|
|
522
|
+
durationMs: number;
|
|
523
|
+
request: {
|
|
524
|
+
method: string;
|
|
525
|
+
url: string;
|
|
526
|
+
headers?: Record<string, string> | undefined;
|
|
527
|
+
body?: {
|
|
528
|
+
text: string;
|
|
529
|
+
contentType?: string | undefined;
|
|
530
|
+
truncated?: boolean | undefined;
|
|
531
|
+
} | undefined;
|
|
532
|
+
};
|
|
533
|
+
response?: {
|
|
534
|
+
status: number;
|
|
535
|
+
statusText?: string | undefined;
|
|
536
|
+
headers?: Record<string, string> | undefined;
|
|
537
|
+
body?: {
|
|
538
|
+
text: string;
|
|
539
|
+
contentType?: string | undefined;
|
|
540
|
+
truncated?: boolean | undefined;
|
|
541
|
+
} | undefined;
|
|
542
|
+
} | undefined;
|
|
543
|
+
error?: {
|
|
544
|
+
message: string;
|
|
545
|
+
code?: string | undefined;
|
|
546
|
+
} | undefined;
|
|
547
|
+
}[] | undefined;
|
|
548
|
+
}>;
|
|
549
|
+
declare let renewSlateTriggerGroupWebhook: (d: {
|
|
550
|
+
client: SlatesTestClient;
|
|
551
|
+
} & Parameters<SlatesTestClient["renewTriggerGroupWebhook"]>[0]) => Promise<{
|
|
503
552
|
webhookRegistrationIdentifier: string;
|
|
504
553
|
webhookRegistrationPayload: any;
|
|
554
|
+
expiresAt?: string | null | undefined;
|
|
555
|
+
renewAfter?: string | null | undefined;
|
|
556
|
+
routingKeys?: string[] | undefined;
|
|
557
|
+
requestTraces?: {
|
|
558
|
+
startedAt: string;
|
|
559
|
+
durationMs: number;
|
|
560
|
+
request: {
|
|
561
|
+
method: string;
|
|
562
|
+
url: string;
|
|
563
|
+
headers?: Record<string, string> | undefined;
|
|
564
|
+
body?: {
|
|
565
|
+
text: string;
|
|
566
|
+
contentType?: string | undefined;
|
|
567
|
+
truncated?: boolean | undefined;
|
|
568
|
+
} | undefined;
|
|
569
|
+
};
|
|
570
|
+
response?: {
|
|
571
|
+
status: number;
|
|
572
|
+
statusText?: string | undefined;
|
|
573
|
+
headers?: Record<string, string> | undefined;
|
|
574
|
+
body?: {
|
|
575
|
+
text: string;
|
|
576
|
+
contentType?: string | undefined;
|
|
577
|
+
truncated?: boolean | undefined;
|
|
578
|
+
} | undefined;
|
|
579
|
+
} | undefined;
|
|
580
|
+
error?: {
|
|
581
|
+
message: string;
|
|
582
|
+
code?: string | undefined;
|
|
583
|
+
} | undefined;
|
|
584
|
+
}[] | undefined;
|
|
585
|
+
}>;
|
|
586
|
+
declare let expandSlateTriggerGroupWebhook: (d: {
|
|
587
|
+
client: SlatesTestClient;
|
|
588
|
+
} & Parameters<SlatesTestClient["expandTriggerGroupWebhook"]>[0]) => Promise<{
|
|
589
|
+
events: {
|
|
590
|
+
payload: Record<string, any>;
|
|
591
|
+
triggerIds: string[];
|
|
592
|
+
idempotencyKey?: string | undefined;
|
|
593
|
+
}[];
|
|
594
|
+
updatedState?: any;
|
|
505
595
|
requestTraces?: {
|
|
506
596
|
startedAt: string;
|
|
507
597
|
durationMs: number;
|
|
@@ -535,6 +625,7 @@ declare let pollSlateTriggerGroupEvents: (d: {
|
|
|
535
625
|
client: SlatesTestClient;
|
|
536
626
|
triggerGroupId: string;
|
|
537
627
|
state?: any;
|
|
628
|
+
selection?: Record<string, any>;
|
|
538
629
|
}) => Promise<{
|
|
539
630
|
events: {
|
|
540
631
|
payload: Record<string, any>;
|
|
@@ -678,6 +769,7 @@ declare let processSlateTriggerGroupWebhook: (d: {
|
|
|
678
769
|
triggerIds: string[];
|
|
679
770
|
idempotencyKey?: string | undefined;
|
|
680
771
|
}[];
|
|
772
|
+
requiresExpansion?: boolean | undefined;
|
|
681
773
|
response?: {
|
|
682
774
|
status: number;
|
|
683
775
|
headers: Record<string, string>;
|
|
@@ -718,6 +810,48 @@ declare let processSlateTriggerGroupWebhook: (d: {
|
|
|
718
810
|
} | undefined;
|
|
719
811
|
}[] | undefined;
|
|
720
812
|
}>;
|
|
813
|
+
declare let authenticateSlateTriggerGroupWebhookDelivery: (d: {
|
|
814
|
+
client: SlatesTestClient;
|
|
815
|
+
triggerGroupId: string;
|
|
816
|
+
url: string;
|
|
817
|
+
method?: string;
|
|
818
|
+
headers?: Record<string, string>;
|
|
819
|
+
body?: string | Uint8Array | null;
|
|
820
|
+
deliveryConfig: unknown;
|
|
821
|
+
}) => Promise<{
|
|
822
|
+
routingKeys: string[];
|
|
823
|
+
rejected?: {
|
|
824
|
+
status: number;
|
|
825
|
+
} | null | undefined;
|
|
826
|
+
requestTraces?: {
|
|
827
|
+
startedAt: string;
|
|
828
|
+
durationMs: number;
|
|
829
|
+
request: {
|
|
830
|
+
method: string;
|
|
831
|
+
url: string;
|
|
832
|
+
headers?: Record<string, string> | undefined;
|
|
833
|
+
body?: {
|
|
834
|
+
text: string;
|
|
835
|
+
contentType?: string | undefined;
|
|
836
|
+
truncated?: boolean | undefined;
|
|
837
|
+
} | undefined;
|
|
838
|
+
};
|
|
839
|
+
response?: {
|
|
840
|
+
status: number;
|
|
841
|
+
statusText?: string | undefined;
|
|
842
|
+
headers?: Record<string, string> | undefined;
|
|
843
|
+
body?: {
|
|
844
|
+
text: string;
|
|
845
|
+
contentType?: string | undefined;
|
|
846
|
+
truncated?: boolean | undefined;
|
|
847
|
+
} | undefined;
|
|
848
|
+
} | undefined;
|
|
849
|
+
error?: {
|
|
850
|
+
message: string;
|
|
851
|
+
code?: string | undefined;
|
|
852
|
+
} | undefined;
|
|
853
|
+
}[] | undefined;
|
|
854
|
+
}>;
|
|
721
855
|
declare let unregisterSlateTriggerGroupWebhook: (d: {
|
|
722
856
|
client: SlatesTestClient;
|
|
723
857
|
triggerGroupId: string;
|
|
@@ -805,4 +939,4 @@ declare let getMcpCompatibleToolSchemaCases: (source: ToolSchemaSource) => Reado
|
|
|
805
939
|
declare let expectMcpCompatibleToolSchema: (tool: ToolSchemaTarget) => void;
|
|
806
940
|
declare let describeMcpCompatibleToolSchemas: (name: string, source: ToolSchemaSource) => void;
|
|
807
941
|
|
|
808
|
-
export { type ExpectedSlateAction, type ExpectedSlateTriggerGroup, type SlatesRuntimeContext, type SlatesTestClient, connectSlateTriggerGroupGateway, createLocalSlateTestClient, createSlatesTestClient, describeMcpCompatibleToolSchemas, expectMcpCompatibleToolSchema, expectSlateContract, expectSlateError, expectToolCall, getMcpCompatibleToolSchemaCases, getSlateContract, getVitestExpect, loadSlatesProfile, loadSlatesRuntimeContext, mapSlateTriggerEvent, pollSlateTriggerGroupEvents, processSlateTriggerGroupWebhook, receiveSlateTriggerGroupGatewayFrames, registerSlateTriggerGroupWebhook, unregisterSlateTriggerGroupWebhook, withSlateProfile };
|
|
942
|
+
export { type ExpectedSlateAction, type ExpectedSlateTriggerGroup, type SlatesRuntimeContext, type SlatesTestClient, authenticateSlateTriggerGroupWebhookDelivery, connectSlateTriggerGroupGateway, createLocalSlateTestClient, createSlatesTestClient, describeMcpCompatibleToolSchemas, expandSlateTriggerGroupWebhook, expectMcpCompatibleToolSchema, expectSlateContract, expectSlateError, expectToolCall, getMcpCompatibleToolSchemaCases, getSlateContract, getVitestExpect, loadSlatesProfile, loadSlatesRuntimeContext, mapSlateTriggerEvent, pollSlateTriggerGroupEvents, processSlateTriggerGroupWebhook, receiveSlateTriggerGroupGatewayFrames, registerSlateTriggerGroupWebhook, renewSlateTriggerGroupWebhook, unregisterSlateTriggerGroupWebhook, withSlateProfile };
|
package/dist/index.d.ts
CHANGED
|
@@ -246,14 +246,22 @@ declare let getSlateContract: (client: SlatesTestClient) => Promise<{
|
|
|
246
246
|
type: "webhook";
|
|
247
247
|
registration: {
|
|
248
248
|
mode: "auto";
|
|
249
|
+
deliveryConfig?: {
|
|
250
|
+
userConfigSchema: Record<string, any>;
|
|
251
|
+
fullConfigSchema: Record<string, any>;
|
|
252
|
+
} | undefined;
|
|
249
253
|
} | {
|
|
250
254
|
mode: "manual";
|
|
251
255
|
userConfigSchema: Record<string, any>;
|
|
252
256
|
fullConfigSchema: Record<string, any>;
|
|
253
257
|
};
|
|
258
|
+
supportsExpansion?: boolean | undefined;
|
|
259
|
+
supportsRenewal?: boolean | undefined;
|
|
260
|
+
reconcileIntervalSeconds?: number | undefined;
|
|
254
261
|
};
|
|
255
262
|
description?: string | undefined;
|
|
256
263
|
metadata?: Record<string, any> | undefined;
|
|
264
|
+
selectionSchema?: Record<string, any> | undefined;
|
|
257
265
|
}[];
|
|
258
266
|
authMethods: {
|
|
259
267
|
id: string;
|
|
@@ -445,14 +453,22 @@ declare let expectSlateContract: (d: {
|
|
|
445
453
|
type: "webhook";
|
|
446
454
|
registration: {
|
|
447
455
|
mode: "auto";
|
|
456
|
+
deliveryConfig?: {
|
|
457
|
+
userConfigSchema: Record<string, any>;
|
|
458
|
+
fullConfigSchema: Record<string, any>;
|
|
459
|
+
} | undefined;
|
|
448
460
|
} | {
|
|
449
461
|
mode: "manual";
|
|
450
462
|
userConfigSchema: Record<string, any>;
|
|
451
463
|
fullConfigSchema: Record<string, any>;
|
|
452
464
|
};
|
|
465
|
+
supportsExpansion?: boolean | undefined;
|
|
466
|
+
supportsRenewal?: boolean | undefined;
|
|
467
|
+
reconcileIntervalSeconds?: number | undefined;
|
|
453
468
|
};
|
|
454
469
|
description?: string | undefined;
|
|
455
470
|
metadata?: Record<string, any> | undefined;
|
|
471
|
+
selectionSchema?: Record<string, any> | undefined;
|
|
456
472
|
}[];
|
|
457
473
|
authMethods: {
|
|
458
474
|
id: string;
|
|
@@ -495,13 +511,87 @@ declare let expectSlateContract: (d: {
|
|
|
495
511
|
}>;
|
|
496
512
|
declare let registerSlateTriggerGroupWebhook: (d: {
|
|
497
513
|
client: SlatesTestClient;
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
514
|
+
} & Parameters<SlatesTestClient["registerTriggerGroupWebhook"]>[0]) => Promise<{
|
|
515
|
+
webhookRegistrationIdentifier: string;
|
|
516
|
+
webhookRegistrationPayload: any;
|
|
517
|
+
expiresAt?: string | null | undefined;
|
|
518
|
+
renewAfter?: string | null | undefined;
|
|
519
|
+
routingKeys?: string[] | undefined;
|
|
520
|
+
requestTraces?: {
|
|
521
|
+
startedAt: string;
|
|
522
|
+
durationMs: number;
|
|
523
|
+
request: {
|
|
524
|
+
method: string;
|
|
525
|
+
url: string;
|
|
526
|
+
headers?: Record<string, string> | undefined;
|
|
527
|
+
body?: {
|
|
528
|
+
text: string;
|
|
529
|
+
contentType?: string | undefined;
|
|
530
|
+
truncated?: boolean | undefined;
|
|
531
|
+
} | undefined;
|
|
532
|
+
};
|
|
533
|
+
response?: {
|
|
534
|
+
status: number;
|
|
535
|
+
statusText?: string | undefined;
|
|
536
|
+
headers?: Record<string, string> | undefined;
|
|
537
|
+
body?: {
|
|
538
|
+
text: string;
|
|
539
|
+
contentType?: string | undefined;
|
|
540
|
+
truncated?: boolean | undefined;
|
|
541
|
+
} | undefined;
|
|
542
|
+
} | undefined;
|
|
543
|
+
error?: {
|
|
544
|
+
message: string;
|
|
545
|
+
code?: string | undefined;
|
|
546
|
+
} | undefined;
|
|
547
|
+
}[] | undefined;
|
|
548
|
+
}>;
|
|
549
|
+
declare let renewSlateTriggerGroupWebhook: (d: {
|
|
550
|
+
client: SlatesTestClient;
|
|
551
|
+
} & Parameters<SlatesTestClient["renewTriggerGroupWebhook"]>[0]) => Promise<{
|
|
503
552
|
webhookRegistrationIdentifier: string;
|
|
504
553
|
webhookRegistrationPayload: any;
|
|
554
|
+
expiresAt?: string | null | undefined;
|
|
555
|
+
renewAfter?: string | null | undefined;
|
|
556
|
+
routingKeys?: string[] | undefined;
|
|
557
|
+
requestTraces?: {
|
|
558
|
+
startedAt: string;
|
|
559
|
+
durationMs: number;
|
|
560
|
+
request: {
|
|
561
|
+
method: string;
|
|
562
|
+
url: string;
|
|
563
|
+
headers?: Record<string, string> | undefined;
|
|
564
|
+
body?: {
|
|
565
|
+
text: string;
|
|
566
|
+
contentType?: string | undefined;
|
|
567
|
+
truncated?: boolean | undefined;
|
|
568
|
+
} | undefined;
|
|
569
|
+
};
|
|
570
|
+
response?: {
|
|
571
|
+
status: number;
|
|
572
|
+
statusText?: string | undefined;
|
|
573
|
+
headers?: Record<string, string> | undefined;
|
|
574
|
+
body?: {
|
|
575
|
+
text: string;
|
|
576
|
+
contentType?: string | undefined;
|
|
577
|
+
truncated?: boolean | undefined;
|
|
578
|
+
} | undefined;
|
|
579
|
+
} | undefined;
|
|
580
|
+
error?: {
|
|
581
|
+
message: string;
|
|
582
|
+
code?: string | undefined;
|
|
583
|
+
} | undefined;
|
|
584
|
+
}[] | undefined;
|
|
585
|
+
}>;
|
|
586
|
+
declare let expandSlateTriggerGroupWebhook: (d: {
|
|
587
|
+
client: SlatesTestClient;
|
|
588
|
+
} & Parameters<SlatesTestClient["expandTriggerGroupWebhook"]>[0]) => Promise<{
|
|
589
|
+
events: {
|
|
590
|
+
payload: Record<string, any>;
|
|
591
|
+
triggerIds: string[];
|
|
592
|
+
idempotencyKey?: string | undefined;
|
|
593
|
+
}[];
|
|
594
|
+
updatedState?: any;
|
|
505
595
|
requestTraces?: {
|
|
506
596
|
startedAt: string;
|
|
507
597
|
durationMs: number;
|
|
@@ -535,6 +625,7 @@ declare let pollSlateTriggerGroupEvents: (d: {
|
|
|
535
625
|
client: SlatesTestClient;
|
|
536
626
|
triggerGroupId: string;
|
|
537
627
|
state?: any;
|
|
628
|
+
selection?: Record<string, any>;
|
|
538
629
|
}) => Promise<{
|
|
539
630
|
events: {
|
|
540
631
|
payload: Record<string, any>;
|
|
@@ -678,6 +769,7 @@ declare let processSlateTriggerGroupWebhook: (d: {
|
|
|
678
769
|
triggerIds: string[];
|
|
679
770
|
idempotencyKey?: string | undefined;
|
|
680
771
|
}[];
|
|
772
|
+
requiresExpansion?: boolean | undefined;
|
|
681
773
|
response?: {
|
|
682
774
|
status: number;
|
|
683
775
|
headers: Record<string, string>;
|
|
@@ -718,6 +810,48 @@ declare let processSlateTriggerGroupWebhook: (d: {
|
|
|
718
810
|
} | undefined;
|
|
719
811
|
}[] | undefined;
|
|
720
812
|
}>;
|
|
813
|
+
declare let authenticateSlateTriggerGroupWebhookDelivery: (d: {
|
|
814
|
+
client: SlatesTestClient;
|
|
815
|
+
triggerGroupId: string;
|
|
816
|
+
url: string;
|
|
817
|
+
method?: string;
|
|
818
|
+
headers?: Record<string, string>;
|
|
819
|
+
body?: string | Uint8Array | null;
|
|
820
|
+
deliveryConfig: unknown;
|
|
821
|
+
}) => Promise<{
|
|
822
|
+
routingKeys: string[];
|
|
823
|
+
rejected?: {
|
|
824
|
+
status: number;
|
|
825
|
+
} | null | undefined;
|
|
826
|
+
requestTraces?: {
|
|
827
|
+
startedAt: string;
|
|
828
|
+
durationMs: number;
|
|
829
|
+
request: {
|
|
830
|
+
method: string;
|
|
831
|
+
url: string;
|
|
832
|
+
headers?: Record<string, string> | undefined;
|
|
833
|
+
body?: {
|
|
834
|
+
text: string;
|
|
835
|
+
contentType?: string | undefined;
|
|
836
|
+
truncated?: boolean | undefined;
|
|
837
|
+
} | undefined;
|
|
838
|
+
};
|
|
839
|
+
response?: {
|
|
840
|
+
status: number;
|
|
841
|
+
statusText?: string | undefined;
|
|
842
|
+
headers?: Record<string, string> | undefined;
|
|
843
|
+
body?: {
|
|
844
|
+
text: string;
|
|
845
|
+
contentType?: string | undefined;
|
|
846
|
+
truncated?: boolean | undefined;
|
|
847
|
+
} | undefined;
|
|
848
|
+
} | undefined;
|
|
849
|
+
error?: {
|
|
850
|
+
message: string;
|
|
851
|
+
code?: string | undefined;
|
|
852
|
+
} | undefined;
|
|
853
|
+
}[] | undefined;
|
|
854
|
+
}>;
|
|
721
855
|
declare let unregisterSlateTriggerGroupWebhook: (d: {
|
|
722
856
|
client: SlatesTestClient;
|
|
723
857
|
triggerGroupId: string;
|
|
@@ -805,4 +939,4 @@ declare let getMcpCompatibleToolSchemaCases: (source: ToolSchemaSource) => Reado
|
|
|
805
939
|
declare let expectMcpCompatibleToolSchema: (tool: ToolSchemaTarget) => void;
|
|
806
940
|
declare let describeMcpCompatibleToolSchemas: (name: string, source: ToolSchemaSource) => void;
|
|
807
941
|
|
|
808
|
-
export { type ExpectedSlateAction, type ExpectedSlateTriggerGroup, type SlatesRuntimeContext, type SlatesTestClient, connectSlateTriggerGroupGateway, createLocalSlateTestClient, createSlatesTestClient, describeMcpCompatibleToolSchemas, expectMcpCompatibleToolSchema, expectSlateContract, expectSlateError, expectToolCall, getMcpCompatibleToolSchemaCases, getSlateContract, getVitestExpect, loadSlatesProfile, loadSlatesRuntimeContext, mapSlateTriggerEvent, pollSlateTriggerGroupEvents, processSlateTriggerGroupWebhook, receiveSlateTriggerGroupGatewayFrames, registerSlateTriggerGroupWebhook, unregisterSlateTriggerGroupWebhook, withSlateProfile };
|
|
942
|
+
export { type ExpectedSlateAction, type ExpectedSlateTriggerGroup, type SlatesRuntimeContext, type SlatesTestClient, authenticateSlateTriggerGroupWebhookDelivery, connectSlateTriggerGroupGateway, createLocalSlateTestClient, createSlatesTestClient, describeMcpCompatibleToolSchemas, expandSlateTriggerGroupWebhook, expectMcpCompatibleToolSchema, expectSlateContract, expectSlateError, expectToolCall, getMcpCompatibleToolSchemaCases, getSlateContract, getVitestExpect, loadSlatesProfile, loadSlatesRuntimeContext, mapSlateTriggerEvent, pollSlateTriggerGroupEvents, processSlateTriggerGroupWebhook, receiveSlateTriggerGroupGatewayFrames, registerSlateTriggerGroupWebhook, renewSlateTriggerGroupWebhook, unregisterSlateTriggerGroupWebhook, withSlateProfile };
|
package/dist/index.module.js
CHANGED
|
@@ -223,17 +223,24 @@ var expectSlateContract = async (d) => {
|
|
|
223
223
|
}
|
|
224
224
|
return contract;
|
|
225
225
|
};
|
|
226
|
-
var registerSlateTriggerGroupWebhook = async (d) =>
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
226
|
+
var registerSlateTriggerGroupWebhook = async (d) => {
|
|
227
|
+
let { client, ...input } = d;
|
|
228
|
+
return client.registerTriggerGroupWebhook(input);
|
|
229
|
+
};
|
|
230
|
+
var renewSlateTriggerGroupWebhook = async (d) => {
|
|
231
|
+
let { client, ...input } = d;
|
|
232
|
+
return client.renewTriggerGroupWebhook(input);
|
|
233
|
+
};
|
|
234
|
+
var expandSlateTriggerGroupWebhook = async (d) => {
|
|
235
|
+
let { client, ...input } = d;
|
|
236
|
+
return client.expandTriggerGroupWebhook(input);
|
|
237
|
+
};
|
|
232
238
|
var pollSlateTriggerGroupEvents = async (d) => {
|
|
233
239
|
d.client.ensureSession();
|
|
234
240
|
return d.client.pollTriggerGroup({
|
|
235
241
|
triggerGroupId: d.triggerGroupId,
|
|
236
|
-
state: d.state ?? null
|
|
242
|
+
state: d.state ?? null,
|
|
243
|
+
selection: d.selection
|
|
237
244
|
});
|
|
238
245
|
};
|
|
239
246
|
var connectSlateTriggerGroupGateway = async (d) => {
|
|
@@ -260,6 +267,14 @@ var processSlateTriggerGroupWebhook = async (d) => d.client.processTriggerGroupW
|
|
|
260
267
|
body: d.body,
|
|
261
268
|
webhookRegistrationPayload: d.webhookRegistrationPayload ?? null
|
|
262
269
|
});
|
|
270
|
+
var authenticateSlateTriggerGroupWebhookDelivery = async (d) => d.client.authenticateTriggerGroupWebhookDelivery({
|
|
271
|
+
triggerGroupId: d.triggerGroupId,
|
|
272
|
+
url: d.url,
|
|
273
|
+
method: d.method ?? "POST",
|
|
274
|
+
headers: d.headers,
|
|
275
|
+
body: d.body,
|
|
276
|
+
deliveryConfig: d.deliveryConfig
|
|
277
|
+
});
|
|
263
278
|
var unregisterSlateTriggerGroupWebhook = async (d) => d.client.unregisterTriggerGroupWebhook({
|
|
264
279
|
triggerGroupId: d.triggerGroupId,
|
|
265
280
|
webhookRegistrationIdentifier: d.webhookRegistrationIdentifier,
|
|
@@ -14852,10 +14867,12 @@ var describeMcpCompatibleToolSchemas = (name, source) => {
|
|
|
14852
14867
|
});
|
|
14853
14868
|
};
|
|
14854
14869
|
export {
|
|
14870
|
+
authenticateSlateTriggerGroupWebhookDelivery,
|
|
14855
14871
|
connectSlateTriggerGroupGateway,
|
|
14856
14872
|
createLocalSlateTestClient,
|
|
14857
14873
|
createSlatesTestClient,
|
|
14858
14874
|
describeMcpCompatibleToolSchemas,
|
|
14875
|
+
expandSlateTriggerGroupWebhook,
|
|
14859
14876
|
expectMcpCompatibleToolSchema,
|
|
14860
14877
|
expectSlateContract,
|
|
14861
14878
|
expectSlateError,
|
|
@@ -14870,6 +14887,7 @@ export {
|
|
|
14870
14887
|
processSlateTriggerGroupWebhook,
|
|
14871
14888
|
receiveSlateTriggerGroupGatewayFrames,
|
|
14872
14889
|
registerSlateTriggerGroupWebhook,
|
|
14890
|
+
renewSlateTriggerGroupWebhook,
|
|
14873
14891
|
unregisterSlateTriggerGroupWebhook,
|
|
14874
14892
|
withSlateProfile
|
|
14875
14893
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slates/test",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.28",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@lowerdeck/testing-tools": "latest",
|
|
43
|
-
"@slates/client": "1.0.0-rc.
|
|
44
|
-
"@slates/profiles": "1.0.0-rc.
|
|
43
|
+
"@slates/client": "1.0.0-rc.33",
|
|
44
|
+
"@slates/profiles": "1.0.0-rc.29"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@slates/provider": "1.0.0-rc.
|
|
47
|
+
"@slates/provider": "1.0.0-rc.34",
|
|
48
48
|
"@slates/tsconfig": "1.0.0-rc.1",
|
|
49
49
|
"typescript": "5.8.2",
|
|
50
50
|
"vitest": "^3.1.2",
|
package/src/runtime.ts
CHANGED
|
@@ -352,29 +352,42 @@ export let expectSlateContract = async (d: {
|
|
|
352
352
|
return contract;
|
|
353
353
|
};
|
|
354
354
|
|
|
355
|
-
export let registerSlateTriggerGroupWebhook = async (
|
|
356
|
-
client: SlatesTestClient
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
355
|
+
export let registerSlateTriggerGroupWebhook = async (
|
|
356
|
+
d: { client: SlatesTestClient } & Parameters<
|
|
357
|
+
SlatesTestClient['registerTriggerGroupWebhook']
|
|
358
|
+
>[0]
|
|
359
|
+
) => {
|
|
360
|
+
let { client, ...input } = d;
|
|
361
|
+
return client.registerTriggerGroupWebhook(input);
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
export let renewSlateTriggerGroupWebhook = async (
|
|
365
|
+
d: { client: SlatesTestClient } & Parameters<SlatesTestClient['renewTriggerGroupWebhook']>[0]
|
|
366
|
+
) => {
|
|
367
|
+
let { client, ...input } = d;
|
|
368
|
+
return client.renewTriggerGroupWebhook(input);
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
export let expandSlateTriggerGroupWebhook = async (
|
|
372
|
+
d: { client: SlatesTestClient } & Parameters<
|
|
373
|
+
SlatesTestClient['expandTriggerGroupWebhook']
|
|
374
|
+
>[0]
|
|
375
|
+
) => {
|
|
376
|
+
let { client, ...input } = d;
|
|
377
|
+
return client.expandTriggerGroupWebhook(input);
|
|
378
|
+
};
|
|
368
379
|
|
|
369
380
|
export let pollSlateTriggerGroupEvents = async (d: {
|
|
370
381
|
client: SlatesTestClient;
|
|
371
382
|
triggerGroupId: string;
|
|
372
383
|
state?: any;
|
|
384
|
+
selection?: Record<string, any>;
|
|
373
385
|
}) => {
|
|
374
386
|
d.client.ensureSession();
|
|
375
387
|
return d.client.pollTriggerGroup({
|
|
376
388
|
triggerGroupId: d.triggerGroupId,
|
|
377
|
-
state: d.state ?? null
|
|
389
|
+
state: d.state ?? null,
|
|
390
|
+
selection: d.selection
|
|
378
391
|
});
|
|
379
392
|
};
|
|
380
393
|
|
|
@@ -424,6 +437,24 @@ export let processSlateTriggerGroupWebhook = async (d: {
|
|
|
424
437
|
webhookRegistrationPayload: d.webhookRegistrationPayload ?? null
|
|
425
438
|
});
|
|
426
439
|
|
|
440
|
+
export let authenticateSlateTriggerGroupWebhookDelivery = async (d: {
|
|
441
|
+
client: SlatesTestClient;
|
|
442
|
+
triggerGroupId: string;
|
|
443
|
+
url: string;
|
|
444
|
+
method?: string;
|
|
445
|
+
headers?: Record<string, string>;
|
|
446
|
+
body?: string | Uint8Array | null;
|
|
447
|
+
deliveryConfig: unknown;
|
|
448
|
+
}) =>
|
|
449
|
+
d.client.authenticateTriggerGroupWebhookDelivery({
|
|
450
|
+
triggerGroupId: d.triggerGroupId,
|
|
451
|
+
url: d.url,
|
|
452
|
+
method: d.method ?? 'POST',
|
|
453
|
+
headers: d.headers,
|
|
454
|
+
body: d.body,
|
|
455
|
+
deliveryConfig: d.deliveryConfig
|
|
456
|
+
});
|
|
457
|
+
|
|
427
458
|
export let unregisterSlateTriggerGroupWebhook = async (d: {
|
|
428
459
|
client: SlatesTestClient;
|
|
429
460
|
triggerGroupId: string;
|
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Slate,
|
|
3
|
+
SlateAuth,
|
|
4
|
+
SlateConfig,
|
|
5
|
+
SlateSpecification,
|
|
6
|
+
SlateTrigger,
|
|
7
|
+
triggerGroup
|
|
8
|
+
} from '@slates/provider';
|
|
9
|
+
import { describe, expect, it } from 'vitest';
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import {
|
|
12
|
+
authenticateSlateTriggerGroupWebhookDelivery,
|
|
13
|
+
createLocalSlateTestClient,
|
|
14
|
+
expandSlateTriggerGroupWebhook,
|
|
15
|
+
pollSlateTriggerGroupEvents,
|
|
16
|
+
processSlateTriggerGroupWebhook,
|
|
17
|
+
registerSlateTriggerGroupWebhook,
|
|
18
|
+
renewSlateTriggerGroupWebhook
|
|
19
|
+
} from './index';
|
|
20
|
+
|
|
21
|
+
let fixture = (
|
|
22
|
+
options: {
|
|
23
|
+
selection?: 'required' | 'default';
|
|
24
|
+
legacy?: boolean;
|
|
25
|
+
expiresAt?: string | null;
|
|
26
|
+
renewAfter?: string | null;
|
|
27
|
+
invalidExpansion?: boolean;
|
|
28
|
+
reconcileIntervalSeconds?: number;
|
|
29
|
+
deliveryConfig?: boolean;
|
|
30
|
+
} = {}
|
|
31
|
+
) => {
|
|
32
|
+
let contexts: { operation: string; auth: unknown; config: unknown; input: any }[] = [];
|
|
33
|
+
let auth = SlateAuth.create<{ token: string }>()
|
|
34
|
+
.output(z.object({ token: z.string() }))
|
|
35
|
+
.addTokenAuth({
|
|
36
|
+
type: 'auth.token',
|
|
37
|
+
key: 'token',
|
|
38
|
+
name: 'Token',
|
|
39
|
+
inputSchema: z.object({ token: z.string() }),
|
|
40
|
+
getOutput: async ctx => ({ output: ctx.input })
|
|
41
|
+
});
|
|
42
|
+
let spec = SlateSpecification.create({
|
|
43
|
+
key: 'lifecycle',
|
|
44
|
+
name: 'Lifecycle',
|
|
45
|
+
description: 'Trigger lifecycle contract',
|
|
46
|
+
auth,
|
|
47
|
+
config: SlateConfig.create(z.object({ tenant: z.string() }))
|
|
48
|
+
});
|
|
49
|
+
let selectionSchema =
|
|
50
|
+
options.selection === 'required'
|
|
51
|
+
? z.object({ resource: z.string() })
|
|
52
|
+
: options.selection === 'default'
|
|
53
|
+
? z.object({ resource: z.string().default('default-resource') })
|
|
54
|
+
: undefined;
|
|
55
|
+
let record = (operation: string, ctx: { auth: unknown; config: unknown; input: any }) => {
|
|
56
|
+
contexts.push({ operation, auth: ctx.auth, config: ctx.config, input: ctx.input });
|
|
57
|
+
};
|
|
58
|
+
let registration = {
|
|
59
|
+
webhookRegistrationIdentifier: 'registration',
|
|
60
|
+
webhookRegistrationPayload: { secret: 'verification' },
|
|
61
|
+
...(options.expiresAt !== undefined ? { expiresAt: options.expiresAt } : {}),
|
|
62
|
+
...(options.renewAfter !== undefined ? { renewAfter: options.renewAfter } : {})
|
|
63
|
+
};
|
|
64
|
+
let group = triggerGroup(spec, { key: 'webhook', name: 'Webhook', selectionSchema })
|
|
65
|
+
.webhook({
|
|
66
|
+
reconcileIntervalSeconds: options.reconcileIntervalSeconds,
|
|
67
|
+
deliveryConfig: options.deliveryConfig
|
|
68
|
+
? {
|
|
69
|
+
userConfigSchema: z.object({ topicName: z.string() }),
|
|
70
|
+
fullConfigSchema: z.object({ topicName: z.string(), audience: z.string() }),
|
|
71
|
+
setup: async ctx => {
|
|
72
|
+
record('setup', ctx);
|
|
73
|
+
return {
|
|
74
|
+
webhookSetupDocument: `Deliver to ${ctx.input.webhookUrl}`,
|
|
75
|
+
partialWebhookRegistrationPayload: {}
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
finish: async ctx => {
|
|
79
|
+
record('finish', ctx);
|
|
80
|
+
return {
|
|
81
|
+
webhookRegistrationPayload: {
|
|
82
|
+
...ctx.input.userWebhookRegistrationPayload,
|
|
83
|
+
audience: ctx.input.webhookUrl
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
authenticate: async ctx => {
|
|
88
|
+
record('authenticate', ctx);
|
|
89
|
+
let status = Number(ctx.input.request.headers.get('x-reject'));
|
|
90
|
+
if (status) return { rejected: { status } };
|
|
91
|
+
let body = JSON.parse(await ctx.input.request.text()) as { keys: string[] };
|
|
92
|
+
return { routingKeys: body.keys };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
: undefined,
|
|
96
|
+
autoRegistration: {
|
|
97
|
+
webhookTargetList: async ctx => {
|
|
98
|
+
record('targets', ctx);
|
|
99
|
+
return { targets: [], nextPageToken: null };
|
|
100
|
+
},
|
|
101
|
+
webhookRegister: async ctx => {
|
|
102
|
+
record('register', ctx);
|
|
103
|
+
return registration;
|
|
104
|
+
},
|
|
105
|
+
webhookRenew: options.legacy
|
|
106
|
+
? undefined
|
|
107
|
+
: async ctx => {
|
|
108
|
+
record('renew', ctx);
|
|
109
|
+
return {
|
|
110
|
+
...registration,
|
|
111
|
+
webhookRegistrationIdentifier: 'renewed-registration'
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
webhookUnregister: async () => {}
|
|
115
|
+
},
|
|
116
|
+
process: async ctx => {
|
|
117
|
+
record('process', ctx);
|
|
118
|
+
return {
|
|
119
|
+
events: [
|
|
120
|
+
{
|
|
121
|
+
payload: { raw: true },
|
|
122
|
+
matchers: [{ tenant: 'tenant' }],
|
|
123
|
+
idempotencyKey: 'raw-key'
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
expandWebhook: options.legacy
|
|
129
|
+
? undefined
|
|
130
|
+
: async ctx => {
|
|
131
|
+
record('expand', ctx);
|
|
132
|
+
// Malformed output deliberately exercises the runtime contract boundary.
|
|
133
|
+
if (options.invalidExpansion) return { events: [{ payload: [] }] };
|
|
134
|
+
let payload = z
|
|
135
|
+
.object({ empty: z.boolean().optional(), preserve: z.boolean().optional() })
|
|
136
|
+
.nullable()
|
|
137
|
+
.parse(ctx.input.payload);
|
|
138
|
+
if (payload?.empty) return { events: [], updatedState: null };
|
|
139
|
+
if (payload?.preserve) return { events: [] };
|
|
140
|
+
return {
|
|
141
|
+
events: [
|
|
142
|
+
{ payload: { kind: 'selected', id: 'one' }, idempotencyKey: 'one' },
|
|
143
|
+
{ payload: { kind: 'other', id: 'two' }, idempotencyKey: 'two' },
|
|
144
|
+
{ payload: { kind: 'selected', id: 'three' }, idempotencyKey: 'three' }
|
|
145
|
+
],
|
|
146
|
+
updatedState: { cursor: 'next' }
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
.routingMatchers(async () => [{ tenant: 'tenant' }])
|
|
151
|
+
.build();
|
|
152
|
+
let poll = triggerGroup(spec, { key: 'poll', name: 'Poll', selectionSchema })
|
|
153
|
+
.polling({
|
|
154
|
+
pollEvents: async ctx => {
|
|
155
|
+
record('poll', ctx);
|
|
156
|
+
return { events: [], updatedState: ctx.input.state };
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
.routingMatchers(async () => [])
|
|
160
|
+
.build();
|
|
161
|
+
let matches = 0;
|
|
162
|
+
let selectedInput = z.object({
|
|
163
|
+
kind: z.string().optional(),
|
|
164
|
+
id: z.string().optional(),
|
|
165
|
+
raw: z.boolean().optional()
|
|
166
|
+
});
|
|
167
|
+
let selected = SlateTrigger.create(spec, { key: 'selected', name: 'Selected' })
|
|
168
|
+
.triggerGroup(group)
|
|
169
|
+
.input(selectedInput)
|
|
170
|
+
.output(z.object({ id: z.string() }))
|
|
171
|
+
.matches(payload => {
|
|
172
|
+
matches++;
|
|
173
|
+
let event = selectedInput.safeParse(payload);
|
|
174
|
+
return event.success && (event.data.kind === 'selected' || event.data.raw === true);
|
|
175
|
+
})
|
|
176
|
+
.map(async ctx => {
|
|
177
|
+
let id = ctx.input.id ?? 'raw';
|
|
178
|
+
return { type: 'selected', id, output: { id } };
|
|
179
|
+
})
|
|
180
|
+
.build();
|
|
181
|
+
let slate = Slate.create({
|
|
182
|
+
spec,
|
|
183
|
+
tools: [],
|
|
184
|
+
triggers: [selected],
|
|
185
|
+
triggerGroups: [group, poll]
|
|
186
|
+
});
|
|
187
|
+
let client = createLocalSlateTestClient({
|
|
188
|
+
slate,
|
|
189
|
+
state: {
|
|
190
|
+
config: { tenant: 'tenant' },
|
|
191
|
+
auth: { authenticationMethodId: 'token', output: { token: 'credential' } }
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
return { client, contexts, matches: () => matches };
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
let registrationInput = {
|
|
198
|
+
triggerGroupId: 'webhook',
|
|
199
|
+
webhookTargetIdentifier: 'target',
|
|
200
|
+
webhookTargetPayload: { resource: 'target' },
|
|
201
|
+
webhookUrl: 'https://example.com/webhook'
|
|
202
|
+
};
|
|
203
|
+
let renewalInput = {
|
|
204
|
+
...registrationInput,
|
|
205
|
+
webhookRegistrationIdentifier: 'registration',
|
|
206
|
+
webhookRegistrationPayload: { secret: 'verification' },
|
|
207
|
+
operationId: 'stable-operation'
|
|
208
|
+
};
|
|
209
|
+
let expansionInput = {
|
|
210
|
+
triggerGroupId: 'webhook',
|
|
211
|
+
payload: { raw: true },
|
|
212
|
+
state: { cursor: 'before' },
|
|
213
|
+
deliveryId: 'delivery',
|
|
214
|
+
webhookRegistrationPayload: { secret: 'verification' }
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
describe('trigger lifecycle protocol helpers', () => {
|
|
218
|
+
it('passes the saved delivery config unchanged and independently from user selection', async () => {
|
|
219
|
+
let { client, contexts } = fixture({ deliveryConfig: true });
|
|
220
|
+
let deliveryConfig = {
|
|
221
|
+
topicName: 'projects/p/topics/t',
|
|
222
|
+
audience: 'https://example.com/delivery',
|
|
223
|
+
nested: { kept: ['as', 'saved'] }
|
|
224
|
+
};
|
|
225
|
+
await registerSlateTriggerGroupWebhook({
|
|
226
|
+
client,
|
|
227
|
+
...registrationInput,
|
|
228
|
+
operationId: 'initial-registration-operation',
|
|
229
|
+
deliveryConfig
|
|
230
|
+
});
|
|
231
|
+
await renewSlateTriggerGroupWebhook({ client, ...renewalInput, deliveryConfig });
|
|
232
|
+
expect(contexts.map(ctx => [ctx.operation, ctx.input.deliveryConfig])).toEqual([
|
|
233
|
+
['register', deliveryConfig],
|
|
234
|
+
['renew', deliveryConfig]
|
|
235
|
+
]);
|
|
236
|
+
expect(contexts[0]?.input.operationId).toBe('initial-registration-operation');
|
|
237
|
+
await registerSlateTriggerGroupWebhook({
|
|
238
|
+
client,
|
|
239
|
+
...registrationInput,
|
|
240
|
+
selection: { deliveryConfig }
|
|
241
|
+
});
|
|
242
|
+
expect(contexts.at(-1)?.input.deliveryConfig).toBeUndefined();
|
|
243
|
+
expect(contexts.at(-1)?.input.operationId).toBeUndefined();
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('exposes the delivery config of an automatic group and completes it without credentials', async () => {
|
|
247
|
+
let { client, contexts } = fixture({ deliveryConfig: true });
|
|
248
|
+
expect((await client.getTriggerGroup('webhook')).triggerGroup.invocation).toMatchObject({
|
|
249
|
+
registration: {
|
|
250
|
+
mode: 'auto',
|
|
251
|
+
deliveryConfig: {
|
|
252
|
+
userConfigSchema: { type: 'object', required: ['topicName'] },
|
|
253
|
+
fullConfigSchema: { type: 'object', required: ['topicName', 'audience'] }
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
client.clearAuth();
|
|
258
|
+
let webhookUrl = 'https://example.com/delivery';
|
|
259
|
+
let setup = await client.setupTriggerGroupWebhookManually({
|
|
260
|
+
triggerGroupId: 'webhook',
|
|
261
|
+
webhookUrl
|
|
262
|
+
});
|
|
263
|
+
expect(setup).toEqual({
|
|
264
|
+
webhookSetupDocument: `Deliver to ${webhookUrl}`,
|
|
265
|
+
partialWebhookRegistrationPayload: {}
|
|
266
|
+
});
|
|
267
|
+
let finished = await client.finishTriggerGroupWebhookManualSetup({
|
|
268
|
+
triggerGroupId: 'webhook',
|
|
269
|
+
webhookUrl,
|
|
270
|
+
partialWebhookRegistrationPayload: setup.partialWebhookRegistrationPayload,
|
|
271
|
+
userWebhookRegistrationPayload: { topicName: 'projects/p/topics/t' }
|
|
272
|
+
});
|
|
273
|
+
expect(finished.webhookRegistrationPayload).toEqual({
|
|
274
|
+
topicName: 'projects/p/topics/t',
|
|
275
|
+
audience: webhookUrl
|
|
276
|
+
});
|
|
277
|
+
expect(contexts.map(ctx => [ctx.operation, ctx.auth, ctx.config])).toEqual([
|
|
278
|
+
['setup', {}, {}],
|
|
279
|
+
['finish', {}, {}]
|
|
280
|
+
]);
|
|
281
|
+
await expect(
|
|
282
|
+
fixture().client.setupTriggerGroupWebhookManually({
|
|
283
|
+
triggerGroupId: 'webhook',
|
|
284
|
+
webhookUrl
|
|
285
|
+
})
|
|
286
|
+
).rejects.toThrow('does not support manual webhook registration');
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('authenticates a delivery through the delivery config without credentials', async () => {
|
|
290
|
+
let { client, contexts } = fixture({ deliveryConfig: true });
|
|
291
|
+
client.clearAuth();
|
|
292
|
+
let deliveryConfig = {
|
|
293
|
+
topicName: 'projects/p/topics/t',
|
|
294
|
+
audience: 'https://example.com/d'
|
|
295
|
+
};
|
|
296
|
+
let delivery = {
|
|
297
|
+
client,
|
|
298
|
+
triggerGroupId: 'webhook',
|
|
299
|
+
url: 'https://example.com/d',
|
|
300
|
+
deliveryConfig
|
|
301
|
+
};
|
|
302
|
+
expect(
|
|
303
|
+
await authenticateSlateTriggerGroupWebhookDelivery({
|
|
304
|
+
...delivery,
|
|
305
|
+
body: JSON.stringify({ keys: ['resource:one', 'resource:two'] })
|
|
306
|
+
})
|
|
307
|
+
).toEqual({ routingKeys: ['resource:one', 'resource:two'], rejected: null });
|
|
308
|
+
expect(
|
|
309
|
+
await authenticateSlateTriggerGroupWebhookDelivery({
|
|
310
|
+
...delivery,
|
|
311
|
+
body: JSON.stringify({ keys: [] })
|
|
312
|
+
})
|
|
313
|
+
).toEqual({ routingKeys: [], rejected: null });
|
|
314
|
+
expect(
|
|
315
|
+
await authenticateSlateTriggerGroupWebhookDelivery({
|
|
316
|
+
...delivery,
|
|
317
|
+
headers: { 'x-reject': '503' }
|
|
318
|
+
})
|
|
319
|
+
).toEqual({ routingKeys: [], rejected: { status: 503 } });
|
|
320
|
+
expect(contexts.map(ctx => [ctx.operation, ctx.auth, ctx.config])).toEqual(
|
|
321
|
+
Array(3).fill(['authenticate', {}, {}])
|
|
322
|
+
);
|
|
323
|
+
expect(contexts.map(ctx => ctx.input.deliveryConfig)).toEqual(
|
|
324
|
+
Array(3).fill(deliveryConfig)
|
|
325
|
+
);
|
|
326
|
+
await expect(
|
|
327
|
+
authenticateSlateTriggerGroupWebhookDelivery({
|
|
328
|
+
...delivery,
|
|
329
|
+
client: fixture().client,
|
|
330
|
+
body: JSON.stringify({ keys: [] })
|
|
331
|
+
})
|
|
332
|
+
).rejects.toThrow('does not support webhook delivery authentication');
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it('advertises schemas and capabilities while preserving old group specifications', async () => {
|
|
336
|
+
let { client } = fixture({ selection: 'default' });
|
|
337
|
+
expect((await client.getTriggerGroup('webhook')).triggerGroup).toMatchObject({
|
|
338
|
+
selectionSchema: {
|
|
339
|
+
type: 'object',
|
|
340
|
+
properties: { resource: { type: 'string', default: 'default-resource' } }
|
|
341
|
+
},
|
|
342
|
+
invocation: { type: 'webhook', supportsExpansion: true, supportsRenewal: true }
|
|
343
|
+
});
|
|
344
|
+
let legacy = fixture({ legacy: true });
|
|
345
|
+
let oldGroup = (await legacy.client.getTriggerGroup('webhook')).triggerGroup;
|
|
346
|
+
expect(oldGroup).not.toHaveProperty('selectionSchema');
|
|
347
|
+
expect(oldGroup.invocation).toEqual({ type: 'webhook', registration: { mode: 'auto' } });
|
|
348
|
+
expect(
|
|
349
|
+
(await client.getTriggerGroup('webhook')).triggerGroup.selectionSchema
|
|
350
|
+
).not.toHaveProperty('required');
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('declares bounded reconciliation and passes scheduled null payloads unchanged', async () => {
|
|
354
|
+
for (let reconcileIntervalSeconds of [
|
|
355
|
+
0,
|
|
356
|
+
899,
|
|
357
|
+
900.5,
|
|
358
|
+
Number.NaN,
|
|
359
|
+
Number.POSITIVE_INFINITY
|
|
360
|
+
]) {
|
|
361
|
+
expect(() => fixture({ reconcileIntervalSeconds })).toThrow(
|
|
362
|
+
'integer of at least 900 seconds'
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
expect(() => fixture({ legacy: true, reconcileIntervalSeconds: 900 })).toThrow(
|
|
366
|
+
'requires an expandWebhook handler'
|
|
367
|
+
);
|
|
368
|
+
let { client, contexts } = fixture({ reconcileIntervalSeconds: 900 });
|
|
369
|
+
expect((await client.getTriggerGroup('webhook')).triggerGroup.invocation).toMatchObject({
|
|
370
|
+
reconcileIntervalSeconds: 900,
|
|
371
|
+
supportsExpansion: true
|
|
372
|
+
});
|
|
373
|
+
let result = await expandSlateTriggerGroupWebhook({
|
|
374
|
+
client,
|
|
375
|
+
...expansionInput,
|
|
376
|
+
payload: null,
|
|
377
|
+
deliveryId: 'scheduled-run'
|
|
378
|
+
});
|
|
379
|
+
expect(result.events).toHaveLength(3);
|
|
380
|
+
expect(contexts[0]?.input).toMatchObject({
|
|
381
|
+
payload: null,
|
|
382
|
+
deliveryId: 'scheduled-run',
|
|
383
|
+
state: expansionInput.state,
|
|
384
|
+
webhookRegistrationPayload: expansionInput.webhookRegistrationPayload
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('verifies without credentials and expands zero or many events with connection context', async () => {
|
|
389
|
+
let { client, contexts, matches } = fixture({ selection: 'required' });
|
|
390
|
+
let processed = await processSlateTriggerGroupWebhook({
|
|
391
|
+
client,
|
|
392
|
+
triggerGroupId: 'webhook',
|
|
393
|
+
url: registrationInput.webhookUrl,
|
|
394
|
+
webhookRegistrationPayload: expansionInput.webhookRegistrationPayload
|
|
395
|
+
});
|
|
396
|
+
expect(processed).toMatchObject({
|
|
397
|
+
requiresExpansion: true,
|
|
398
|
+
events: [{ triggerIds: [], idempotencyKey: 'raw-key' }]
|
|
399
|
+
});
|
|
400
|
+
expect(matches()).toBe(0);
|
|
401
|
+
expect(contexts[0]).toMatchObject({ operation: 'process', auth: {}, config: {} });
|
|
402
|
+
let expanded = await expandSlateTriggerGroupWebhook({
|
|
403
|
+
client,
|
|
404
|
+
...expansionInput,
|
|
405
|
+
selection: { resource: 'chosen' }
|
|
406
|
+
});
|
|
407
|
+
expect(expanded).toMatchObject({
|
|
408
|
+
updatedState: { cursor: 'next' },
|
|
409
|
+
events: [
|
|
410
|
+
{ idempotencyKey: 'one', triggerIds: ['selected'] },
|
|
411
|
+
{ idempotencyKey: 'two', triggerIds: [] },
|
|
412
|
+
{ idempotencyKey: 'three', triggerIds: ['selected'] }
|
|
413
|
+
]
|
|
414
|
+
});
|
|
415
|
+
expect(contexts[1]).toMatchObject({
|
|
416
|
+
operation: 'expand',
|
|
417
|
+
auth: { token: 'credential' },
|
|
418
|
+
config: { tenant: 'tenant' },
|
|
419
|
+
input: {
|
|
420
|
+
payload: expansionInput.payload,
|
|
421
|
+
state: expansionInput.state,
|
|
422
|
+
deliveryId: expansionInput.deliveryId,
|
|
423
|
+
webhookRegistrationPayload: expansionInput.webhookRegistrationPayload,
|
|
424
|
+
selection: { resource: 'chosen' }
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
expect(matches()).toBe(3);
|
|
428
|
+
expect(
|
|
429
|
+
await client.mapTriggerEvent('selected', expanded.events[0]!.payload)
|
|
430
|
+
).toMatchObject({ output: { id: 'one' } });
|
|
431
|
+
let cleared = await expandSlateTriggerGroupWebhook({
|
|
432
|
+
client,
|
|
433
|
+
...expansionInput,
|
|
434
|
+
payload: { empty: true },
|
|
435
|
+
selection: { resource: 'chosen' }
|
|
436
|
+
});
|
|
437
|
+
expect(cleared).toMatchObject({ events: [], updatedState: null });
|
|
438
|
+
let preserved = await expandSlateTriggerGroupWebhook({
|
|
439
|
+
client,
|
|
440
|
+
...expansionInput,
|
|
441
|
+
payload: { preserve: true },
|
|
442
|
+
selection: { resource: 'chosen' }
|
|
443
|
+
});
|
|
444
|
+
expect(preserved.events).toEqual([]);
|
|
445
|
+
expect(preserved).not.toHaveProperty('updatedState');
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('validates selection before every affected handler and applies accepted defaults', async () => {
|
|
449
|
+
let { client, contexts } = fixture({ selection: 'required' });
|
|
450
|
+
let calls = [
|
|
451
|
+
() => client.listTriggerGroupWebhookTargets({ triggerGroupId: 'webhook' }),
|
|
452
|
+
() => registerSlateTriggerGroupWebhook({ client, ...registrationInput }),
|
|
453
|
+
() => renewSlateTriggerGroupWebhook({ client, ...renewalInput }),
|
|
454
|
+
() => expandSlateTriggerGroupWebhook({ client, ...expansionInput }),
|
|
455
|
+
() => pollSlateTriggerGroupEvents({ client, triggerGroupId: 'poll' })
|
|
456
|
+
];
|
|
457
|
+
for (let call of calls) await expect(call()).rejects.toThrow('Invalid selection');
|
|
458
|
+
expect(contexts).toEqual([]);
|
|
459
|
+
let defaults = fixture({ selection: 'default' });
|
|
460
|
+
await defaults.client.listTriggerGroupWebhookTargets({ triggerGroupId: 'webhook' });
|
|
461
|
+
await registerSlateTriggerGroupWebhook({ client: defaults.client, ...registrationInput });
|
|
462
|
+
await renewSlateTriggerGroupWebhook({ client: defaults.client, ...renewalInput });
|
|
463
|
+
await expandSlateTriggerGroupWebhook({ client: defaults.client, ...expansionInput });
|
|
464
|
+
await pollSlateTriggerGroupEvents({ client: defaults.client, triggerGroupId: 'poll' });
|
|
465
|
+
expect(defaults.contexts.map(ctx => ctx.input.selection)).toEqual(
|
|
466
|
+
Array(5).fill({ resource: 'default-resource' })
|
|
467
|
+
);
|
|
468
|
+
await pollSlateTriggerGroupEvents({
|
|
469
|
+
client: defaults.client,
|
|
470
|
+
triggerGroupId: 'poll',
|
|
471
|
+
selection: { resource: 'explicit' }
|
|
472
|
+
});
|
|
473
|
+
expect(defaults.contexts.at(-1)?.input.selection).toEqual({ resource: 'explicit' });
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
it('keeps groups without selection, expansion, or renewal backward compatible', async () => {
|
|
477
|
+
let { client, contexts } = fixture({ legacy: true });
|
|
478
|
+
await registerSlateTriggerGroupWebhook({ client, ...registrationInput });
|
|
479
|
+
await pollSlateTriggerGroupEvents({ client, triggerGroupId: 'poll' });
|
|
480
|
+
expect(contexts.map(ctx => ctx.input.selection)).toEqual([{}, {}]);
|
|
481
|
+
let processed = await processSlateTriggerGroupWebhook({
|
|
482
|
+
client,
|
|
483
|
+
triggerGroupId: 'webhook',
|
|
484
|
+
url: registrationInput.webhookUrl
|
|
485
|
+
});
|
|
486
|
+
expect(processed.events[0]?.triggerIds).toEqual(['selected']);
|
|
487
|
+
expect(processed).not.toHaveProperty('requiresExpansion');
|
|
488
|
+
await expect(renewSlateTriggerGroupWebhook({ client, ...renewalInput })).rejects.toThrow(
|
|
489
|
+
'does not support webhook renewal'
|
|
490
|
+
);
|
|
491
|
+
await expect(
|
|
492
|
+
expandSlateTriggerGroupWebhook({ client, ...expansionInput })
|
|
493
|
+
).rejects.toThrow('does not support webhook expansion');
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
it('requires authenticated context for expansion and renewal', async () => {
|
|
497
|
+
let { client, contexts } = fixture();
|
|
498
|
+
client.clearAuth();
|
|
499
|
+
await expect(
|
|
500
|
+
expandSlateTriggerGroupWebhook({ client, ...expansionInput })
|
|
501
|
+
).rejects.toMatchObject({
|
|
502
|
+
data: { code: 'request.precondition_failed' }
|
|
503
|
+
});
|
|
504
|
+
await expect(
|
|
505
|
+
renewSlateTriggerGroupWebhook({ client, ...renewalInput })
|
|
506
|
+
).rejects.toMatchObject({
|
|
507
|
+
data: { code: 'request.precondition_failed' }
|
|
508
|
+
});
|
|
509
|
+
expect(contexts).toEqual([]);
|
|
510
|
+
await processSlateTriggerGroupWebhook({
|
|
511
|
+
client,
|
|
512
|
+
triggerGroupId: 'webhook',
|
|
513
|
+
url: registrationInput.webhookUrl
|
|
514
|
+
});
|
|
515
|
+
expect(contexts[0]).toMatchObject({ operation: 'process', auth: {}, config: {} });
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
it('passes stable renewal identity and validates nullable ISO scheduling metadata', async () => {
|
|
519
|
+
let { client, contexts } = fixture({
|
|
520
|
+
expiresAt: '2026-12-01T12:00:00+01:00',
|
|
521
|
+
renewAfter: null
|
|
522
|
+
});
|
|
523
|
+
let registered = await registerSlateTriggerGroupWebhook({ client, ...registrationInput });
|
|
524
|
+
expect(registered).toMatchObject({
|
|
525
|
+
expiresAt: '2026-12-01T12:00:00+01:00',
|
|
526
|
+
renewAfter: null
|
|
527
|
+
});
|
|
528
|
+
let renewed = await renewSlateTriggerGroupWebhook({
|
|
529
|
+
client,
|
|
530
|
+
...renewalInput,
|
|
531
|
+
selection: { resource: 'chosen' }
|
|
532
|
+
});
|
|
533
|
+
expect(renewed).toMatchObject({
|
|
534
|
+
webhookRegistrationIdentifier: 'renewed-registration',
|
|
535
|
+
expiresAt: registered.expiresAt,
|
|
536
|
+
renewAfter: null
|
|
537
|
+
});
|
|
538
|
+
expect(contexts.at(-1)).toMatchObject({
|
|
539
|
+
operation: 'renew',
|
|
540
|
+
auth: { token: 'credential' },
|
|
541
|
+
config: { tenant: 'tenant' },
|
|
542
|
+
input: {
|
|
543
|
+
operationId: 'stable-operation',
|
|
544
|
+
webhookRegistrationIdentifier: 'registration',
|
|
545
|
+
webhookTargetIdentifier: 'target',
|
|
546
|
+
selection: { resource: 'chosen' }
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
let invalid = fixture({ expiresAt: 'tomorrow' });
|
|
550
|
+
await expect(
|
|
551
|
+
registerSlateTriggerGroupWebhook({ client: invalid.client, ...registrationInput })
|
|
552
|
+
).rejects.toThrow('invalid result');
|
|
553
|
+
await expect(
|
|
554
|
+
renewSlateTriggerGroupWebhook({ client: invalid.client, ...renewalInput })
|
|
555
|
+
).rejects.toThrow('invalid result');
|
|
556
|
+
let invalidExpansion = fixture({ invalidExpansion: true });
|
|
557
|
+
await expect(
|
|
558
|
+
expandSlateTriggerGroupWebhook({ client: invalidExpansion.client, ...expansionInput })
|
|
559
|
+
).rejects.toThrow('invalid result');
|
|
560
|
+
});
|
|
561
|
+
});
|