@slates/provider 1.0.0-rc.21 → 1.0.0-rc.23

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 CHANGED
@@ -50,6 +50,8 @@ __export(index_exports, {
50
50
  SlateSpecification: () => SlateSpecification,
51
51
  SlateTool: () => SlateTool,
52
52
  SlateTrigger: () => SlateTrigger,
53
+ SlateTriggerGroup: () => SlateTriggerGroup,
54
+ SlateTriggerGroupBuilder: () => SlateTriggerGroupBuilder,
53
55
  adapterSpec: () => adapterSpec,
54
56
  allOf: () => allOf,
55
57
  anyOf: () => anyOf,
@@ -101,6 +103,7 @@ __export(index_exports, {
101
103
  statusLabelForApiError: () => statusLabelForApiError,
102
104
  tool: () => tool,
103
105
  trigger: () => trigger,
106
+ triggerGroup: () => triggerGroup,
104
107
  uploadAttachmentDirect: () => uploadAttachmentDirect,
105
108
  validateScopes: () => validateScopes,
106
109
  verifyHmacSignature: () => verifyHmacSignature
@@ -934,7 +937,9 @@ var SlateActionBuilder = class {
934
937
  #scopes;
935
938
  #authMethods;
936
939
  #toolParams = null;
937
- #triggerParams = null;
940
+ #triggerGroup = null;
941
+ #triggerMatches = null;
942
+ #triggerMap = null;
938
943
  #interfaceLocked = false;
939
944
  input(schema) {
940
945
  if (this.#interfaceLocked) {
@@ -984,32 +989,25 @@ var SlateActionBuilder = class {
984
989
  };
985
990
  return this;
986
991
  }
987
- webhook(props) {
992
+ triggerGroup(group) {
988
993
  if (this.type !== "trigger") {
989
- throw new SlateDeclarationError("handleEvent can only be set for trigger actions");
994
+ throw new SlateDeclarationError("triggerGroup can only be set for trigger actions");
990
995
  }
991
- this.#triggerParams = {
992
- type: "trigger",
993
- source: "webhook",
994
- handleEvent: props.handleEvent,
995
- handleRequest: props.handleRequest,
996
- autoRegisterWebhook: props.autoRegisterWebhook,
997
- autoUnregisterWebhook: props.autoUnregisterWebhook,
998
- http: props.http
999
- };
996
+ this.#triggerGroup = group;
1000
997
  return this;
1001
998
  }
1002
- polling(props) {
999
+ matches(handler) {
1003
1000
  if (this.type !== "trigger") {
1004
- throw new SlateDeclarationError("handleEvent can only be set for trigger actions");
1001
+ throw new SlateDeclarationError("matches can only be set for trigger actions");
1005
1002
  }
1006
- this.#triggerParams = {
1007
- type: "trigger",
1008
- source: "polling",
1009
- polling: props.options,
1010
- pollEvents: props.pollEvents,
1011
- handleEvent: props.handleEvent
1012
- };
1003
+ this.#triggerMatches = handler;
1004
+ return this;
1005
+ }
1006
+ map(handler) {
1007
+ if (this.type !== "trigger") {
1008
+ throw new SlateDeclarationError("map can only be set for trigger actions");
1009
+ }
1010
+ this.#triggerMap = handler;
1013
1011
  return this;
1014
1012
  }
1015
1013
  build() {
@@ -1030,9 +1028,21 @@ var SlateActionBuilder = class {
1030
1028
  if (this.type === "tool" && !this.#toolParams) {
1031
1029
  throw new SlateDeclarationError("Tool invocation handler is not defined");
1032
1030
  }
1033
- if (this.type === "trigger" && !this.#triggerParams) {
1034
- throw new SlateDeclarationError("Trigger event handlers are not defined");
1031
+ if (this.type === "trigger" && !this.#triggerGroup) {
1032
+ throw new SlateDeclarationError("Trigger group is not defined");
1033
+ }
1034
+ if (this.type === "trigger" && !this.#triggerMatches) {
1035
+ throw new SlateDeclarationError("Trigger matches handler is not defined");
1036
+ }
1037
+ if (this.type === "trigger" && !this.#triggerMap) {
1038
+ throw new SlateDeclarationError("Trigger map handler is not defined");
1035
1039
  }
1040
+ let triggerParams = this.type === "trigger" ? {
1041
+ type: "trigger",
1042
+ triggerGroup: this.#triggerGroup,
1043
+ matches: this.#triggerMatches,
1044
+ map: this.#triggerMap
1045
+ } : null;
1036
1046
  return this.factory({
1037
1047
  ...this.params,
1038
1048
  scopes,
@@ -1043,7 +1053,7 @@ var SlateActionBuilder = class {
1043
1053
  inputSchema: this.#inputSchema,
1044
1054
  outputSchema: this.#outputSchema,
1045
1055
  ...this.#toolParams,
1046
- ...this.#triggerParams
1056
+ ...triggerParams
1047
1057
  });
1048
1058
  }
1049
1059
  };
@@ -1051,6 +1061,91 @@ var SlateActionBuilder = class {
1051
1061
  // src/action/getFileUrlTool.ts
1052
1062
  var import_zod = require("zod");
1053
1063
 
1064
+ // src/auth/redact.ts
1065
+ var AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX = "$$MT$secret$authConfig$";
1066
+ var AuthConfigSecretRedactor = class {
1067
+ secretToPlaceholder = /* @__PURE__ */ new Map();
1068
+ constructor(authConfig) {
1069
+ if (authConfig) this.buildSecretMap(authConfig);
1070
+ }
1071
+ redact(value) {
1072
+ return this.transform(value, (stringValue) => {
1073
+ return this.secretToPlaceholder.get(stringValue) ?? stringValue;
1074
+ });
1075
+ }
1076
+ redactEmbedded(value) {
1077
+ if (this.secretToPlaceholder.size === 0) return value;
1078
+ let pattern = new RegExp(
1079
+ [...this.secretToPlaceholder.keys()].sort((a, b) => b.length - a.length).map((secret) => secret.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"),
1080
+ "g"
1081
+ );
1082
+ return this.transform(value, (stringValue) => {
1083
+ let exactPlaceholder = this.secretToPlaceholder.get(stringValue);
1084
+ if (exactPlaceholder) return exactPlaceholder;
1085
+ return stringValue.replace(
1086
+ pattern,
1087
+ (secret) => `${this.secretToPlaceholder.get(secret)}$$`
1088
+ );
1089
+ });
1090
+ }
1091
+ buildSecretMap(value, path = []) {
1092
+ if (typeof value === "string") {
1093
+ if (value.length === 0) return;
1094
+ this.secretToPlaceholder.set(
1095
+ value,
1096
+ `${AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX}${path.join(".")}`
1097
+ );
1098
+ return;
1099
+ }
1100
+ if (Array.isArray(value)) {
1101
+ value.forEach((item, index) => {
1102
+ this.buildSecretMap(item, [...path, String(index)]);
1103
+ });
1104
+ return;
1105
+ }
1106
+ if (this.isPlainObject(value)) {
1107
+ Object.entries(value).forEach(([key, nestedValue]) => {
1108
+ this.buildSecretMap(nestedValue, [...path, key]);
1109
+ });
1110
+ }
1111
+ }
1112
+ transform(value, transformString) {
1113
+ if (typeof value === "string") {
1114
+ return transformString(value);
1115
+ }
1116
+ if (Array.isArray(value)) {
1117
+ return value.map((item) => this.transform(item, transformString));
1118
+ }
1119
+ if (this.isPlainObject(value)) {
1120
+ let result = {};
1121
+ Object.entries(value).forEach(([key, nestedValue]) => {
1122
+ result[key] = this.transform(nestedValue, transformString);
1123
+ });
1124
+ return result;
1125
+ }
1126
+ return value;
1127
+ }
1128
+ isPlainObject(value) {
1129
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1130
+ }
1131
+ };
1132
+ var redactUrlAttachmentSecrets = (attachments, authConfig) => {
1133
+ if (!authConfig || !attachments) return attachments;
1134
+ let redactor = new AuthConfigSecretRedactor(authConfig);
1135
+ return attachments.map((attachment) => {
1136
+ if (attachment.content.type !== "url") return attachment;
1137
+ if (!attachment.content.headers && !attachment.content.query) return attachment;
1138
+ return {
1139
+ ...attachment,
1140
+ content: {
1141
+ ...attachment.content,
1142
+ headers: attachment.content.headers ? redactor.redactEmbedded(attachment.content.headers) : void 0,
1143
+ query: attachment.content.query ? redactor.redactEmbedded(attachment.content.query) : void 0
1144
+ }
1145
+ };
1146
+ });
1147
+ };
1148
+
1054
1149
  // src/action/tool.ts
1055
1150
  var SlateTool = class _SlateTool extends SlateAction {
1056
1151
  #handleInvocation;
@@ -1089,10 +1184,18 @@ var getFileUrlTool = (spec2, handleGetFileUrl) => tool(spec2, {
1089
1184
  key: GET_FILE_URL_TOOL_ID,
1090
1185
  name: "Get File URL",
1091
1186
  description: "Reserved: refreshes an expiring attachment download URL. Hub-internal only."
1092
- }).input(getFileUrlToolInputSchema).output(getFileUrlToolOutputSchema).handleInvocation(async (ctx) => ({
1093
- output: await handleGetFileUrl(ctx),
1094
- message: "ok"
1095
- })).build();
1187
+ }).input(getFileUrlToolInputSchema).output(getFileUrlToolOutputSchema).handleInvocation(async (ctx) => {
1188
+ let output = await handleGetFileUrl(ctx);
1189
+ let redactor = new AuthConfigSecretRedactor(ctx._getAuthConfigForRedaction());
1190
+ return {
1191
+ output: {
1192
+ ...output,
1193
+ ...output.headers ? { headers: redactor.redactEmbedded(output.headers) } : {},
1194
+ ...output.query ? { query: redactor.redactEmbedded(output.query) } : {}
1195
+ },
1196
+ message: "ok"
1197
+ };
1198
+ }).build();
1096
1199
 
1097
1200
  // src/action/publicTool.ts
1098
1201
  var SlatePublicTool = class {
@@ -1116,28 +1219,15 @@ var SlatePublicTool = class {
1116
1219
  var publicTool = (spec2, params) => SlatePublicTool.create(spec2, params);
1117
1220
 
1118
1221
  // src/action/trigger.ts
1119
- var SlateDefaultPollingIntervalSeconds = 60 * 10;
1120
1222
  var SlateTrigger = class _SlateTrigger extends SlateAction {
1121
- #source;
1122
- #polling;
1123
- #handleEvent;
1124
- #handleRequest;
1125
- #http;
1126
- #pollEvents;
1127
- #autoRegisterWebhook;
1128
- #autoUnregisterWebhook;
1223
+ #triggerGroup;
1224
+ #matches;
1225
+ #map;
1129
1226
  constructor(spec2, inputSchema, outputSchema, params) {
1130
1227
  super("trigger", spec2, inputSchema, outputSchema, params);
1131
- this.#source = params.source;
1132
- this.#polling = params.polling || {
1133
- intervalInSeconds: SlateDefaultPollingIntervalSeconds
1134
- };
1135
- this.#handleEvent = params.handleEvent;
1136
- this.#handleRequest = params.handleRequest;
1137
- this.#http = params.http;
1138
- this.#pollEvents = params.pollEvents;
1139
- this.#autoRegisterWebhook = params.autoRegisterWebhook;
1140
- this.#autoUnregisterWebhook = params.autoUnregisterWebhook;
1228
+ this.#triggerGroup = params.triggerGroup;
1229
+ this.#matches = params.matches;
1230
+ this.#map = params.map;
1141
1231
  }
1142
1232
  static create(spec2, params) {
1143
1233
  return new SlateActionBuilder("trigger", spec2, params, (params2) => {
@@ -1145,32 +1235,122 @@ var SlateTrigger = class _SlateTrigger extends SlateAction {
1145
1235
  return new _SlateTrigger(spec2, params2.inputSchema, params2.outputSchema, params2);
1146
1236
  });
1147
1237
  }
1148
- get polling() {
1149
- return this.#polling;
1238
+ get triggerGroup() {
1239
+ return this.#triggerGroup;
1240
+ }
1241
+ get matches() {
1242
+ return this.#matches;
1243
+ }
1244
+ get map() {
1245
+ return this.#map;
1246
+ }
1247
+ };
1248
+ var trigger = (spec2, params) => SlateTrigger.create(spec2, params);
1249
+
1250
+ // src/action/triggerGroup.ts
1251
+ var SlateDefaultPollingIntervalSeconds = 60 * 10;
1252
+ var SlateTriggerGroup = class _SlateTriggerGroup {
1253
+ constructor(_spec, _params) {
1254
+ this._spec = _spec;
1255
+ this._params = _params;
1256
+ }
1257
+ _spec;
1258
+ _params;
1259
+ static create(spec2, params) {
1260
+ return new SlateTriggerGroupBuilder(spec2, params, (p) => new _SlateTriggerGroup(spec2, p));
1261
+ }
1262
+ get spec() {
1263
+ return this._spec;
1264
+ }
1265
+ get key() {
1266
+ return this._params.key;
1267
+ }
1268
+ get name() {
1269
+ return this._params.name;
1270
+ }
1271
+ get description() {
1272
+ return this._params.description;
1273
+ }
1274
+ get metadata() {
1275
+ return this._params.metadata;
1150
1276
  }
1151
1277
  get source() {
1152
- return this.#source;
1278
+ return this._params.source;
1153
1279
  }
1154
- get handleEvent() {
1155
- return this.#handleEvent;
1280
+ get polling() {
1281
+ return this._params.polling;
1156
1282
  }
1157
- get handleRequest() {
1158
- return this.#handleRequest;
1283
+ get webhook() {
1284
+ return this._params.webhook;
1159
1285
  }
1160
- get http() {
1161
- return this.#http;
1286
+ get routingMatchers() {
1287
+ return this._params.routingMatchers;
1162
1288
  }
1163
- get pollEvents() {
1164
- return this.#pollEvents;
1289
+ };
1290
+ var SlateTriggerGroupBuilder = class {
1291
+ constructor(spec2, params, factory) {
1292
+ this.spec = spec2;
1293
+ this.params = params;
1294
+ this.factory = factory;
1165
1295
  }
1166
- get autoRegisterWebhook() {
1167
- return this.#autoRegisterWebhook;
1296
+ spec;
1297
+ params;
1298
+ factory;
1299
+ #source = null;
1300
+ #polling = null;
1301
+ #webhook = null;
1302
+ #routingMatchers = null;
1303
+ polling(props) {
1304
+ if (this.#source) {
1305
+ throw new SlateDeclarationError("Trigger group invocation is already defined");
1306
+ }
1307
+ this.#source = "polling";
1308
+ this.#polling = {
1309
+ intervalSeconds: props.intervalSeconds ?? SlateDefaultPollingIntervalSeconds,
1310
+ pollEvents: props.pollEvents
1311
+ };
1312
+ return this;
1313
+ }
1314
+ webhook(props) {
1315
+ if (this.#source) {
1316
+ throw new SlateDeclarationError("Trigger group invocation is already defined");
1317
+ }
1318
+ if (!!props.autoRegistration === !!props.manualRegistration) {
1319
+ throw new SlateDeclarationError(
1320
+ "Webhook trigger groups require exactly one of autoRegistration or manualRegistration"
1321
+ );
1322
+ }
1323
+ this.#source = "webhook";
1324
+ this.#webhook = {
1325
+ autoRegistration: props.autoRegistration,
1326
+ manualRegistration: props.manualRegistration,
1327
+ process: props.process
1328
+ };
1329
+ return this;
1168
1330
  }
1169
- get autoUnregisterWebhook() {
1170
- return this.#autoUnregisterWebhook;
1331
+ routingMatchers(handler) {
1332
+ this.#routingMatchers = handler;
1333
+ return this;
1334
+ }
1335
+ build() {
1336
+ if (!this.#source) {
1337
+ throw new SlateDeclarationError(
1338
+ "Trigger group invocation (polling or webhook) is not defined"
1339
+ );
1340
+ }
1341
+ if (!this.#routingMatchers) {
1342
+ throw new SlateDeclarationError("Trigger group routing matchers handler is not defined");
1343
+ }
1344
+ return this.factory({
1345
+ ...this.params,
1346
+ source: this.#source,
1347
+ polling: this.#polling ?? void 0,
1348
+ webhook: this.#webhook ?? void 0,
1349
+ routingMatchers: this.#routingMatchers
1350
+ });
1171
1351
  }
1172
1352
  };
1173
- var trigger = (spec2, params) => SlateTrigger.create(spec2, params);
1353
+ var triggerGroup = (spec2, params) => SlateTriggerGroup.create(spec2, params);
1174
1354
 
1175
1355
  // src/action/attachment.ts
1176
1356
  var createUrlAttachment = (url, opts = {}) => {
@@ -1215,7 +1395,9 @@ var bufferAttachmentBody = async (body, maxSizeBytes) => {
1215
1395
  if (body.byteLength > maxSizeBytes) {
1216
1396
  throw new Error(`Attachment exceeds the maximum size of ${maxSizeBytes} bytes`);
1217
1397
  }
1218
- return body;
1398
+ let buffered2 = new ArrayBuffer(body.byteLength);
1399
+ new Uint8Array(buffered2).set(body);
1400
+ return buffered2;
1219
1401
  }
1220
1402
  let reader = body.getReader();
1221
1403
  let chunks = [];
@@ -1231,10 +1413,11 @@ var bufferAttachmentBody = async (body, maxSizeBytes) => {
1231
1413
  }
1232
1414
  chunks.push(value);
1233
1415
  }
1234
- let buffered = new Uint8Array(sizeBytes);
1416
+ let buffered = new ArrayBuffer(sizeBytes);
1417
+ let bufferedView = new Uint8Array(buffered);
1235
1418
  let offset = 0;
1236
1419
  for (let chunk of chunks) {
1237
- buffered.set(chunk, offset);
1420
+ bufferedView.set(chunk, offset);
1238
1421
  offset += chunk.byteLength;
1239
1422
  }
1240
1423
  return buffered;
@@ -1555,76 +1738,6 @@ var normalizeOAuthTokenResponse = (data, options = {}) => {
1555
1738
  };
1556
1739
  };
1557
1740
 
1558
- // src/auth/redact.ts
1559
- var AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX = "$$MT$secret$authConfig$";
1560
- var AuthConfigSecretRedactor = class {
1561
- secretToPlaceholder = /* @__PURE__ */ new Map();
1562
- constructor(authConfig) {
1563
- if (authConfig) this.buildSecretMap(authConfig);
1564
- }
1565
- redact(value) {
1566
- return this.transform(value, (stringValue) => {
1567
- return this.secretToPlaceholder.get(stringValue) ?? stringValue;
1568
- });
1569
- }
1570
- buildSecretMap(value, path = []) {
1571
- if (typeof value === "string") {
1572
- if (value.length === 0) return;
1573
- this.secretToPlaceholder.set(
1574
- value,
1575
- `${AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX}${path.join(".")}`
1576
- );
1577
- return;
1578
- }
1579
- if (Array.isArray(value)) {
1580
- value.forEach((item, index) => {
1581
- this.buildSecretMap(item, [...path, String(index)]);
1582
- });
1583
- return;
1584
- }
1585
- if (this.isPlainObject(value)) {
1586
- Object.entries(value).forEach(([key, nestedValue]) => {
1587
- this.buildSecretMap(nestedValue, [...path, key]);
1588
- });
1589
- }
1590
- }
1591
- transform(value, transformString) {
1592
- if (typeof value === "string") {
1593
- return transformString(value);
1594
- }
1595
- if (Array.isArray(value)) {
1596
- return value.map((item) => this.transform(item, transformString));
1597
- }
1598
- if (this.isPlainObject(value)) {
1599
- let result = {};
1600
- Object.entries(value).forEach(([key, nestedValue]) => {
1601
- result[key] = this.transform(nestedValue, transformString);
1602
- });
1603
- return result;
1604
- }
1605
- return value;
1606
- }
1607
- isPlainObject(value) {
1608
- return typeof value === "object" && value !== null && !Array.isArray(value);
1609
- }
1610
- };
1611
- var redactUrlAttachmentSecrets = (attachments, authConfig) => {
1612
- if (!authConfig || !attachments) return attachments;
1613
- let redactor = new AuthConfigSecretRedactor(authConfig);
1614
- return attachments.map((attachment) => {
1615
- if (attachment.content.type !== "url") return attachment;
1616
- if (!attachment.content.headers && !attachment.content.query) return attachment;
1617
- return {
1618
- ...attachment,
1619
- content: {
1620
- ...attachment.content,
1621
- headers: attachment.content.headers ? redactor.redact(attachment.content.headers) : void 0,
1622
- query: attachment.content.query ? redactor.redact(attachment.content.query) : void 0
1623
- }
1624
- };
1625
- });
1626
- };
1627
-
1628
1741
  // src/axios/index.ts
1629
1742
  var import_axios3 = __toESM(require("axios"), 1);
1630
1743
 
@@ -2664,14 +2777,16 @@ var setIfDefined = (target, key, value) => {
2664
2777
 
2665
2778
  // src/specification/slate.ts
2666
2779
  var Slate = class _Slate {
2667
- constructor(_spec, _actions, _adapters) {
2780
+ constructor(_spec, _actions, _adapters, _triggerGroups) {
2668
2781
  this._spec = _spec;
2669
2782
  this._actions = _actions;
2670
2783
  this._adapters = _adapters;
2784
+ this._triggerGroups = _triggerGroups;
2671
2785
  }
2672
2786
  _spec;
2673
2787
  _actions;
2674
2788
  _adapters;
2789
+ _triggerGroups;
2675
2790
  static create(params) {
2676
2791
  let adapters = params.adapters ?? [];
2677
2792
  let actions = [...params.triggers, ...params.tools];
@@ -2697,7 +2812,25 @@ var Slate = class _Slate {
2697
2812
  }
2698
2813
  }
2699
2814
  }
2700
- return new _Slate(params.spec, actions, adapters);
2815
+ let triggerGroups = params.triggerGroups ?? [];
2816
+ let seenTriggerGroupKeys = /* @__PURE__ */ new Set();
2817
+ for (let group of triggerGroups) {
2818
+ if (seenTriggerGroupKeys.has(group.key)) {
2819
+ throw new SlateDeclarationError(
2820
+ `Trigger group "${group.key}" is registered more than once`
2821
+ );
2822
+ }
2823
+ seenTriggerGroupKeys.add(group.key);
2824
+ }
2825
+ let manualWebhookTriggerGroups = triggerGroups.filter(
2826
+ (group) => group.source === "webhook" && group.webhook?.manualRegistration
2827
+ );
2828
+ if (manualWebhookTriggerGroups.length > 1) {
2829
+ throw new SlateDeclarationError(
2830
+ `Only one trigger group may use manual webhook registration, but found: ${manualWebhookTriggerGroups.map((group) => group.key).join(", ")}`
2831
+ );
2832
+ }
2833
+ return new _Slate(params.spec, actions, adapters, triggerGroups);
2701
2834
  }
2702
2835
  get spec() {
2703
2836
  return this._spec;
@@ -2708,6 +2841,9 @@ var Slate = class _Slate {
2708
2841
  get adapters() {
2709
2842
  return this._adapters;
2710
2843
  }
2844
+ get triggerGroups() {
2845
+ return this._triggerGroups;
2846
+ }
2711
2847
  };
2712
2848
 
2713
2849
  // src/specification/specification.ts
@@ -2828,6 +2964,8 @@ var getMetaWebhookVerificationResponse = (request, expectedVerifyToken) => {
2828
2964
  SlateSpecification,
2829
2965
  SlateTool,
2830
2966
  SlateTrigger,
2967
+ SlateTriggerGroup,
2968
+ SlateTriggerGroupBuilder,
2831
2969
  adapterSpec,
2832
2970
  allOf,
2833
2971
  anyOf,
@@ -2879,6 +3017,7 @@ var getMetaWebhookVerificationResponse = (request, expectedVerifyToken) => {
2879
3017
  statusLabelForApiError,
2880
3018
  tool,
2881
3019
  trigger,
3020
+ triggerGroup,
2882
3021
  uploadAttachmentDirect,
2883
3022
  validateScopes,
2884
3023
  verifyHmacSignature