@slates/provider 1.0.0-rc.33 → 1.0.0-rc.35
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 +289 -19
- package/dist/index.d.cts +168 -2
- package/dist/index.d.ts +168 -2
- package/dist/index.module.js +279 -19
- package/package.json +1 -1
- package/src/action/action.ts +1 -0
- package/src/action/builder.ts +73 -1
- package/src/action/index.ts +1 -0
- package/src/action/optionList.ts +94 -0
- package/src/action/trigger.test.ts +132 -0
- package/src/action/trigger.ts +7 -0
- package/src/action/triggerGroup.test.ts +172 -0
- package/src/action/triggerGroup.ts +248 -5
- package/src/crypto/hmac.test.ts +17 -1
- package/src/crypto/hmac.ts +11 -6
- package/src/dedup/index.test.ts +47 -0
- package/src/dedup/index.ts +25 -0
- package/src/error/api.test.ts +22 -0
- package/src/error/api.ts +8 -0
- package/src/error/index.ts +1 -0
- package/src/error/parse.test.ts +29 -0
- package/src/error/parse.ts +14 -0
- package/src/index.ts +2 -0
- package/src/pagination/index.test.ts +21 -0
- package/src/pagination/index.ts +15 -0
- package/src/specification/slate.test.ts +123 -3
- package/src/specification/slate.ts +33 -7
package/dist/index.cjs
CHANGED
|
@@ -48,6 +48,7 @@ __export(index_exports, {
|
|
|
48
48
|
SlateDefaultPollingIntervalSeconds: () => SlateDefaultPollingIntervalSeconds,
|
|
49
49
|
SlateError: () => SlateError,
|
|
50
50
|
SlateLogger: () => SlateLogger,
|
|
51
|
+
SlateOptionList: () => SlateOptionList,
|
|
51
52
|
SlatePublicContext: () => SlatePublicContext,
|
|
52
53
|
SlatePublicTool: () => SlatePublicTool,
|
|
53
54
|
SlateSpecification: () => SlateSpecification,
|
|
@@ -59,6 +60,7 @@ __export(index_exports, {
|
|
|
59
60
|
adapterSpec: () => adapterSpec,
|
|
60
61
|
allOf: () => allOf,
|
|
61
62
|
anyOf: () => anyOf,
|
|
63
|
+
assertNewPageToken: () => assertNewPageToken,
|
|
62
64
|
auth: () => auth,
|
|
63
65
|
axios: () => axios,
|
|
64
66
|
buildApiServiceError: () => buildApiServiceError,
|
|
@@ -88,6 +90,7 @@ __export(index_exports, {
|
|
|
88
90
|
getResponseHeaderValue: () => getResponseHeaderValue,
|
|
89
91
|
getRuntimeInfo: () => getRuntimeInfo,
|
|
90
92
|
getServiceErrorData: () => getServiceErrorData,
|
|
93
|
+
getUpstreamErrorStatus: () => getUpstreamErrorStatus,
|
|
91
94
|
graphWebhookHttp: () => graphWebhookHttp,
|
|
92
95
|
inferSlateErrorFromAxios: () => inferSlateErrorFromAxios,
|
|
93
96
|
isApiErrorRecord: () => isApiErrorRecord,
|
|
@@ -100,19 +103,26 @@ __export(index_exports, {
|
|
|
100
103
|
mergeScopes: () => mergeScopes,
|
|
101
104
|
metaWebhookHttp: () => metaWebhookHttp,
|
|
102
105
|
normalizeOAuthTokenResponse: () => normalizeOAuthTokenResponse,
|
|
106
|
+
optionList: () => optionList,
|
|
107
|
+
parseWithServiceError: () => parseWithServiceError,
|
|
103
108
|
pickDefined: () => pickDefined,
|
|
109
|
+
pruneSeenEntries: () => pruneSeenEntries,
|
|
104
110
|
publicTool: () => publicTool,
|
|
105
111
|
pushBoundedApiErrorDetail: () => pushBoundedApiErrorDetail,
|
|
106
112
|
readApiErrorText: () => readApiErrorText,
|
|
107
113
|
redactUrlAttachmentSecrets: () => redactUrlAttachmentSecrets,
|
|
114
|
+
rememberPageToken: () => rememberPageToken,
|
|
108
115
|
requestAxios: () => requestAxios,
|
|
109
116
|
requestAxiosData: () => requestAxiosData,
|
|
110
117
|
runWithContext: () => runWithContext,
|
|
111
118
|
scopeClause: () => scopeClause,
|
|
119
|
+
seenEntryKey: () => seenEntryKey,
|
|
120
|
+
seenEntrySchema: () => seenEntrySchema,
|
|
112
121
|
setIfDefined: () => setIfDefined,
|
|
113
122
|
skipWebhook: () => skipWebhook,
|
|
114
123
|
spec: () => spec,
|
|
115
124
|
statusLabelForApiError: () => statusLabelForApiError,
|
|
125
|
+
timingSafeStringEqual: () => timingSafeStringEqual,
|
|
116
126
|
tool: () => tool,
|
|
117
127
|
toolCategory: () => toolCategory,
|
|
118
128
|
trigger: () => trigger,
|
|
@@ -1392,6 +1402,11 @@ var getApiErrorResponse = (error) => {
|
|
|
1392
1402
|
};
|
|
1393
1403
|
};
|
|
1394
1404
|
var getApiErrorStatus = (error) => getApiErrorResponse(error)?.status;
|
|
1405
|
+
var getUpstreamErrorStatus = (error) => {
|
|
1406
|
+
let value = error instanceof import_error.ServiceError ? error.data.upstreamStatus : getApiErrorStatus(error);
|
|
1407
|
+
let status = Number(value);
|
|
1408
|
+
return Number.isInteger(status) && status >= 100 && status <= 599 ? status : void 0;
|
|
1409
|
+
};
|
|
1395
1410
|
var getApiErrorResponseWithBody = (error) => {
|
|
1396
1411
|
let response = getApiErrorResponse(error);
|
|
1397
1412
|
if (response?.data !== void 0) return response;
|
|
@@ -1899,6 +1914,13 @@ var SlateDeclarationError = class _SlateDeclarationError extends SlateError {
|
|
|
1899
1914
|
}
|
|
1900
1915
|
};
|
|
1901
1916
|
|
|
1917
|
+
// src/error/parse.ts
|
|
1918
|
+
var parseWithServiceError = (schema, value, message, options = {}) => {
|
|
1919
|
+
let result = schema.safeParse(value);
|
|
1920
|
+
if (!result.success) throw createApiServiceError(message, options);
|
|
1921
|
+
return result.data;
|
|
1922
|
+
};
|
|
1923
|
+
|
|
1902
1924
|
// src/action/scopes.ts
|
|
1903
1925
|
var scopeClause = (...scopes) => {
|
|
1904
1926
|
assertScopeValues(scopes);
|
|
@@ -1967,6 +1989,45 @@ var isClause = (value) => typeof value === "object" && value !== null && "OR" in
|
|
|
1967
1989
|
var isScopes = (value) => typeof value === "object" && value !== null && "AND" in value && Array.isArray(value.AND);
|
|
1968
1990
|
|
|
1969
1991
|
// src/action/builder.ts
|
|
1992
|
+
var EVENT_ATTRIBUTE_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;
|
|
1993
|
+
var EVENT_ATTRIBUTE_MAX_KEYS = 8;
|
|
1994
|
+
var checkEventAttributeNames = (fields) => {
|
|
1995
|
+
if (!Array.isArray(fields)) {
|
|
1996
|
+
throw new SlateDeclarationError("Event attributes must be a list of output field names");
|
|
1997
|
+
}
|
|
1998
|
+
if (fields.length > EVENT_ATTRIBUTE_MAX_KEYS) {
|
|
1999
|
+
throw new SlateDeclarationError(
|
|
2000
|
+
`A trigger can declare at most ${EVENT_ATTRIBUTE_MAX_KEYS} event attributes`
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
2003
|
+
let seen = /* @__PURE__ */ new Set();
|
|
2004
|
+
for (let field of fields) {
|
|
2005
|
+
if (typeof field !== "string" || !EVENT_ATTRIBUTE_KEY_PATTERN.test(field)) {
|
|
2006
|
+
throw new SlateDeclarationError(
|
|
2007
|
+
`Event attribute "${field}" must start with a letter and contain only letters, digits and underscores (at most 64 characters)`
|
|
2008
|
+
);
|
|
2009
|
+
}
|
|
2010
|
+
if (seen.has(field)) {
|
|
2011
|
+
throw new SlateDeclarationError(`Event attribute "${field}" is declared more than once`);
|
|
2012
|
+
}
|
|
2013
|
+
seen.add(field);
|
|
2014
|
+
}
|
|
2015
|
+
};
|
|
2016
|
+
var checkEventAttributeFields = (fields, outputSchema) => {
|
|
2017
|
+
if (outputSchema._zod?.def?.type !== "object") {
|
|
2018
|
+
throw new SlateDeclarationError(
|
|
2019
|
+
"Event attributes require the output schema to be a zod object"
|
|
2020
|
+
);
|
|
2021
|
+
}
|
|
2022
|
+
let shape = outputSchema.shape;
|
|
2023
|
+
for (let field of fields) {
|
|
2024
|
+
if (!Object.hasOwn(shape, field)) {
|
|
2025
|
+
throw new SlateDeclarationError(
|
|
2026
|
+
`Event attribute "${field}" is not a top-level property of the output schema`
|
|
2027
|
+
);
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
};
|
|
1970
2031
|
var SlateActionBuilder = class {
|
|
1971
2032
|
constructor(type, spec2, params, factory, isPublicTool = false) {
|
|
1972
2033
|
this.type = type;
|
|
@@ -1992,6 +2053,7 @@ var SlateActionBuilder = class {
|
|
|
1992
2053
|
#triggerGroup = null;
|
|
1993
2054
|
#triggerMatches = null;
|
|
1994
2055
|
#triggerMap = null;
|
|
2056
|
+
#eventAttributes = null;
|
|
1995
2057
|
#interfaceLocked = false;
|
|
1996
2058
|
input(schema) {
|
|
1997
2059
|
if (this.#interfaceLocked) {
|
|
@@ -2062,6 +2124,21 @@ var SlateActionBuilder = class {
|
|
|
2062
2124
|
this.#triggerMap = handler;
|
|
2063
2125
|
return this;
|
|
2064
2126
|
}
|
|
2127
|
+
/**
|
|
2128
|
+
* Returns the values of these top-level output fields with every mapped event, so events
|
|
2129
|
+
* can be filtered by them. Strings, finite numbers, booleans and arrays of those are used.
|
|
2130
|
+
*/
|
|
2131
|
+
eventAttributes(fields) {
|
|
2132
|
+
if (this.type !== "trigger") {
|
|
2133
|
+
throw new SlateDeclarationError("eventAttributes can only be set for trigger actions");
|
|
2134
|
+
}
|
|
2135
|
+
checkEventAttributeNames(fields);
|
|
2136
|
+
if (this.#outputSchema) {
|
|
2137
|
+
checkEventAttributeFields(fields, this.#outputSchema);
|
|
2138
|
+
}
|
|
2139
|
+
this.#eventAttributes = [...fields];
|
|
2140
|
+
return this;
|
|
2141
|
+
}
|
|
2065
2142
|
build() {
|
|
2066
2143
|
let scopes = this.#scopes ?? this.params.scopes;
|
|
2067
2144
|
if (scopes) {
|
|
@@ -2089,11 +2166,15 @@ var SlateActionBuilder = class {
|
|
|
2089
2166
|
if (this.type === "trigger" && !this.#triggerMap) {
|
|
2090
2167
|
throw new SlateDeclarationError("Trigger map handler is not defined");
|
|
2091
2168
|
}
|
|
2169
|
+
if (this.#eventAttributes) {
|
|
2170
|
+
checkEventAttributeFields(this.#eventAttributes, this.#outputSchema);
|
|
2171
|
+
}
|
|
2092
2172
|
let triggerParams = this.type === "trigger" ? {
|
|
2093
2173
|
type: "trigger",
|
|
2094
2174
|
triggerGroup: this.#triggerGroup,
|
|
2095
2175
|
matches: this.#triggerMatches,
|
|
2096
|
-
map: this.#triggerMap
|
|
2176
|
+
map: this.#triggerMap,
|
|
2177
|
+
...this.#eventAttributes?.length ? { eventAttributes: this.#eventAttributes } : {}
|
|
2097
2178
|
} : null;
|
|
2098
2179
|
return this.factory({
|
|
2099
2180
|
...this.params,
|
|
@@ -2165,6 +2246,41 @@ var getFileUrlTool = (spec2, handleGetFileUrl) => tool(spec2, {
|
|
|
2165
2246
|
};
|
|
2166
2247
|
}).build();
|
|
2167
2248
|
|
|
2249
|
+
// src/action/optionList.ts
|
|
2250
|
+
var import_zod2 = require("zod");
|
|
2251
|
+
var SlateOptionList = class _SlateOptionList {
|
|
2252
|
+
constructor(_spec, _params, _paramsSchema) {
|
|
2253
|
+
this._spec = _spec;
|
|
2254
|
+
this._params = _params;
|
|
2255
|
+
this._paramsSchema = _paramsSchema;
|
|
2256
|
+
}
|
|
2257
|
+
_spec;
|
|
2258
|
+
_params;
|
|
2259
|
+
_paramsSchema;
|
|
2260
|
+
static create(spec2, params) {
|
|
2261
|
+
let paramsSchema = params.paramsSchema ?? import_zod2.z.object({});
|
|
2262
|
+
if (paramsSchema?._zod?.def?.type !== "object") {
|
|
2263
|
+
throw new SlateDeclarationError(
|
|
2264
|
+
`Option list "${params.key}" params schema must be a zod object`
|
|
2265
|
+
);
|
|
2266
|
+
}
|
|
2267
|
+
return new _SlateOptionList(spec2, params, paramsSchema.strict());
|
|
2268
|
+
}
|
|
2269
|
+
get spec() {
|
|
2270
|
+
return this._spec;
|
|
2271
|
+
}
|
|
2272
|
+
get key() {
|
|
2273
|
+
return this._params.key;
|
|
2274
|
+
}
|
|
2275
|
+
get paramsSchema() {
|
|
2276
|
+
return this._paramsSchema;
|
|
2277
|
+
}
|
|
2278
|
+
get list() {
|
|
2279
|
+
return this._params.list;
|
|
2280
|
+
}
|
|
2281
|
+
};
|
|
2282
|
+
var optionList = (spec2, params) => SlateOptionList.create(spec2, params);
|
|
2283
|
+
|
|
2168
2284
|
// src/action/publicTool.ts
|
|
2169
2285
|
var SlatePublicTool = class {
|
|
2170
2286
|
constructor() {
|
|
@@ -2218,11 +2334,13 @@ var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
|
2218
2334
|
#triggerGroup;
|
|
2219
2335
|
#matches;
|
|
2220
2336
|
#map;
|
|
2337
|
+
#eventAttributes;
|
|
2221
2338
|
constructor(spec2, inputSchema, outputSchema, params) {
|
|
2222
2339
|
super("trigger", spec2, inputSchema, outputSchema, params);
|
|
2223
2340
|
this.#triggerGroup = params.triggerGroup;
|
|
2224
2341
|
this.#matches = params.matches;
|
|
2225
2342
|
this.#map = params.map;
|
|
2343
|
+
this.#eventAttributes = params.eventAttributes ?? [];
|
|
2226
2344
|
}
|
|
2227
2345
|
static create(spec2, params) {
|
|
2228
2346
|
return new SlateActionBuilder("trigger", spec2, params, (params2) => {
|
|
@@ -2239,12 +2357,53 @@ var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
|
2239
2357
|
get map() {
|
|
2240
2358
|
return this.#map;
|
|
2241
2359
|
}
|
|
2360
|
+
get eventAttributes() {
|
|
2361
|
+
return [...this.#eventAttributes];
|
|
2362
|
+
}
|
|
2242
2363
|
};
|
|
2243
2364
|
var trigger = (spec2, params) => SlateTrigger.create(spec2, params);
|
|
2244
2365
|
|
|
2245
2366
|
// src/action/triggerGroup.ts
|
|
2246
|
-
var
|
|
2367
|
+
var import_zod3 = require("zod");
|
|
2247
2368
|
var SlateDefaultPollingIntervalSeconds = 60 * 10;
|
|
2369
|
+
var LINKED_SLATE_PATTERN = /^[^/\s]+\/[^/\s]+$/;
|
|
2370
|
+
var checkSelectionOptions = (field, sources, shape) => {
|
|
2371
|
+
if (!Object.hasOwn(shape, field)) {
|
|
2372
|
+
throw new SlateDeclarationError(
|
|
2373
|
+
`Selection field "${field}" is not a top-level property of the selection schema`
|
|
2374
|
+
);
|
|
2375
|
+
}
|
|
2376
|
+
if (typeof sources !== "object" || sources === null) {
|
|
2377
|
+
throw new SlateDeclarationError(
|
|
2378
|
+
`Selection field "${field}" must be declared as { list, linked }`
|
|
2379
|
+
);
|
|
2380
|
+
}
|
|
2381
|
+
let { list, linked } = sources;
|
|
2382
|
+
if (!list && !linked) {
|
|
2383
|
+
throw new SlateDeclarationError(
|
|
2384
|
+
`Selection field "${field}" needs its own options list, a linked option list, or both`
|
|
2385
|
+
);
|
|
2386
|
+
}
|
|
2387
|
+
if (list !== void 0 && typeof list !== "function") {
|
|
2388
|
+
throw new SlateDeclarationError(`Selection field "${field}" list must be a function`);
|
|
2389
|
+
}
|
|
2390
|
+
if (linked) {
|
|
2391
|
+
if (typeof linked.slate !== "string" || !LINKED_SLATE_PATTERN.test(linked.slate)) {
|
|
2392
|
+
throw new SlateDeclarationError(
|
|
2393
|
+
`Selection field "${field}" links to slate "${linked.slate}", which must be written as <scope>/<name>`
|
|
2394
|
+
);
|
|
2395
|
+
}
|
|
2396
|
+
if (typeof linked.optionList !== "string" || !linked.optionList.trim()) {
|
|
2397
|
+
throw new SlateDeclarationError(
|
|
2398
|
+
`Selection field "${field}" must name the option list it links to`
|
|
2399
|
+
);
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
return {
|
|
2403
|
+
...list ? { list } : {},
|
|
2404
|
+
...linked ? { linked } : {}
|
|
2405
|
+
};
|
|
2406
|
+
};
|
|
2248
2407
|
var SlateTriggerGroup = class _SlateTriggerGroup {
|
|
2249
2408
|
constructor(_spec, _params) {
|
|
2250
2409
|
this._spec = _spec;
|
|
@@ -2271,11 +2430,14 @@ var SlateTriggerGroup = class _SlateTriggerGroup {
|
|
|
2271
2430
|
return this._params.metadata;
|
|
2272
2431
|
}
|
|
2273
2432
|
get eventSchema() {
|
|
2274
|
-
return this._params.eventSchema ??
|
|
2433
|
+
return this._params.eventSchema ?? import_zod3.z.object({}).passthrough();
|
|
2275
2434
|
}
|
|
2276
2435
|
get source() {
|
|
2277
2436
|
return this._params.source;
|
|
2278
2437
|
}
|
|
2438
|
+
get selectionSchema() {
|
|
2439
|
+
return this._params.selectionSchema;
|
|
2440
|
+
}
|
|
2279
2441
|
get polling() {
|
|
2280
2442
|
return this._params.polling;
|
|
2281
2443
|
}
|
|
@@ -2288,6 +2450,9 @@ var SlateTriggerGroup = class _SlateTriggerGroup {
|
|
|
2288
2450
|
get routingMatchers() {
|
|
2289
2451
|
return this._params.routingMatchers;
|
|
2290
2452
|
}
|
|
2453
|
+
get selectionOptions() {
|
|
2454
|
+
return this._params.selectionOptions ?? {};
|
|
2455
|
+
}
|
|
2291
2456
|
};
|
|
2292
2457
|
var SlateTriggerGroupBuilder = class {
|
|
2293
2458
|
constructor(spec2, params, factory) {
|
|
@@ -2303,6 +2468,7 @@ var SlateTriggerGroupBuilder = class {
|
|
|
2303
2468
|
#webhook = null;
|
|
2304
2469
|
#gateway = null;
|
|
2305
2470
|
#routingMatchers = null;
|
|
2471
|
+
#selectionOptions = {};
|
|
2306
2472
|
polling(props) {
|
|
2307
2473
|
if (this.#source) {
|
|
2308
2474
|
throw new SlateDeclarationError("Trigger group invocation is already defined");
|
|
@@ -2323,11 +2489,41 @@ var SlateTriggerGroupBuilder = class {
|
|
|
2323
2489
|
"Webhook trigger groups require exactly one of autoRegistration or manualRegistration"
|
|
2324
2490
|
);
|
|
2325
2491
|
}
|
|
2492
|
+
if (props.deliveryConfig !== void 0) {
|
|
2493
|
+
if (!props.autoRegistration) {
|
|
2494
|
+
throw new SlateDeclarationError(
|
|
2495
|
+
"A webhook delivery config requires automatic webhook registration"
|
|
2496
|
+
);
|
|
2497
|
+
}
|
|
2498
|
+
if (!props.deliveryConfig.finish) {
|
|
2499
|
+
throw new SlateDeclarationError("A webhook delivery config requires a finish handler");
|
|
2500
|
+
}
|
|
2501
|
+
if (!props.deliveryConfig.authenticate) {
|
|
2502
|
+
throw new SlateDeclarationError(
|
|
2503
|
+
"A webhook delivery config requires an authenticate handler"
|
|
2504
|
+
);
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
if (props.reconcileIntervalSeconds !== void 0) {
|
|
2508
|
+
if (!Number.isSafeInteger(props.reconcileIntervalSeconds) || props.reconcileIntervalSeconds < 900) {
|
|
2509
|
+
throw new SlateDeclarationError(
|
|
2510
|
+
"Webhook reconciliation interval must be an integer of at least 900 seconds"
|
|
2511
|
+
);
|
|
2512
|
+
}
|
|
2513
|
+
if (!props.expandWebhook) {
|
|
2514
|
+
throw new SlateDeclarationError(
|
|
2515
|
+
"Webhook reconciliation requires an expandWebhook handler"
|
|
2516
|
+
);
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2326
2519
|
this.#source = "webhook";
|
|
2327
2520
|
this.#webhook = {
|
|
2328
2521
|
autoRegistration: props.autoRegistration,
|
|
2329
2522
|
manualRegistration: props.manualRegistration,
|
|
2330
|
-
|
|
2523
|
+
deliveryConfig: props.deliveryConfig,
|
|
2524
|
+
process: props.process,
|
|
2525
|
+
expandWebhook: props.expandWebhook,
|
|
2526
|
+
reconcileIntervalSeconds: props.reconcileIntervalSeconds
|
|
2331
2527
|
};
|
|
2332
2528
|
return this;
|
|
2333
2529
|
}
|
|
@@ -2344,6 +2540,27 @@ var SlateTriggerGroupBuilder = class {
|
|
|
2344
2540
|
this.#routingMatchers = handler;
|
|
2345
2541
|
return this;
|
|
2346
2542
|
}
|
|
2543
|
+
/**
|
|
2544
|
+
* Lets the dashboard offer a list for these selection fields instead of a typed-in value.
|
|
2545
|
+
* Each field must be a top-level property of the selection schema, which must be a zod object.
|
|
2546
|
+
* For an array property the listed options are values for its items.
|
|
2547
|
+
*/
|
|
2548
|
+
selectionOptions(declarations) {
|
|
2549
|
+
let schema = this.params.selectionSchema;
|
|
2550
|
+
if (!schema) {
|
|
2551
|
+
throw new SlateDeclarationError("Selection options require a selection schema");
|
|
2552
|
+
}
|
|
2553
|
+
if (schema._zod?.def?.type !== "object") {
|
|
2554
|
+
throw new SlateDeclarationError(
|
|
2555
|
+
"Selection options require the selection schema to be a zod object"
|
|
2556
|
+
);
|
|
2557
|
+
}
|
|
2558
|
+
let shape = schema.shape;
|
|
2559
|
+
for (let [field, sources] of Object.entries(declarations)) {
|
|
2560
|
+
this.#selectionOptions[field] = checkSelectionOptions(field, sources, shape);
|
|
2561
|
+
}
|
|
2562
|
+
return this;
|
|
2563
|
+
}
|
|
2347
2564
|
build() {
|
|
2348
2565
|
if (!this.#source) {
|
|
2349
2566
|
throw new SlateDeclarationError(
|
|
@@ -2359,7 +2576,8 @@ var SlateTriggerGroupBuilder = class {
|
|
|
2359
2576
|
polling: this.#polling ?? void 0,
|
|
2360
2577
|
webhook: this.#webhook ?? void 0,
|
|
2361
2578
|
gateway: this.#gateway ?? void 0,
|
|
2362
|
-
routingMatchers: this.#routingMatchers
|
|
2579
|
+
routingMatchers: this.#routingMatchers,
|
|
2580
|
+
selectionOptions: this.#selectionOptions
|
|
2363
2581
|
});
|
|
2364
2582
|
}
|
|
2365
2583
|
};
|
|
@@ -3107,13 +3325,29 @@ var createHmacSignature = ({
|
|
|
3107
3325
|
digest,
|
|
3108
3326
|
prefix = ""
|
|
3109
3327
|
}) => `${prefix}${(0, import_crypto.createHmac)(algorithm, secret).update(payload).digest(digest)}`;
|
|
3110
|
-
var
|
|
3111
|
-
let expected = createHmacSignature(options);
|
|
3328
|
+
var timingSafeStringEqual = (expected, received) => {
|
|
3112
3329
|
let expectedBytes = Buffer.from(expected);
|
|
3113
|
-
let
|
|
3114
|
-
let lengthsMatch =
|
|
3115
|
-
let
|
|
3116
|
-
return (0, import_crypto.timingSafeEqual)(
|
|
3330
|
+
let receivedBytes = Buffer.from(received ?? "");
|
|
3331
|
+
let lengthsMatch = receivedBytes.length === expectedBytes.length;
|
|
3332
|
+
let comparable = lengthsMatch ? receivedBytes : Buffer.alloc(expectedBytes.length);
|
|
3333
|
+
return (0, import_crypto.timingSafeEqual)(comparable, expectedBytes) && lengthsMatch && expectedBytes.length > 0;
|
|
3334
|
+
};
|
|
3335
|
+
var verifyHmacSignature = (options) => timingSafeStringEqual(createHmacSignature(options), options.signature);
|
|
3336
|
+
|
|
3337
|
+
// src/dedup/index.ts
|
|
3338
|
+
var import_crypto2 = require("crypto");
|
|
3339
|
+
var import_zod4 = require("zod");
|
|
3340
|
+
var seenEntrySchema = import_zod4.z.object({ key: import_zod4.z.string().min(1), at: import_zod4.z.number().finite() });
|
|
3341
|
+
var seenEntryKey = (idempotencyKey) => (0, import_crypto2.createHash)("sha256").update(idempotencyKey).digest("base64url").slice(0, 16);
|
|
3342
|
+
var pruneSeenEntries = (entries, options) => {
|
|
3343
|
+
let kept = [];
|
|
3344
|
+
for (let { key, at, retain } of entries) {
|
|
3345
|
+
if (retain || at >= options.cutoff) kept.push({ key, at });
|
|
3346
|
+
}
|
|
3347
|
+
kept.sort((a, b) => b.at - a.at || (a.key < b.key ? -1 : 1));
|
|
3348
|
+
if (kept.length <= options.maxEntries) return kept;
|
|
3349
|
+
options.onOverflow?.(kept.length - options.maxEntries);
|
|
3350
|
+
return kept.slice(0, options.maxEntries);
|
|
3117
3351
|
};
|
|
3118
3352
|
|
|
3119
3353
|
// src/file/index.ts
|
|
@@ -3243,15 +3477,26 @@ var setIfDefined = (target, key, value) => {
|
|
|
3243
3477
|
return target;
|
|
3244
3478
|
};
|
|
3245
3479
|
|
|
3480
|
+
// src/pagination/index.ts
|
|
3481
|
+
var rememberPageToken = (seen, token) => {
|
|
3482
|
+
if (seen.has(token)) return false;
|
|
3483
|
+
seen.add(token);
|
|
3484
|
+
return true;
|
|
3485
|
+
};
|
|
3486
|
+
var assertNewPageToken = (seen, token, repeated) => {
|
|
3487
|
+
if (token && !rememberPageToken(seen, token)) throw repeated();
|
|
3488
|
+
};
|
|
3489
|
+
|
|
3246
3490
|
// src/specification/slate.ts
|
|
3247
3491
|
var Slate = class _Slate {
|
|
3248
|
-
constructor(_spec, _actions, _adapters, _triggerGroups, _toolCategories, _toolCategoryKeysByActionKey) {
|
|
3492
|
+
constructor(_spec, _actions, _adapters, _triggerGroups, _toolCategories, _toolCategoryKeysByActionKey, _optionLists) {
|
|
3249
3493
|
this._spec = _spec;
|
|
3250
3494
|
this._actions = _actions;
|
|
3251
3495
|
this._adapters = _adapters;
|
|
3252
3496
|
this._triggerGroups = _triggerGroups;
|
|
3253
3497
|
this._toolCategories = _toolCategories;
|
|
3254
3498
|
this._toolCategoryKeysByActionKey = _toolCategoryKeysByActionKey;
|
|
3499
|
+
this._optionLists = _optionLists;
|
|
3255
3500
|
}
|
|
3256
3501
|
_spec;
|
|
3257
3502
|
_actions;
|
|
@@ -3259,6 +3504,7 @@ var Slate = class _Slate {
|
|
|
3259
3504
|
_triggerGroups;
|
|
3260
3505
|
_toolCategories;
|
|
3261
3506
|
_toolCategoryKeysByActionKey;
|
|
3507
|
+
_optionLists;
|
|
3262
3508
|
static create(params) {
|
|
3263
3509
|
let adapters = params.adapters ?? [];
|
|
3264
3510
|
let actions = [...params.triggers, ...params.tools];
|
|
@@ -3294,14 +3540,24 @@ var Slate = class _Slate {
|
|
|
3294
3540
|
}
|
|
3295
3541
|
seenTriggerGroupKeys.add(group.key);
|
|
3296
3542
|
}
|
|
3297
|
-
let
|
|
3298
|
-
(group) => group.source === "webhook" && group.webhook?.manualRegistration
|
|
3543
|
+
let configuredWebhookTriggerGroups = triggerGroups.filter(
|
|
3544
|
+
(group) => group.source === "webhook" && (group.webhook?.manualRegistration || group.webhook?.deliveryConfig)
|
|
3299
3545
|
);
|
|
3300
|
-
if (
|
|
3546
|
+
if (configuredWebhookTriggerGroups.length > 1) {
|
|
3301
3547
|
throw new SlateDeclarationError(
|
|
3302
|
-
`Only one trigger group may use manual webhook registration, but found: ${
|
|
3548
|
+
`Only one trigger group may use manual webhook registration or a delivery config, but found: ${configuredWebhookTriggerGroups.map((group) => group.key).join(", ")}`
|
|
3303
3549
|
);
|
|
3304
3550
|
}
|
|
3551
|
+
let optionLists = params.optionLists ?? [];
|
|
3552
|
+
let seenOptionListKeys = /* @__PURE__ */ new Set();
|
|
3553
|
+
for (let list of optionLists) {
|
|
3554
|
+
if (seenOptionListKeys.has(list.key)) {
|
|
3555
|
+
throw new SlateDeclarationError(
|
|
3556
|
+
`Option list "${list.key}" is registered more than once`
|
|
3557
|
+
);
|
|
3558
|
+
}
|
|
3559
|
+
seenOptionListKeys.add(list.key);
|
|
3560
|
+
}
|
|
3305
3561
|
let toolCategories = params.toolCategories ?? [];
|
|
3306
3562
|
let toolCategoryKeysByActionKey = resolveToolCategoryMembership(toolCategories, actions);
|
|
3307
3563
|
return new _Slate(
|
|
@@ -3310,7 +3566,8 @@ var Slate = class _Slate {
|
|
|
3310
3566
|
adapters,
|
|
3311
3567
|
triggerGroups,
|
|
3312
3568
|
toolCategories,
|
|
3313
|
-
toolCategoryKeysByActionKey
|
|
3569
|
+
toolCategoryKeysByActionKey,
|
|
3570
|
+
optionLists
|
|
3314
3571
|
);
|
|
3315
3572
|
}
|
|
3316
3573
|
get spec() {
|
|
@@ -3328,6 +3585,9 @@ var Slate = class _Slate {
|
|
|
3328
3585
|
get toolCategories() {
|
|
3329
3586
|
return this._toolCategories ?? [];
|
|
3330
3587
|
}
|
|
3588
|
+
get optionLists() {
|
|
3589
|
+
return this._optionLists ?? [];
|
|
3590
|
+
}
|
|
3331
3591
|
// Keys of the tool categories an action belongs to, in declared category order.
|
|
3332
3592
|
getToolCategoryKeys(actionKey) {
|
|
3333
3593
|
return [...this._toolCategoryKeysByActionKey?.get(actionKey) ?? []];
|
|
@@ -3401,7 +3661,7 @@ var resolveToolCategoryMembership = (toolCategories, actions) => {
|
|
|
3401
3661
|
};
|
|
3402
3662
|
|
|
3403
3663
|
// src/specification/specification.ts
|
|
3404
|
-
var
|
|
3664
|
+
var import_zod5 = __toESM(require("zod"), 1);
|
|
3405
3665
|
var SlateSpecification = class _SlateSpecification {
|
|
3406
3666
|
constructor(_config, _auth, _params) {
|
|
3407
3667
|
this._config = _config;
|
|
@@ -3418,7 +3678,7 @@ var SlateSpecification = class _SlateSpecification {
|
|
|
3418
3678
|
return this._config.configSchema;
|
|
3419
3679
|
}
|
|
3420
3680
|
get authSchema() {
|
|
3421
|
-
return "outputSchema" in this._auth ? this._auth.outputSchema :
|
|
3681
|
+
return "outputSchema" in this._auth ? this._auth.outputSchema : import_zod5.default.object({});
|
|
3422
3682
|
}
|
|
3423
3683
|
get config() {
|
|
3424
3684
|
return this._config;
|
|
@@ -3523,6 +3783,7 @@ var skipWebhook = (reason, response) => ({
|
|
|
3523
3783
|
SlateDefaultPollingIntervalSeconds,
|
|
3524
3784
|
SlateError,
|
|
3525
3785
|
SlateLogger,
|
|
3786
|
+
SlateOptionList,
|
|
3526
3787
|
SlatePublicContext,
|
|
3527
3788
|
SlatePublicTool,
|
|
3528
3789
|
SlateSpecification,
|
|
@@ -3534,6 +3795,7 @@ var skipWebhook = (reason, response) => ({
|
|
|
3534
3795
|
adapterSpec,
|
|
3535
3796
|
allOf,
|
|
3536
3797
|
anyOf,
|
|
3798
|
+
assertNewPageToken,
|
|
3537
3799
|
auth,
|
|
3538
3800
|
axios,
|
|
3539
3801
|
buildApiServiceError,
|
|
@@ -3563,6 +3825,7 @@ var skipWebhook = (reason, response) => ({
|
|
|
3563
3825
|
getResponseHeaderValue,
|
|
3564
3826
|
getRuntimeInfo,
|
|
3565
3827
|
getServiceErrorData,
|
|
3828
|
+
getUpstreamErrorStatus,
|
|
3566
3829
|
graphWebhookHttp,
|
|
3567
3830
|
inferSlateErrorFromAxios,
|
|
3568
3831
|
isApiErrorRecord,
|
|
@@ -3575,19 +3838,26 @@ var skipWebhook = (reason, response) => ({
|
|
|
3575
3838
|
mergeScopes,
|
|
3576
3839
|
metaWebhookHttp,
|
|
3577
3840
|
normalizeOAuthTokenResponse,
|
|
3841
|
+
optionList,
|
|
3842
|
+
parseWithServiceError,
|
|
3578
3843
|
pickDefined,
|
|
3844
|
+
pruneSeenEntries,
|
|
3579
3845
|
publicTool,
|
|
3580
3846
|
pushBoundedApiErrorDetail,
|
|
3581
3847
|
readApiErrorText,
|
|
3582
3848
|
redactUrlAttachmentSecrets,
|
|
3849
|
+
rememberPageToken,
|
|
3583
3850
|
requestAxios,
|
|
3584
3851
|
requestAxiosData,
|
|
3585
3852
|
runWithContext,
|
|
3586
3853
|
scopeClause,
|
|
3854
|
+
seenEntryKey,
|
|
3855
|
+
seenEntrySchema,
|
|
3587
3856
|
setIfDefined,
|
|
3588
3857
|
skipWebhook,
|
|
3589
3858
|
spec,
|
|
3590
3859
|
statusLabelForApiError,
|
|
3860
|
+
timingSafeStringEqual,
|
|
3591
3861
|
tool,
|
|
3592
3862
|
toolCategory,
|
|
3593
3863
|
trigger,
|