@slates/provider 1.0.0-rc.29 → 1.0.0-rc.30
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 +119 -2
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.module.js +117 -2
- package/package.json +1 -1
- package/src/action/index.ts +1 -0
- package/src/action/toolCategory.ts +40 -0
- package/src/specification/slate.test.ts +153 -1
- package/src/specification/slate.ts +105 -3
package/dist/index.cjs
CHANGED
|
@@ -52,6 +52,7 @@ __export(index_exports, {
|
|
|
52
52
|
SlatePublicTool: () => SlatePublicTool,
|
|
53
53
|
SlateSpecification: () => SlateSpecification,
|
|
54
54
|
SlateTool: () => SlateTool,
|
|
55
|
+
SlateToolCategory: () => SlateToolCategory,
|
|
55
56
|
SlateTrigger: () => SlateTrigger,
|
|
56
57
|
SlateTriggerGroup: () => SlateTriggerGroup,
|
|
57
58
|
SlateTriggerGroupBuilder: () => SlateTriggerGroupBuilder,
|
|
@@ -112,6 +113,7 @@ __export(index_exports, {
|
|
|
112
113
|
spec: () => spec,
|
|
113
114
|
statusLabelForApiError: () => statusLabelForApiError,
|
|
114
115
|
tool: () => tool,
|
|
116
|
+
toolCategory: () => toolCategory,
|
|
115
117
|
trigger: () => trigger,
|
|
116
118
|
triggerGroup: () => triggerGroup,
|
|
117
119
|
truncateApiErrorMessage: () => truncateApiErrorMessage,
|
|
@@ -2178,6 +2180,33 @@ var SlatePublicTool = class {
|
|
|
2178
2180
|
};
|
|
2179
2181
|
var publicTool = (spec2, params) => SlatePublicTool.create(spec2, params);
|
|
2180
2182
|
|
|
2183
|
+
// src/action/toolCategory.ts
|
|
2184
|
+
var SlateToolCategory = class _SlateToolCategory {
|
|
2185
|
+
constructor(_params) {
|
|
2186
|
+
this._params = _params;
|
|
2187
|
+
}
|
|
2188
|
+
_params;
|
|
2189
|
+
static create(params) {
|
|
2190
|
+
return new _SlateToolCategory(params);
|
|
2191
|
+
}
|
|
2192
|
+
get key() {
|
|
2193
|
+
return this._params.key;
|
|
2194
|
+
}
|
|
2195
|
+
get name() {
|
|
2196
|
+
return this._params.name;
|
|
2197
|
+
}
|
|
2198
|
+
get description() {
|
|
2199
|
+
return this._params.description;
|
|
2200
|
+
}
|
|
2201
|
+
get imageUrl() {
|
|
2202
|
+
return this._params.imageUrl;
|
|
2203
|
+
}
|
|
2204
|
+
get tools() {
|
|
2205
|
+
return this._params.tools;
|
|
2206
|
+
}
|
|
2207
|
+
};
|
|
2208
|
+
var toolCategory = (params) => SlateToolCategory.create(params);
|
|
2209
|
+
|
|
2181
2210
|
// src/action/trigger.ts
|
|
2182
2211
|
var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
2183
2212
|
#triggerGroup;
|
|
@@ -3201,16 +3230,20 @@ var setIfDefined = (target, key, value) => {
|
|
|
3201
3230
|
|
|
3202
3231
|
// src/specification/slate.ts
|
|
3203
3232
|
var Slate = class _Slate {
|
|
3204
|
-
constructor(_spec, _actions, _adapters, _triggerGroups) {
|
|
3233
|
+
constructor(_spec, _actions, _adapters, _triggerGroups, _toolCategories, _toolCategoryKeysByActionKey) {
|
|
3205
3234
|
this._spec = _spec;
|
|
3206
3235
|
this._actions = _actions;
|
|
3207
3236
|
this._adapters = _adapters;
|
|
3208
3237
|
this._triggerGroups = _triggerGroups;
|
|
3238
|
+
this._toolCategories = _toolCategories;
|
|
3239
|
+
this._toolCategoryKeysByActionKey = _toolCategoryKeysByActionKey;
|
|
3209
3240
|
}
|
|
3210
3241
|
_spec;
|
|
3211
3242
|
_actions;
|
|
3212
3243
|
_adapters;
|
|
3213
3244
|
_triggerGroups;
|
|
3245
|
+
_toolCategories;
|
|
3246
|
+
_toolCategoryKeysByActionKey;
|
|
3214
3247
|
static create(params) {
|
|
3215
3248
|
let adapters = params.adapters ?? [];
|
|
3216
3249
|
let actions = [...params.triggers, ...params.tools];
|
|
@@ -3254,7 +3287,16 @@ var Slate = class _Slate {
|
|
|
3254
3287
|
`Only one trigger group may use manual webhook registration, but found: ${manualWebhookTriggerGroups.map((group) => group.key).join(", ")}`
|
|
3255
3288
|
);
|
|
3256
3289
|
}
|
|
3257
|
-
|
|
3290
|
+
let toolCategories = params.toolCategories ?? [];
|
|
3291
|
+
let toolCategoryKeysByActionKey = resolveToolCategoryMembership(toolCategories, actions);
|
|
3292
|
+
return new _Slate(
|
|
3293
|
+
params.spec,
|
|
3294
|
+
actions,
|
|
3295
|
+
adapters,
|
|
3296
|
+
triggerGroups,
|
|
3297
|
+
toolCategories,
|
|
3298
|
+
toolCategoryKeysByActionKey
|
|
3299
|
+
);
|
|
3258
3300
|
}
|
|
3259
3301
|
get spec() {
|
|
3260
3302
|
return this._spec;
|
|
@@ -3268,6 +3310,79 @@ var Slate = class _Slate {
|
|
|
3268
3310
|
get triggerGroups() {
|
|
3269
3311
|
return this._triggerGroups ?? [];
|
|
3270
3312
|
}
|
|
3313
|
+
get toolCategories() {
|
|
3314
|
+
return this._toolCategories ?? [];
|
|
3315
|
+
}
|
|
3316
|
+
// Keys of the tool categories an action belongs to, in declared category order.
|
|
3317
|
+
getToolCategoryKeys(actionKey) {
|
|
3318
|
+
return [...this._toolCategoryKeysByActionKey?.get(actionKey) ?? []];
|
|
3319
|
+
}
|
|
3320
|
+
};
|
|
3321
|
+
var TOOL_CATEGORY_KEY_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
3322
|
+
var isHttpUrl = (value) => {
|
|
3323
|
+
try {
|
|
3324
|
+
let url = new URL(value);
|
|
3325
|
+
return url.protocol === "https:" || url.protocol === "http:";
|
|
3326
|
+
} catch {
|
|
3327
|
+
return false;
|
|
3328
|
+
}
|
|
3329
|
+
};
|
|
3330
|
+
var resolveToolCategoryMembership = (toolCategories, actions) => {
|
|
3331
|
+
let effectiveActions = /* @__PURE__ */ new Map();
|
|
3332
|
+
for (let action of actions) {
|
|
3333
|
+
if (!effectiveActions.has(action.key)) effectiveActions.set(action.key, action);
|
|
3334
|
+
}
|
|
3335
|
+
let registeredActions = new Set(actions);
|
|
3336
|
+
let membersByCategoryKey = /* @__PURE__ */ new Map();
|
|
3337
|
+
for (let category of toolCategories) {
|
|
3338
|
+
if (!TOOL_CATEGORY_KEY_PATTERN.test(category.key)) {
|
|
3339
|
+
throw new SlateDeclarationError(
|
|
3340
|
+
`Tool category key "${category.key}" must match ${TOOL_CATEGORY_KEY_PATTERN}`
|
|
3341
|
+
);
|
|
3342
|
+
}
|
|
3343
|
+
if (membersByCategoryKey.has(category.key)) {
|
|
3344
|
+
throw new SlateDeclarationError(
|
|
3345
|
+
`Tool category "${category.key}" is registered more than once`
|
|
3346
|
+
);
|
|
3347
|
+
}
|
|
3348
|
+
if (!category.name?.trim()) {
|
|
3349
|
+
throw new SlateDeclarationError(`Tool category "${category.key}" must have a name`);
|
|
3350
|
+
}
|
|
3351
|
+
if (category.imageUrl !== void 0 && !isHttpUrl(category.imageUrl)) {
|
|
3352
|
+
throw new SlateDeclarationError(
|
|
3353
|
+
`Tool category "${category.key}" imageUrl must be an absolute http(s) URL`
|
|
3354
|
+
);
|
|
3355
|
+
}
|
|
3356
|
+
if (!category.tools?.length) {
|
|
3357
|
+
throw new SlateDeclarationError(
|
|
3358
|
+
`Tool category "${category.key}" must list at least one tool`
|
|
3359
|
+
);
|
|
3360
|
+
}
|
|
3361
|
+
let members = /* @__PURE__ */ new Set();
|
|
3362
|
+
for (let tool2 of category.tools) {
|
|
3363
|
+
if (!registeredActions.has(tool2)) {
|
|
3364
|
+
throw new SlateDeclarationError(
|
|
3365
|
+
`Tool category "${category.key}" lists tool "${tool2.key}", which is not registered in this slate`
|
|
3366
|
+
);
|
|
3367
|
+
}
|
|
3368
|
+
if (tool2.type !== "tool") {
|
|
3369
|
+
throw new SlateDeclarationError(
|
|
3370
|
+
`Tool category "${category.key}" lists trigger "${tool2.key}", but only tools can belong to a tool category`
|
|
3371
|
+
);
|
|
3372
|
+
}
|
|
3373
|
+
if (effectiveActions.get(tool2.key) === tool2) members.add(tool2.key);
|
|
3374
|
+
}
|
|
3375
|
+
membersByCategoryKey.set(category.key, members);
|
|
3376
|
+
}
|
|
3377
|
+
let keysByActionKey = /* @__PURE__ */ new Map();
|
|
3378
|
+
for (let category of toolCategories) {
|
|
3379
|
+
for (let actionKey of membersByCategoryKey.get(category.key) ?? []) {
|
|
3380
|
+
let keys = keysByActionKey.get(actionKey) ?? [];
|
|
3381
|
+
keys.push(category.key);
|
|
3382
|
+
keysByActionKey.set(actionKey, keys);
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
return keysByActionKey;
|
|
3271
3386
|
};
|
|
3272
3387
|
|
|
3273
3388
|
// src/specification/specification.ts
|
|
@@ -3397,6 +3512,7 @@ var skipWebhook = (reason, response) => ({
|
|
|
3397
3512
|
SlatePublicTool,
|
|
3398
3513
|
SlateSpecification,
|
|
3399
3514
|
SlateTool,
|
|
3515
|
+
SlateToolCategory,
|
|
3400
3516
|
SlateTrigger,
|
|
3401
3517
|
SlateTriggerGroup,
|
|
3402
3518
|
SlateTriggerGroupBuilder,
|
|
@@ -3457,6 +3573,7 @@ var skipWebhook = (reason, response) => ({
|
|
|
3457
3573
|
spec,
|
|
3458
3574
|
statusLabelForApiError,
|
|
3459
3575
|
tool,
|
|
3576
|
+
toolCategory,
|
|
3460
3577
|
trigger,
|
|
3461
3578
|
triggerGroup,
|
|
3462
3579
|
truncateApiErrorMessage,
|
package/dist/index.d.cts
CHANGED
|
@@ -857,6 +857,25 @@ declare let allOf: (...inputs: SlateActionScopesInput[]) => SlateActionScopes;
|
|
|
857
857
|
declare let mergeScopes: (...inputs: Array<SlateActionScopes | null | undefined | false>) => SlateActionScopes | undefined;
|
|
858
858
|
declare let validateScopes: (scopes: SlateActionScopes) => SlateActionScopes;
|
|
859
859
|
|
|
860
|
+
interface SlateToolCategoryParameters {
|
|
861
|
+
key: string;
|
|
862
|
+
name: string;
|
|
863
|
+
description?: string;
|
|
864
|
+
imageUrl?: string;
|
|
865
|
+
tools: SlateTool<any, any, any, any>[];
|
|
866
|
+
}
|
|
867
|
+
declare class SlateToolCategory {
|
|
868
|
+
private readonly _params;
|
|
869
|
+
private constructor();
|
|
870
|
+
static create(params: SlateToolCategoryParameters): SlateToolCategory;
|
|
871
|
+
get key(): string;
|
|
872
|
+
get name(): string;
|
|
873
|
+
get description(): string | undefined;
|
|
874
|
+
get imageUrl(): string | undefined;
|
|
875
|
+
get tools(): SlateTool<any, any, any, any>[];
|
|
876
|
+
}
|
|
877
|
+
declare let toolCategory: (params: SlateToolCategoryParameters) => SlateToolCategory;
|
|
878
|
+
|
|
860
879
|
interface SlateTriggerParameters<ConfigType extends {}, AuthType extends {}, InputType extends {}, OutputType extends {
|
|
861
880
|
type: string;
|
|
862
881
|
}> extends SlateActionParameters {
|
|
@@ -1123,6 +1142,8 @@ declare class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
1123
1142
|
private readonly _actions;
|
|
1124
1143
|
private readonly _adapters;
|
|
1125
1144
|
private readonly _triggerGroups;
|
|
1145
|
+
private readonly _toolCategories;
|
|
1146
|
+
private readonly _toolCategoryKeysByActionKey;
|
|
1126
1147
|
private constructor();
|
|
1127
1148
|
static create<ConfigType extends {}, AuthType extends {}>(params: {
|
|
1128
1149
|
spec: SlateSpecification<ConfigType, AuthType>;
|
|
@@ -1130,11 +1151,14 @@ declare class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
1130
1151
|
tools: SlateTool<ConfigType, AuthType, any, any>[];
|
|
1131
1152
|
adapters?: SlateAdapter<ConfigType, AuthType>[];
|
|
1132
1153
|
triggerGroups?: SlateTriggerGroup<ConfigType, AuthType>[];
|
|
1154
|
+
toolCategories?: SlateToolCategory[];
|
|
1133
1155
|
}): Slate<ConfigType, AuthType>;
|
|
1134
1156
|
get spec(): SlateSpecification<ConfigType, AuthType>;
|
|
1135
1157
|
get actions(): (SlateTrigger<ConfigType, AuthType, any, any> | SlateTool<ConfigType, AuthType, any, any>)[];
|
|
1136
1158
|
get adapters(): SlateAdapter<ConfigType, AuthType>[];
|
|
1137
1159
|
get triggerGroups(): SlateTriggerGroup<ConfigType, AuthType, Record<string, unknown>>[];
|
|
1160
|
+
get toolCategories(): SlateToolCategory[];
|
|
1161
|
+
getToolCategoryKeys(actionKey: string): string[];
|
|
1138
1162
|
}
|
|
1139
1163
|
|
|
1140
1164
|
declare const graphWebhookHttp: {
|
|
@@ -1168,4 +1192,4 @@ declare let skipWebhook: (reason: string, response?: Response | SlateWebhookHttp
|
|
|
1168
1192
|
response: Response | SlateWebhookHttpResponseInit;
|
|
1169
1193
|
};
|
|
1170
1194
|
|
|
1171
|
-
export { API_ERROR_MAX_DETAILS, API_ERROR_MAX_MESSAGE_LENGTH, API_ERROR_TRUNCATED_PLACEHOLDER, AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX, type ApiErrorBuildHelpers, type ApiErrorDetailOptions, type ApiErrorResponse, type ApiErrorStatus, type ApiErrorTextOptions, type ApiServiceError, type AuthConfigSecretFilter, AuthConfigSecretRedactor, type BoundedApiErrorDetailOptions, type BuildApiServiceErrorOptions, type CreateHmacSignatureOptions, type DecodeApiErrorBodyOptions, GET_FILE_URL_TOOL_ID, type GetFileUrlHandler, type GetFileUrlToolInput, type GetFileUrlToolOutput, type NormalizeOAuthTokenResponseOptions, type OAuthExpiresAtOptions, type OAuthRefreshTokenFallbackMode, type OAuthTokenResponse, Slate, SlateAction, SlateActionBuilder, type SlateActionCreateParameters, type SlateActionDocsReference, type SlateActionParameters, type SlateActionParametersAny, type SlateActionParametersTool, type SlateActionParametersTrigger, type SlateActionScopeClause, type SlateActionScopeClauseInput, type SlateActionScopeValue, type SlateActionScopes, type SlateActionScopesInput, type SlateActionType, SlateAdapter, type SlateAdapterCapability, SlateAdapterSpec, type SlateAdapterSpecParameters, type SlateAddAttachmentContent, type SlateAddAttachmentInput, type SlateAttachment, type SlateAttachmentInlineContent, type SlateAttachmentUploadReferenceContent, type SlateAttachmentUrlContent, SlateAuth, type SlateAuthDocsReference, type SlateAuthType, type SlateAuthWithCustomData, type SlateAuthWithNone, type SlateAuthWithOauth, type SlateAuthWithServiceAccount, type SlateAuthWithToken, type SlateAuthenticatedAxiosDefaults, type SlateAxiosDefaults, type SlateAxiosErrorAdapter, type SlateAxiosErrorOptions, SlateConfig, type SlateConfigDocsReference, SlateContext, SlateDeclarationError, SlateDefaultPollingIntervalSeconds, type SlateDirectUploadInput, type SlateDocsReference, SlateError, type SlateErrorInput, type SlateErrorIssue, type SlateErrorKind, type SlateErrorProviderInfo, type SlateErrorResponse, type SlateErrorUpstreamInfo, type SlateGatewayEvent, type SlateLiveInvocationInfo, type SlateLogEntry, type SlateLogFields, type SlateLogListener, type SlateLogMessageInput, type SlateLogType, SlateLogger, type SlateProviderDocsReference, SlatePublicContext, SlatePublicTool, type SlatePublicToolInvocationHandler, type SlatePublicToolParameters, type SlateServiceErrorData, SlateSpecification, type SlateSpecificationCreateParameters, type SlateSpecificationParameters, SlateTool, type SlateToolInvocationHandler, type SlateToolParameters, SlateTrigger, SlateTriggerGroup, SlateTriggerGroupBuilder, type SlateTriggerGroupCreateParameters, type SlateTriggerGroupGatewayConnectHandler, type SlateTriggerGroupGatewayParameters, type SlateTriggerGroupGatewayReceiveHandler, type SlateTriggerGroupParameters, type SlateTriggerGroupPollHandler, type SlateTriggerGroupPollingParameters, type SlateTriggerGroupRoutingMatchersHandler, type SlateTriggerGroupWebhookAutoRegistrationParameters, type SlateTriggerGroupWebhookManualRegistrationParameters, type SlateTriggerGroupWebhookParameters, type SlateTriggerMappingHandler, type SlateTriggerMatchesHandler, type SlateTriggerParameters, type SlateTriggerRoutingMatcher, type SlateTypedDocsReference, type SlateWebhookHttpResponseInit, type SlateWebhookManualFinishHandler, type SlateWebhookManualSetupHandler, type SlateWebhookProcessHandler, type SlateWebhookRegisterHandler, type SlateWebhookSkipped, type SlateWebhookTarget, type SlateWebhookTargetListHandler, type SlateWebhookTargetOwnership, type SlateWebhookUnregisterHandler, type VerifyHmacSignatureOptions, adapterSpec, allOf, anyOf, auth, axios, buildApiServiceError, collectApiErrorDetails, config, createApiServiceError, createAuthenticatedAxios, createAxios, createBase64Attachment, createHmacSignature, createSlateError, createTextAttachment, createUrlAttachment, decodeApiErrorBody, extractApiErrorMessage, getApiErrorResponse, getApiErrorResponseWithBody, getApiErrorStatus, getBase64ByteLength, getCurrentContext, getFileUrlTool, getFileUrlToolInputSchema, getFileUrlToolOutputSchema, getGraphWebhookValidationResponse, getMetaWebhookVerificationResponse, getOAuthExpiresAtFromExpiresIn, getResponseHeaderValue, getServiceErrorData, graphWebhookHttp, inferSlateErrorFromAxios, isApiErrorRecord, isAxiosErrorLike, isServiceErrorData, isUrlEmbeddedCredential, looksLikeHtmlErrorBody, mapServiceErrorCode, mapServiceErrorToSlateErrorInput, mergeScopes, metaWebhookHttp, normalizeOAuthTokenResponse, pickDefined, publicTool, pushBoundedApiErrorDetail, readApiErrorText, redactUrlAttachmentSecrets, requestAxios, requestAxiosData, runWithContext, scopeClause, setIfDefined, skipWebhook, spec, statusLabelForApiError, tool, trigger, triggerGroup, truncateApiErrorMessage, uploadAttachmentDirect, validateScopes, verifyHmacSignature };
|
|
1195
|
+
export { API_ERROR_MAX_DETAILS, API_ERROR_MAX_MESSAGE_LENGTH, API_ERROR_TRUNCATED_PLACEHOLDER, AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX, type ApiErrorBuildHelpers, type ApiErrorDetailOptions, type ApiErrorResponse, type ApiErrorStatus, type ApiErrorTextOptions, type ApiServiceError, type AuthConfigSecretFilter, AuthConfigSecretRedactor, type BoundedApiErrorDetailOptions, type BuildApiServiceErrorOptions, type CreateHmacSignatureOptions, type DecodeApiErrorBodyOptions, GET_FILE_URL_TOOL_ID, type GetFileUrlHandler, type GetFileUrlToolInput, type GetFileUrlToolOutput, type NormalizeOAuthTokenResponseOptions, type OAuthExpiresAtOptions, type OAuthRefreshTokenFallbackMode, type OAuthTokenResponse, Slate, SlateAction, SlateActionBuilder, type SlateActionCreateParameters, type SlateActionDocsReference, type SlateActionParameters, type SlateActionParametersAny, type SlateActionParametersTool, type SlateActionParametersTrigger, type SlateActionScopeClause, type SlateActionScopeClauseInput, type SlateActionScopeValue, type SlateActionScopes, type SlateActionScopesInput, type SlateActionType, SlateAdapter, type SlateAdapterCapability, SlateAdapterSpec, type SlateAdapterSpecParameters, type SlateAddAttachmentContent, type SlateAddAttachmentInput, type SlateAttachment, type SlateAttachmentInlineContent, type SlateAttachmentUploadReferenceContent, type SlateAttachmentUrlContent, SlateAuth, type SlateAuthDocsReference, type SlateAuthType, type SlateAuthWithCustomData, type SlateAuthWithNone, type SlateAuthWithOauth, type SlateAuthWithServiceAccount, type SlateAuthWithToken, type SlateAuthenticatedAxiosDefaults, type SlateAxiosDefaults, type SlateAxiosErrorAdapter, type SlateAxiosErrorOptions, SlateConfig, type SlateConfigDocsReference, SlateContext, SlateDeclarationError, SlateDefaultPollingIntervalSeconds, type SlateDirectUploadInput, type SlateDocsReference, SlateError, type SlateErrorInput, type SlateErrorIssue, type SlateErrorKind, type SlateErrorProviderInfo, type SlateErrorResponse, type SlateErrorUpstreamInfo, type SlateGatewayEvent, type SlateLiveInvocationInfo, type SlateLogEntry, type SlateLogFields, type SlateLogListener, type SlateLogMessageInput, type SlateLogType, SlateLogger, type SlateProviderDocsReference, SlatePublicContext, SlatePublicTool, type SlatePublicToolInvocationHandler, type SlatePublicToolParameters, type SlateServiceErrorData, SlateSpecification, type SlateSpecificationCreateParameters, type SlateSpecificationParameters, SlateTool, SlateToolCategory, type SlateToolCategoryParameters, type SlateToolInvocationHandler, type SlateToolParameters, SlateTrigger, SlateTriggerGroup, SlateTriggerGroupBuilder, type SlateTriggerGroupCreateParameters, type SlateTriggerGroupGatewayConnectHandler, type SlateTriggerGroupGatewayParameters, type SlateTriggerGroupGatewayReceiveHandler, type SlateTriggerGroupParameters, type SlateTriggerGroupPollHandler, type SlateTriggerGroupPollingParameters, type SlateTriggerGroupRoutingMatchersHandler, type SlateTriggerGroupWebhookAutoRegistrationParameters, type SlateTriggerGroupWebhookManualRegistrationParameters, type SlateTriggerGroupWebhookParameters, type SlateTriggerMappingHandler, type SlateTriggerMatchesHandler, type SlateTriggerParameters, type SlateTriggerRoutingMatcher, type SlateTypedDocsReference, type SlateWebhookHttpResponseInit, type SlateWebhookManualFinishHandler, type SlateWebhookManualSetupHandler, type SlateWebhookProcessHandler, type SlateWebhookRegisterHandler, type SlateWebhookSkipped, type SlateWebhookTarget, type SlateWebhookTargetListHandler, type SlateWebhookTargetOwnership, type SlateWebhookUnregisterHandler, type VerifyHmacSignatureOptions, adapterSpec, allOf, anyOf, auth, axios, buildApiServiceError, collectApiErrorDetails, config, createApiServiceError, createAuthenticatedAxios, createAxios, createBase64Attachment, createHmacSignature, createSlateError, createTextAttachment, createUrlAttachment, decodeApiErrorBody, extractApiErrorMessage, getApiErrorResponse, getApiErrorResponseWithBody, getApiErrorStatus, getBase64ByteLength, getCurrentContext, getFileUrlTool, getFileUrlToolInputSchema, getFileUrlToolOutputSchema, getGraphWebhookValidationResponse, getMetaWebhookVerificationResponse, getOAuthExpiresAtFromExpiresIn, getResponseHeaderValue, getServiceErrorData, graphWebhookHttp, inferSlateErrorFromAxios, isApiErrorRecord, isAxiosErrorLike, isServiceErrorData, isUrlEmbeddedCredential, looksLikeHtmlErrorBody, mapServiceErrorCode, mapServiceErrorToSlateErrorInput, mergeScopes, metaWebhookHttp, normalizeOAuthTokenResponse, pickDefined, publicTool, pushBoundedApiErrorDetail, readApiErrorText, redactUrlAttachmentSecrets, requestAxios, requestAxiosData, runWithContext, scopeClause, setIfDefined, skipWebhook, spec, statusLabelForApiError, tool, toolCategory, trigger, triggerGroup, truncateApiErrorMessage, uploadAttachmentDirect, validateScopes, verifyHmacSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -857,6 +857,25 @@ declare let allOf: (...inputs: SlateActionScopesInput[]) => SlateActionScopes;
|
|
|
857
857
|
declare let mergeScopes: (...inputs: Array<SlateActionScopes | null | undefined | false>) => SlateActionScopes | undefined;
|
|
858
858
|
declare let validateScopes: (scopes: SlateActionScopes) => SlateActionScopes;
|
|
859
859
|
|
|
860
|
+
interface SlateToolCategoryParameters {
|
|
861
|
+
key: string;
|
|
862
|
+
name: string;
|
|
863
|
+
description?: string;
|
|
864
|
+
imageUrl?: string;
|
|
865
|
+
tools: SlateTool<any, any, any, any>[];
|
|
866
|
+
}
|
|
867
|
+
declare class SlateToolCategory {
|
|
868
|
+
private readonly _params;
|
|
869
|
+
private constructor();
|
|
870
|
+
static create(params: SlateToolCategoryParameters): SlateToolCategory;
|
|
871
|
+
get key(): string;
|
|
872
|
+
get name(): string;
|
|
873
|
+
get description(): string | undefined;
|
|
874
|
+
get imageUrl(): string | undefined;
|
|
875
|
+
get tools(): SlateTool<any, any, any, any>[];
|
|
876
|
+
}
|
|
877
|
+
declare let toolCategory: (params: SlateToolCategoryParameters) => SlateToolCategory;
|
|
878
|
+
|
|
860
879
|
interface SlateTriggerParameters<ConfigType extends {}, AuthType extends {}, InputType extends {}, OutputType extends {
|
|
861
880
|
type: string;
|
|
862
881
|
}> extends SlateActionParameters {
|
|
@@ -1123,6 +1142,8 @@ declare class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
1123
1142
|
private readonly _actions;
|
|
1124
1143
|
private readonly _adapters;
|
|
1125
1144
|
private readonly _triggerGroups;
|
|
1145
|
+
private readonly _toolCategories;
|
|
1146
|
+
private readonly _toolCategoryKeysByActionKey;
|
|
1126
1147
|
private constructor();
|
|
1127
1148
|
static create<ConfigType extends {}, AuthType extends {}>(params: {
|
|
1128
1149
|
spec: SlateSpecification<ConfigType, AuthType>;
|
|
@@ -1130,11 +1151,14 @@ declare class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
1130
1151
|
tools: SlateTool<ConfigType, AuthType, any, any>[];
|
|
1131
1152
|
adapters?: SlateAdapter<ConfigType, AuthType>[];
|
|
1132
1153
|
triggerGroups?: SlateTriggerGroup<ConfigType, AuthType>[];
|
|
1154
|
+
toolCategories?: SlateToolCategory[];
|
|
1133
1155
|
}): Slate<ConfigType, AuthType>;
|
|
1134
1156
|
get spec(): SlateSpecification<ConfigType, AuthType>;
|
|
1135
1157
|
get actions(): (SlateTrigger<ConfigType, AuthType, any, any> | SlateTool<ConfigType, AuthType, any, any>)[];
|
|
1136
1158
|
get adapters(): SlateAdapter<ConfigType, AuthType>[];
|
|
1137
1159
|
get triggerGroups(): SlateTriggerGroup<ConfigType, AuthType, Record<string, unknown>>[];
|
|
1160
|
+
get toolCategories(): SlateToolCategory[];
|
|
1161
|
+
getToolCategoryKeys(actionKey: string): string[];
|
|
1138
1162
|
}
|
|
1139
1163
|
|
|
1140
1164
|
declare const graphWebhookHttp: {
|
|
@@ -1168,4 +1192,4 @@ declare let skipWebhook: (reason: string, response?: Response | SlateWebhookHttp
|
|
|
1168
1192
|
response: Response | SlateWebhookHttpResponseInit;
|
|
1169
1193
|
};
|
|
1170
1194
|
|
|
1171
|
-
export { API_ERROR_MAX_DETAILS, API_ERROR_MAX_MESSAGE_LENGTH, API_ERROR_TRUNCATED_PLACEHOLDER, AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX, type ApiErrorBuildHelpers, type ApiErrorDetailOptions, type ApiErrorResponse, type ApiErrorStatus, type ApiErrorTextOptions, type ApiServiceError, type AuthConfigSecretFilter, AuthConfigSecretRedactor, type BoundedApiErrorDetailOptions, type BuildApiServiceErrorOptions, type CreateHmacSignatureOptions, type DecodeApiErrorBodyOptions, GET_FILE_URL_TOOL_ID, type GetFileUrlHandler, type GetFileUrlToolInput, type GetFileUrlToolOutput, type NormalizeOAuthTokenResponseOptions, type OAuthExpiresAtOptions, type OAuthRefreshTokenFallbackMode, type OAuthTokenResponse, Slate, SlateAction, SlateActionBuilder, type SlateActionCreateParameters, type SlateActionDocsReference, type SlateActionParameters, type SlateActionParametersAny, type SlateActionParametersTool, type SlateActionParametersTrigger, type SlateActionScopeClause, type SlateActionScopeClauseInput, type SlateActionScopeValue, type SlateActionScopes, type SlateActionScopesInput, type SlateActionType, SlateAdapter, type SlateAdapterCapability, SlateAdapterSpec, type SlateAdapterSpecParameters, type SlateAddAttachmentContent, type SlateAddAttachmentInput, type SlateAttachment, type SlateAttachmentInlineContent, type SlateAttachmentUploadReferenceContent, type SlateAttachmentUrlContent, SlateAuth, type SlateAuthDocsReference, type SlateAuthType, type SlateAuthWithCustomData, type SlateAuthWithNone, type SlateAuthWithOauth, type SlateAuthWithServiceAccount, type SlateAuthWithToken, type SlateAuthenticatedAxiosDefaults, type SlateAxiosDefaults, type SlateAxiosErrorAdapter, type SlateAxiosErrorOptions, SlateConfig, type SlateConfigDocsReference, SlateContext, SlateDeclarationError, SlateDefaultPollingIntervalSeconds, type SlateDirectUploadInput, type SlateDocsReference, SlateError, type SlateErrorInput, type SlateErrorIssue, type SlateErrorKind, type SlateErrorProviderInfo, type SlateErrorResponse, type SlateErrorUpstreamInfo, type SlateGatewayEvent, type SlateLiveInvocationInfo, type SlateLogEntry, type SlateLogFields, type SlateLogListener, type SlateLogMessageInput, type SlateLogType, SlateLogger, type SlateProviderDocsReference, SlatePublicContext, SlatePublicTool, type SlatePublicToolInvocationHandler, type SlatePublicToolParameters, type SlateServiceErrorData, SlateSpecification, type SlateSpecificationCreateParameters, type SlateSpecificationParameters, SlateTool, type SlateToolInvocationHandler, type SlateToolParameters, SlateTrigger, SlateTriggerGroup, SlateTriggerGroupBuilder, type SlateTriggerGroupCreateParameters, type SlateTriggerGroupGatewayConnectHandler, type SlateTriggerGroupGatewayParameters, type SlateTriggerGroupGatewayReceiveHandler, type SlateTriggerGroupParameters, type SlateTriggerGroupPollHandler, type SlateTriggerGroupPollingParameters, type SlateTriggerGroupRoutingMatchersHandler, type SlateTriggerGroupWebhookAutoRegistrationParameters, type SlateTriggerGroupWebhookManualRegistrationParameters, type SlateTriggerGroupWebhookParameters, type SlateTriggerMappingHandler, type SlateTriggerMatchesHandler, type SlateTriggerParameters, type SlateTriggerRoutingMatcher, type SlateTypedDocsReference, type SlateWebhookHttpResponseInit, type SlateWebhookManualFinishHandler, type SlateWebhookManualSetupHandler, type SlateWebhookProcessHandler, type SlateWebhookRegisterHandler, type SlateWebhookSkipped, type SlateWebhookTarget, type SlateWebhookTargetListHandler, type SlateWebhookTargetOwnership, type SlateWebhookUnregisterHandler, type VerifyHmacSignatureOptions, adapterSpec, allOf, anyOf, auth, axios, buildApiServiceError, collectApiErrorDetails, config, createApiServiceError, createAuthenticatedAxios, createAxios, createBase64Attachment, createHmacSignature, createSlateError, createTextAttachment, createUrlAttachment, decodeApiErrorBody, extractApiErrorMessage, getApiErrorResponse, getApiErrorResponseWithBody, getApiErrorStatus, getBase64ByteLength, getCurrentContext, getFileUrlTool, getFileUrlToolInputSchema, getFileUrlToolOutputSchema, getGraphWebhookValidationResponse, getMetaWebhookVerificationResponse, getOAuthExpiresAtFromExpiresIn, getResponseHeaderValue, getServiceErrorData, graphWebhookHttp, inferSlateErrorFromAxios, isApiErrorRecord, isAxiosErrorLike, isServiceErrorData, isUrlEmbeddedCredential, looksLikeHtmlErrorBody, mapServiceErrorCode, mapServiceErrorToSlateErrorInput, mergeScopes, metaWebhookHttp, normalizeOAuthTokenResponse, pickDefined, publicTool, pushBoundedApiErrorDetail, readApiErrorText, redactUrlAttachmentSecrets, requestAxios, requestAxiosData, runWithContext, scopeClause, setIfDefined, skipWebhook, spec, statusLabelForApiError, tool, trigger, triggerGroup, truncateApiErrorMessage, uploadAttachmentDirect, validateScopes, verifyHmacSignature };
|
|
1195
|
+
export { API_ERROR_MAX_DETAILS, API_ERROR_MAX_MESSAGE_LENGTH, API_ERROR_TRUNCATED_PLACEHOLDER, AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX, type ApiErrorBuildHelpers, type ApiErrorDetailOptions, type ApiErrorResponse, type ApiErrorStatus, type ApiErrorTextOptions, type ApiServiceError, type AuthConfigSecretFilter, AuthConfigSecretRedactor, type BoundedApiErrorDetailOptions, type BuildApiServiceErrorOptions, type CreateHmacSignatureOptions, type DecodeApiErrorBodyOptions, GET_FILE_URL_TOOL_ID, type GetFileUrlHandler, type GetFileUrlToolInput, type GetFileUrlToolOutput, type NormalizeOAuthTokenResponseOptions, type OAuthExpiresAtOptions, type OAuthRefreshTokenFallbackMode, type OAuthTokenResponse, Slate, SlateAction, SlateActionBuilder, type SlateActionCreateParameters, type SlateActionDocsReference, type SlateActionParameters, type SlateActionParametersAny, type SlateActionParametersTool, type SlateActionParametersTrigger, type SlateActionScopeClause, type SlateActionScopeClauseInput, type SlateActionScopeValue, type SlateActionScopes, type SlateActionScopesInput, type SlateActionType, SlateAdapter, type SlateAdapterCapability, SlateAdapterSpec, type SlateAdapterSpecParameters, type SlateAddAttachmentContent, type SlateAddAttachmentInput, type SlateAttachment, type SlateAttachmentInlineContent, type SlateAttachmentUploadReferenceContent, type SlateAttachmentUrlContent, SlateAuth, type SlateAuthDocsReference, type SlateAuthType, type SlateAuthWithCustomData, type SlateAuthWithNone, type SlateAuthWithOauth, type SlateAuthWithServiceAccount, type SlateAuthWithToken, type SlateAuthenticatedAxiosDefaults, type SlateAxiosDefaults, type SlateAxiosErrorAdapter, type SlateAxiosErrorOptions, SlateConfig, type SlateConfigDocsReference, SlateContext, SlateDeclarationError, SlateDefaultPollingIntervalSeconds, type SlateDirectUploadInput, type SlateDocsReference, SlateError, type SlateErrorInput, type SlateErrorIssue, type SlateErrorKind, type SlateErrorProviderInfo, type SlateErrorResponse, type SlateErrorUpstreamInfo, type SlateGatewayEvent, type SlateLiveInvocationInfo, type SlateLogEntry, type SlateLogFields, type SlateLogListener, type SlateLogMessageInput, type SlateLogType, SlateLogger, type SlateProviderDocsReference, SlatePublicContext, SlatePublicTool, type SlatePublicToolInvocationHandler, type SlatePublicToolParameters, type SlateServiceErrorData, SlateSpecification, type SlateSpecificationCreateParameters, type SlateSpecificationParameters, SlateTool, SlateToolCategory, type SlateToolCategoryParameters, type SlateToolInvocationHandler, type SlateToolParameters, SlateTrigger, SlateTriggerGroup, SlateTriggerGroupBuilder, type SlateTriggerGroupCreateParameters, type SlateTriggerGroupGatewayConnectHandler, type SlateTriggerGroupGatewayParameters, type SlateTriggerGroupGatewayReceiveHandler, type SlateTriggerGroupParameters, type SlateTriggerGroupPollHandler, type SlateTriggerGroupPollingParameters, type SlateTriggerGroupRoutingMatchersHandler, type SlateTriggerGroupWebhookAutoRegistrationParameters, type SlateTriggerGroupWebhookManualRegistrationParameters, type SlateTriggerGroupWebhookParameters, type SlateTriggerMappingHandler, type SlateTriggerMatchesHandler, type SlateTriggerParameters, type SlateTriggerRoutingMatcher, type SlateTypedDocsReference, type SlateWebhookHttpResponseInit, type SlateWebhookManualFinishHandler, type SlateWebhookManualSetupHandler, type SlateWebhookProcessHandler, type SlateWebhookRegisterHandler, type SlateWebhookSkipped, type SlateWebhookTarget, type SlateWebhookTargetListHandler, type SlateWebhookTargetOwnership, type SlateWebhookUnregisterHandler, type VerifyHmacSignatureOptions, adapterSpec, allOf, anyOf, auth, axios, buildApiServiceError, collectApiErrorDetails, config, createApiServiceError, createAuthenticatedAxios, createAxios, createBase64Attachment, createHmacSignature, createSlateError, createTextAttachment, createUrlAttachment, decodeApiErrorBody, extractApiErrorMessage, getApiErrorResponse, getApiErrorResponseWithBody, getApiErrorStatus, getBase64ByteLength, getCurrentContext, getFileUrlTool, getFileUrlToolInputSchema, getFileUrlToolOutputSchema, getGraphWebhookValidationResponse, getMetaWebhookVerificationResponse, getOAuthExpiresAtFromExpiresIn, getResponseHeaderValue, getServiceErrorData, graphWebhookHttp, inferSlateErrorFromAxios, isApiErrorRecord, isAxiosErrorLike, isServiceErrorData, isUrlEmbeddedCredential, looksLikeHtmlErrorBody, mapServiceErrorCode, mapServiceErrorToSlateErrorInput, mergeScopes, metaWebhookHttp, normalizeOAuthTokenResponse, pickDefined, publicTool, pushBoundedApiErrorDetail, readApiErrorText, redactUrlAttachmentSecrets, requestAxios, requestAxiosData, runWithContext, scopeClause, setIfDefined, skipWebhook, spec, statusLabelForApiError, tool, toolCategory, trigger, triggerGroup, truncateApiErrorMessage, uploadAttachmentDirect, validateScopes, verifyHmacSignature };
|
package/dist/index.module.js
CHANGED
|
@@ -2055,6 +2055,33 @@ var SlatePublicTool = class {
|
|
|
2055
2055
|
};
|
|
2056
2056
|
var publicTool = (spec2, params) => SlatePublicTool.create(spec2, params);
|
|
2057
2057
|
|
|
2058
|
+
// src/action/toolCategory.ts
|
|
2059
|
+
var SlateToolCategory = class _SlateToolCategory {
|
|
2060
|
+
constructor(_params) {
|
|
2061
|
+
this._params = _params;
|
|
2062
|
+
}
|
|
2063
|
+
_params;
|
|
2064
|
+
static create(params) {
|
|
2065
|
+
return new _SlateToolCategory(params);
|
|
2066
|
+
}
|
|
2067
|
+
get key() {
|
|
2068
|
+
return this._params.key;
|
|
2069
|
+
}
|
|
2070
|
+
get name() {
|
|
2071
|
+
return this._params.name;
|
|
2072
|
+
}
|
|
2073
|
+
get description() {
|
|
2074
|
+
return this._params.description;
|
|
2075
|
+
}
|
|
2076
|
+
get imageUrl() {
|
|
2077
|
+
return this._params.imageUrl;
|
|
2078
|
+
}
|
|
2079
|
+
get tools() {
|
|
2080
|
+
return this._params.tools;
|
|
2081
|
+
}
|
|
2082
|
+
};
|
|
2083
|
+
var toolCategory = (params) => SlateToolCategory.create(params);
|
|
2084
|
+
|
|
2058
2085
|
// src/action/trigger.ts
|
|
2059
2086
|
var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
2060
2087
|
#triggerGroup;
|
|
@@ -3078,16 +3105,20 @@ var setIfDefined = (target, key, value) => {
|
|
|
3078
3105
|
|
|
3079
3106
|
// src/specification/slate.ts
|
|
3080
3107
|
var Slate = class _Slate {
|
|
3081
|
-
constructor(_spec, _actions, _adapters, _triggerGroups) {
|
|
3108
|
+
constructor(_spec, _actions, _adapters, _triggerGroups, _toolCategories, _toolCategoryKeysByActionKey) {
|
|
3082
3109
|
this._spec = _spec;
|
|
3083
3110
|
this._actions = _actions;
|
|
3084
3111
|
this._adapters = _adapters;
|
|
3085
3112
|
this._triggerGroups = _triggerGroups;
|
|
3113
|
+
this._toolCategories = _toolCategories;
|
|
3114
|
+
this._toolCategoryKeysByActionKey = _toolCategoryKeysByActionKey;
|
|
3086
3115
|
}
|
|
3087
3116
|
_spec;
|
|
3088
3117
|
_actions;
|
|
3089
3118
|
_adapters;
|
|
3090
3119
|
_triggerGroups;
|
|
3120
|
+
_toolCategories;
|
|
3121
|
+
_toolCategoryKeysByActionKey;
|
|
3091
3122
|
static create(params) {
|
|
3092
3123
|
let adapters = params.adapters ?? [];
|
|
3093
3124
|
let actions = [...params.triggers, ...params.tools];
|
|
@@ -3131,7 +3162,16 @@ var Slate = class _Slate {
|
|
|
3131
3162
|
`Only one trigger group may use manual webhook registration, but found: ${manualWebhookTriggerGroups.map((group) => group.key).join(", ")}`
|
|
3132
3163
|
);
|
|
3133
3164
|
}
|
|
3134
|
-
|
|
3165
|
+
let toolCategories = params.toolCategories ?? [];
|
|
3166
|
+
let toolCategoryKeysByActionKey = resolveToolCategoryMembership(toolCategories, actions);
|
|
3167
|
+
return new _Slate(
|
|
3168
|
+
params.spec,
|
|
3169
|
+
actions,
|
|
3170
|
+
adapters,
|
|
3171
|
+
triggerGroups,
|
|
3172
|
+
toolCategories,
|
|
3173
|
+
toolCategoryKeysByActionKey
|
|
3174
|
+
);
|
|
3135
3175
|
}
|
|
3136
3176
|
get spec() {
|
|
3137
3177
|
return this._spec;
|
|
@@ -3145,6 +3185,79 @@ var Slate = class _Slate {
|
|
|
3145
3185
|
get triggerGroups() {
|
|
3146
3186
|
return this._triggerGroups ?? [];
|
|
3147
3187
|
}
|
|
3188
|
+
get toolCategories() {
|
|
3189
|
+
return this._toolCategories ?? [];
|
|
3190
|
+
}
|
|
3191
|
+
// Keys of the tool categories an action belongs to, in declared category order.
|
|
3192
|
+
getToolCategoryKeys(actionKey) {
|
|
3193
|
+
return [...this._toolCategoryKeysByActionKey?.get(actionKey) ?? []];
|
|
3194
|
+
}
|
|
3195
|
+
};
|
|
3196
|
+
var TOOL_CATEGORY_KEY_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
3197
|
+
var isHttpUrl = (value) => {
|
|
3198
|
+
try {
|
|
3199
|
+
let url = new URL(value);
|
|
3200
|
+
return url.protocol === "https:" || url.protocol === "http:";
|
|
3201
|
+
} catch {
|
|
3202
|
+
return false;
|
|
3203
|
+
}
|
|
3204
|
+
};
|
|
3205
|
+
var resolveToolCategoryMembership = (toolCategories, actions) => {
|
|
3206
|
+
let effectiveActions = /* @__PURE__ */ new Map();
|
|
3207
|
+
for (let action of actions) {
|
|
3208
|
+
if (!effectiveActions.has(action.key)) effectiveActions.set(action.key, action);
|
|
3209
|
+
}
|
|
3210
|
+
let registeredActions = new Set(actions);
|
|
3211
|
+
let membersByCategoryKey = /* @__PURE__ */ new Map();
|
|
3212
|
+
for (let category of toolCategories) {
|
|
3213
|
+
if (!TOOL_CATEGORY_KEY_PATTERN.test(category.key)) {
|
|
3214
|
+
throw new SlateDeclarationError(
|
|
3215
|
+
`Tool category key "${category.key}" must match ${TOOL_CATEGORY_KEY_PATTERN}`
|
|
3216
|
+
);
|
|
3217
|
+
}
|
|
3218
|
+
if (membersByCategoryKey.has(category.key)) {
|
|
3219
|
+
throw new SlateDeclarationError(
|
|
3220
|
+
`Tool category "${category.key}" is registered more than once`
|
|
3221
|
+
);
|
|
3222
|
+
}
|
|
3223
|
+
if (!category.name?.trim()) {
|
|
3224
|
+
throw new SlateDeclarationError(`Tool category "${category.key}" must have a name`);
|
|
3225
|
+
}
|
|
3226
|
+
if (category.imageUrl !== void 0 && !isHttpUrl(category.imageUrl)) {
|
|
3227
|
+
throw new SlateDeclarationError(
|
|
3228
|
+
`Tool category "${category.key}" imageUrl must be an absolute http(s) URL`
|
|
3229
|
+
);
|
|
3230
|
+
}
|
|
3231
|
+
if (!category.tools?.length) {
|
|
3232
|
+
throw new SlateDeclarationError(
|
|
3233
|
+
`Tool category "${category.key}" must list at least one tool`
|
|
3234
|
+
);
|
|
3235
|
+
}
|
|
3236
|
+
let members = /* @__PURE__ */ new Set();
|
|
3237
|
+
for (let tool2 of category.tools) {
|
|
3238
|
+
if (!registeredActions.has(tool2)) {
|
|
3239
|
+
throw new SlateDeclarationError(
|
|
3240
|
+
`Tool category "${category.key}" lists tool "${tool2.key}", which is not registered in this slate`
|
|
3241
|
+
);
|
|
3242
|
+
}
|
|
3243
|
+
if (tool2.type !== "tool") {
|
|
3244
|
+
throw new SlateDeclarationError(
|
|
3245
|
+
`Tool category "${category.key}" lists trigger "${tool2.key}", but only tools can belong to a tool category`
|
|
3246
|
+
);
|
|
3247
|
+
}
|
|
3248
|
+
if (effectiveActions.get(tool2.key) === tool2) members.add(tool2.key);
|
|
3249
|
+
}
|
|
3250
|
+
membersByCategoryKey.set(category.key, members);
|
|
3251
|
+
}
|
|
3252
|
+
let keysByActionKey = /* @__PURE__ */ new Map();
|
|
3253
|
+
for (let category of toolCategories) {
|
|
3254
|
+
for (let actionKey of membersByCategoryKey.get(category.key) ?? []) {
|
|
3255
|
+
let keys = keysByActionKey.get(actionKey) ?? [];
|
|
3256
|
+
keys.push(category.key);
|
|
3257
|
+
keysByActionKey.set(actionKey, keys);
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3260
|
+
return keysByActionKey;
|
|
3148
3261
|
};
|
|
3149
3262
|
|
|
3150
3263
|
// src/specification/specification.ts
|
|
@@ -3273,6 +3386,7 @@ export {
|
|
|
3273
3386
|
SlatePublicTool,
|
|
3274
3387
|
SlateSpecification,
|
|
3275
3388
|
SlateTool,
|
|
3389
|
+
SlateToolCategory,
|
|
3276
3390
|
SlateTrigger,
|
|
3277
3391
|
SlateTriggerGroup,
|
|
3278
3392
|
SlateTriggerGroupBuilder,
|
|
@@ -3333,6 +3447,7 @@ export {
|
|
|
3333
3447
|
spec,
|
|
3334
3448
|
statusLabelForApiError,
|
|
3335
3449
|
tool,
|
|
3450
|
+
toolCategory,
|
|
3336
3451
|
trigger,
|
|
3337
3452
|
triggerGroup,
|
|
3338
3453
|
truncateApiErrorMessage,
|
package/package.json
CHANGED
package/src/action/index.ts
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SlateTool } from './tool';
|
|
2
|
+
|
|
3
|
+
export interface SlateToolCategoryParameters {
|
|
4
|
+
key: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
imageUrl?: string;
|
|
8
|
+
tools: SlateTool<any, any, any, any>[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class SlateToolCategory {
|
|
12
|
+
private constructor(private readonly _params: SlateToolCategoryParameters) {}
|
|
13
|
+
|
|
14
|
+
static create(params: SlateToolCategoryParameters) {
|
|
15
|
+
return new SlateToolCategory(params);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get key() {
|
|
19
|
+
return this._params.key;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get name() {
|
|
23
|
+
return this._params.name;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get description() {
|
|
27
|
+
return this._params.description;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get imageUrl() {
|
|
31
|
+
return this._params.imageUrl;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get tools() {
|
|
35
|
+
return this._params.tools;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export let toolCategory = (params: SlateToolCategoryParameters) =>
|
|
40
|
+
SlateToolCategory.create(params);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { SlateTrigger, SlateTriggerGroup } from '../action';
|
|
3
|
+
import { SlateTool, SlateTrigger, SlateTriggerGroup, toolCategory } from '../action';
|
|
4
4
|
import { SlateAuth } from '../auth';
|
|
5
5
|
import { SlateConfig } from '../config';
|
|
6
6
|
import { Slate } from './slate';
|
|
@@ -117,3 +117,155 @@ describe('Slate.create', () => {
|
|
|
117
117
|
expect(slate.triggerGroups).toEqual([]);
|
|
118
118
|
});
|
|
119
119
|
});
|
|
120
|
+
|
|
121
|
+
let createTestTool = (spec: ReturnType<typeof createTestSpec>, key: string) =>
|
|
122
|
+
SlateTool.create(spec, { key, name: key })
|
|
123
|
+
.input(z.object({}))
|
|
124
|
+
.output(z.object({}))
|
|
125
|
+
.handleInvocation(async () => ({ output: {}, message: 'ok' }))
|
|
126
|
+
.build();
|
|
127
|
+
|
|
128
|
+
describe('Slate.create tool categories', () => {
|
|
129
|
+
it('resolves membership in declared category order', () => {
|
|
130
|
+
let spec = createTestSpec();
|
|
131
|
+
let records = createTestTool(spec, 'records');
|
|
132
|
+
let report = createTestTool(spec, 'report');
|
|
133
|
+
let other = createTestTool(spec, 'other');
|
|
134
|
+
|
|
135
|
+
let slate = Slate.create({
|
|
136
|
+
spec,
|
|
137
|
+
tools: [records, report, other],
|
|
138
|
+
triggers: [],
|
|
139
|
+
toolCategories: [
|
|
140
|
+
toolCategory({ key: 'crm', name: 'CRM', tools: [records, report] }),
|
|
141
|
+
toolCategory({ key: 'reporting', name: 'Reporting', tools: [report] })
|
|
142
|
+
]
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expect(slate.toolCategories.map(category => category.key)).toEqual(['crm', 'reporting']);
|
|
146
|
+
expect(slate.getToolCategoryKeys('records')).toEqual(['crm']);
|
|
147
|
+
expect(slate.getToolCategoryKeys('report')).toEqual(['crm', 'reporting']);
|
|
148
|
+
expect(slate.getToolCategoryKeys('other')).toEqual([]);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('ignores a shadowed duplicate tool listed in a category', () => {
|
|
152
|
+
let spec = createTestSpec();
|
|
153
|
+
let writer = createTestTool(spec, 'dup');
|
|
154
|
+
let reader = createTestTool(spec, 'dup');
|
|
155
|
+
|
|
156
|
+
let slate = Slate.create({
|
|
157
|
+
spec,
|
|
158
|
+
tools: [writer, reader],
|
|
159
|
+
triggers: [],
|
|
160
|
+
toolCategories: [toolCategory({ key: 'read', name: 'Read', tools: [reader] })]
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
expect(slate.getToolCategoryKeys('dup')).toEqual([]);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('returns a copy of the membership list', () => {
|
|
167
|
+
let spec = createTestSpec();
|
|
168
|
+
let tool = createTestTool(spec, 'a');
|
|
169
|
+
let slate = Slate.create({
|
|
170
|
+
spec,
|
|
171
|
+
tools: [tool],
|
|
172
|
+
triggers: [],
|
|
173
|
+
toolCategories: [toolCategory({ key: 'crm', name: 'CRM', tools: [tool] })]
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
slate.getToolCategoryKeys('a').push('mutated');
|
|
177
|
+
expect(slate.getToolCategoryKeys('a')).toEqual(['crm']);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('defaults to no categories', () => {
|
|
181
|
+
let spec = createTestSpec();
|
|
182
|
+
let slate = Slate.create({ spec, tools: [createTestTool(spec, 'a')], triggers: [] });
|
|
183
|
+
|
|
184
|
+
expect(slate.toolCategories).toEqual([]);
|
|
185
|
+
expect(slate.getToolCategoryKeys('a')).toEqual([]);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('rejects duplicate and malformed category keys', () => {
|
|
189
|
+
let spec = createTestSpec();
|
|
190
|
+
let tool = createTestTool(spec, 'a');
|
|
191
|
+
|
|
192
|
+
expect(() =>
|
|
193
|
+
Slate.create({
|
|
194
|
+
spec,
|
|
195
|
+
tools: [tool],
|
|
196
|
+
triggers: [],
|
|
197
|
+
toolCategories: [
|
|
198
|
+
toolCategory({ key: 'crm', name: 'CRM', tools: [tool] }),
|
|
199
|
+
toolCategory({ key: 'crm', name: 'CRM again', tools: [tool] })
|
|
200
|
+
]
|
|
201
|
+
})
|
|
202
|
+
).toThrow('Tool category "crm" is registered more than once');
|
|
203
|
+
|
|
204
|
+
expect(() =>
|
|
205
|
+
Slate.create({
|
|
206
|
+
spec,
|
|
207
|
+
tools: [tool],
|
|
208
|
+
triggers: [],
|
|
209
|
+
toolCategories: [toolCategory({ key: 'Zoho CRM', name: 'CRM', tools: [tool] })]
|
|
210
|
+
})
|
|
211
|
+
).toThrow('Tool category key "Zoho CRM" must match');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('accepts http(s) category images and rejects anything else', () => {
|
|
215
|
+
let spec = createTestSpec();
|
|
216
|
+
let tool = createTestTool(spec, 'a');
|
|
217
|
+
let slate = Slate.create({
|
|
218
|
+
spec,
|
|
219
|
+
tools: [tool],
|
|
220
|
+
triggers: [],
|
|
221
|
+
toolCategories: [
|
|
222
|
+
toolCategory({
|
|
223
|
+
key: 'crm',
|
|
224
|
+
name: 'CRM',
|
|
225
|
+
imageUrl: 'https://cdn.test/crm.svg',
|
|
226
|
+
tools: [tool]
|
|
227
|
+
})
|
|
228
|
+
]
|
|
229
|
+
});
|
|
230
|
+
expect(slate.toolCategories[0]?.imageUrl).toBe('https://cdn.test/crm.svg');
|
|
231
|
+
|
|
232
|
+
expect(() =>
|
|
233
|
+
Slate.create({
|
|
234
|
+
spec,
|
|
235
|
+
tools: [tool],
|
|
236
|
+
triggers: [],
|
|
237
|
+
toolCategories: [
|
|
238
|
+
toolCategory({ key: 'crm', name: 'CRM', imageUrl: 'crm.svg', tools: [tool] })
|
|
239
|
+
]
|
|
240
|
+
})
|
|
241
|
+
).toThrow('Tool category "crm" imageUrl must be an absolute http(s) URL');
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('rejects a category without tools', () => {
|
|
245
|
+
let spec = createTestSpec();
|
|
246
|
+
|
|
247
|
+
expect(() =>
|
|
248
|
+
Slate.create({
|
|
249
|
+
spec,
|
|
250
|
+
tools: [createTestTool(spec, 'a')],
|
|
251
|
+
triggers: [],
|
|
252
|
+
toolCategories: [toolCategory({ key: 'crm', name: 'CRM', tools: [] })]
|
|
253
|
+
})
|
|
254
|
+
).toThrow('Tool category "crm" must list at least one tool');
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('rejects unregistered member tools', () => {
|
|
258
|
+
let spec = createTestSpec();
|
|
259
|
+
|
|
260
|
+
expect(() =>
|
|
261
|
+
Slate.create({
|
|
262
|
+
spec,
|
|
263
|
+
tools: [],
|
|
264
|
+
triggers: [],
|
|
265
|
+
toolCategories: [
|
|
266
|
+
toolCategory({ key: 'crm', name: 'CRM', tools: [createTestTool(spec, 'stray')] })
|
|
267
|
+
]
|
|
268
|
+
})
|
|
269
|
+
).toThrow('Tool category "crm" lists tool "stray", which is not registered in this slate');
|
|
270
|
+
});
|
|
271
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SlateTool, SlateTrigger, SlateTriggerGroup } from '../action';
|
|
1
|
+
import type { SlateTool, SlateToolCategory, SlateTrigger, SlateTriggerGroup } from '../action';
|
|
2
2
|
import type { SlateAdapter } from '../adapter';
|
|
3
3
|
import { SlateDeclarationError } from '../error';
|
|
4
4
|
import type { SlateSpecification } from './specification';
|
|
@@ -11,7 +11,9 @@ export class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
11
11
|
| SlateTool<ConfigType, AuthType, any, any>
|
|
12
12
|
)[],
|
|
13
13
|
private readonly _adapters: SlateAdapter<ConfigType, AuthType>[],
|
|
14
|
-
private readonly _triggerGroups: SlateTriggerGroup<ConfigType, AuthType>[]
|
|
14
|
+
private readonly _triggerGroups: SlateTriggerGroup<ConfigType, AuthType>[],
|
|
15
|
+
private readonly _toolCategories: SlateToolCategory[],
|
|
16
|
+
private readonly _toolCategoryKeysByActionKey: Map<string, string[]>
|
|
15
17
|
) {}
|
|
16
18
|
|
|
17
19
|
static create<ConfigType extends {}, AuthType extends {}>(params: {
|
|
@@ -20,6 +22,7 @@ export class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
20
22
|
tools: SlateTool<ConfigType, AuthType, any, any>[];
|
|
21
23
|
adapters?: SlateAdapter<ConfigType, AuthType>[];
|
|
22
24
|
triggerGroups?: SlateTriggerGroup<ConfigType, AuthType>[];
|
|
25
|
+
toolCategories?: SlateToolCategory[];
|
|
23
26
|
}) {
|
|
24
27
|
let adapters = params.adapters ?? [];
|
|
25
28
|
let actions = [...params.triggers, ...params.tools];
|
|
@@ -71,7 +74,17 @@ export class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
71
74
|
);
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
let toolCategories = params.toolCategories ?? [];
|
|
78
|
+
let toolCategoryKeysByActionKey = resolveToolCategoryMembership(toolCategories, actions);
|
|
79
|
+
|
|
80
|
+
return new Slate(
|
|
81
|
+
params.spec,
|
|
82
|
+
actions,
|
|
83
|
+
adapters,
|
|
84
|
+
triggerGroups,
|
|
85
|
+
toolCategories,
|
|
86
|
+
toolCategoryKeysByActionKey
|
|
87
|
+
);
|
|
75
88
|
}
|
|
76
89
|
|
|
77
90
|
get spec() {
|
|
@@ -89,4 +102,93 @@ export class Slate<ConfigType extends {}, AuthType extends {}> {
|
|
|
89
102
|
get triggerGroups() {
|
|
90
103
|
return this._triggerGroups ?? [];
|
|
91
104
|
}
|
|
105
|
+
|
|
106
|
+
get toolCategories() {
|
|
107
|
+
return this._toolCategories ?? [];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Keys of the tool categories an action belongs to, in declared category order.
|
|
111
|
+
getToolCategoryKeys(actionKey: string) {
|
|
112
|
+
return [...(this._toolCategoryKeysByActionKey?.get(actionKey) ?? [])];
|
|
113
|
+
}
|
|
92
114
|
}
|
|
115
|
+
|
|
116
|
+
let TOOL_CATEGORY_KEY_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
117
|
+
|
|
118
|
+
let isHttpUrl = (value: string) => {
|
|
119
|
+
try {
|
|
120
|
+
let url = new URL(value);
|
|
121
|
+
return url.protocol === 'https:' || url.protocol === 'http:';
|
|
122
|
+
} catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
type SlateActionAny = SlateTool<any, any, any, any> | SlateTrigger<any, any, any, any>;
|
|
128
|
+
|
|
129
|
+
let resolveToolCategoryMembership = (
|
|
130
|
+
toolCategories: SlateToolCategory[],
|
|
131
|
+
actions: SlateActionAny[]
|
|
132
|
+
) => {
|
|
133
|
+
// Actions resolve by key and the first registered one wins, so a shadowed duplicate must
|
|
134
|
+
// not lend its categories to the action that actually runs.
|
|
135
|
+
let effectiveActions = new Map<string, SlateActionAny>();
|
|
136
|
+
for (let action of actions) {
|
|
137
|
+
if (!effectiveActions.has(action.key)) effectiveActions.set(action.key, action);
|
|
138
|
+
}
|
|
139
|
+
let registeredActions = new Set(actions);
|
|
140
|
+
let membersByCategoryKey = new Map<string, Set<string>>();
|
|
141
|
+
|
|
142
|
+
for (let category of toolCategories) {
|
|
143
|
+
if (!TOOL_CATEGORY_KEY_PATTERN.test(category.key)) {
|
|
144
|
+
throw new SlateDeclarationError(
|
|
145
|
+
`Tool category key "${category.key}" must match ${TOOL_CATEGORY_KEY_PATTERN}`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
if (membersByCategoryKey.has(category.key)) {
|
|
149
|
+
throw new SlateDeclarationError(
|
|
150
|
+
`Tool category "${category.key}" is registered more than once`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
if (!category.name?.trim()) {
|
|
154
|
+
throw new SlateDeclarationError(`Tool category "${category.key}" must have a name`);
|
|
155
|
+
}
|
|
156
|
+
if (category.imageUrl !== undefined && !isHttpUrl(category.imageUrl)) {
|
|
157
|
+
throw new SlateDeclarationError(
|
|
158
|
+
`Tool category "${category.key}" imageUrl must be an absolute http(s) URL`
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
if (!category.tools?.length) {
|
|
162
|
+
throw new SlateDeclarationError(
|
|
163
|
+
`Tool category "${category.key}" must list at least one tool`
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let members = new Set<string>();
|
|
168
|
+
for (let tool of category.tools) {
|
|
169
|
+
if (!registeredActions.has(tool)) {
|
|
170
|
+
throw new SlateDeclarationError(
|
|
171
|
+
`Tool category "${category.key}" lists tool "${tool.key}", which is not registered in this slate`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
if (tool.type !== 'tool') {
|
|
175
|
+
throw new SlateDeclarationError(
|
|
176
|
+
`Tool category "${category.key}" lists trigger "${tool.key}", but only tools can belong to a tool category`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
if (effectiveActions.get(tool.key) === tool) members.add(tool.key);
|
|
180
|
+
}
|
|
181
|
+
membersByCategoryKey.set(category.key, members);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
let keysByActionKey = new Map<string, string[]>();
|
|
185
|
+
for (let category of toolCategories) {
|
|
186
|
+
for (let actionKey of membersByCategoryKey.get(category.key) ?? []) {
|
|
187
|
+
let keys = keysByActionKey.get(actionKey) ?? [];
|
|
188
|
+
keys.push(category.key);
|
|
189
|
+
keysByActionKey.set(actionKey, keys);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return keysByActionKey;
|
|
194
|
+
};
|