@slates/provider 1.0.0-rc.17 → 1.0.0-rc.18
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 +244 -17
- package/dist/index.d.cts +108 -29
- package/dist/index.d.ts +108 -29
- package/dist/index.module.js +237 -17
- package/package.json +2 -2
- package/src/action/action.ts +19 -1
- package/src/action/builder.test.ts +136 -0
- package/src/action/builder.ts +68 -11
- package/src/action/index.ts +2 -1
- package/src/action/publicTool.ts +36 -0
- package/src/action/tool.ts +15 -3
- package/src/adapter/adapter.ts +38 -0
- package/src/adapter/index.test.ts +322 -0
- package/src/adapter/index.ts +2 -0
- package/src/adapter/spec.ts +154 -0
- package/src/axios/trace.ts +3 -3
- package/src/context/context.ts +31 -16
- package/src/context/hook.ts +5 -10
- package/src/index.ts +1 -0
- package/src/specification/slate.ts +38 -2
package/dist/index.module.js
CHANGED
|
@@ -54,6 +54,12 @@ var SlateAction = class {
|
|
|
54
54
|
get docs() {
|
|
55
55
|
return this._params.docs;
|
|
56
56
|
}
|
|
57
|
+
get adapter() {
|
|
58
|
+
return this._params.adapter ?? null;
|
|
59
|
+
}
|
|
60
|
+
get isPublic() {
|
|
61
|
+
return this._params.isPublic === true;
|
|
62
|
+
}
|
|
57
63
|
};
|
|
58
64
|
|
|
59
65
|
// src/error/api.ts
|
|
@@ -798,11 +804,12 @@ var isScopes = (value) => typeof value === "object" && value !== null && "AND" i
|
|
|
798
804
|
|
|
799
805
|
// src/action/builder.ts
|
|
800
806
|
var SlateActionBuilder = class {
|
|
801
|
-
constructor(type, spec2, params, factory) {
|
|
807
|
+
constructor(type, spec2, params, factory, isPublicTool = false) {
|
|
802
808
|
this.type = type;
|
|
803
809
|
this.spec = spec2;
|
|
804
810
|
this.params = params;
|
|
805
811
|
this.factory = factory;
|
|
812
|
+
this.isPublicTool = isPublicTool;
|
|
806
813
|
this.#configSchema = spec2.configSchema;
|
|
807
814
|
this.#authSchema = spec2.authSchema;
|
|
808
815
|
}
|
|
@@ -810,6 +817,7 @@ var SlateActionBuilder = class {
|
|
|
810
817
|
spec;
|
|
811
818
|
params;
|
|
812
819
|
factory;
|
|
820
|
+
isPublicTool;
|
|
813
821
|
#configSchema;
|
|
814
822
|
#authSchema;
|
|
815
823
|
#inputSchema = null;
|
|
@@ -818,20 +826,34 @@ var SlateActionBuilder = class {
|
|
|
818
826
|
#authMethods;
|
|
819
827
|
#toolParams = null;
|
|
820
828
|
#triggerParams = null;
|
|
829
|
+
#interfaceLocked = false;
|
|
821
830
|
input(schema) {
|
|
831
|
+
if (this.#interfaceLocked) {
|
|
832
|
+
throw new SlateDeclarationError("Adapter contract input schema cannot be changed");
|
|
833
|
+
}
|
|
822
834
|
this.#inputSchema = schema;
|
|
823
835
|
return this;
|
|
824
836
|
}
|
|
825
837
|
output(schema) {
|
|
838
|
+
if (this.#interfaceLocked) {
|
|
839
|
+
throw new SlateDeclarationError("Adapter contract output schema cannot be changed");
|
|
840
|
+
}
|
|
826
841
|
this.#outputSchema = schema;
|
|
827
842
|
return this;
|
|
828
843
|
}
|
|
844
|
+
lockInterface() {
|
|
845
|
+
this.#interfaceLocked = true;
|
|
846
|
+
return this;
|
|
847
|
+
}
|
|
829
848
|
scopes(scopes) {
|
|
830
849
|
validateScopes(scopes);
|
|
831
850
|
this.#scopes = scopes;
|
|
832
851
|
return this;
|
|
833
852
|
}
|
|
834
853
|
authMethods(authMethods) {
|
|
854
|
+
if (this.isPublicTool) {
|
|
855
|
+
throw new SlateDeclarationError("Public tools cannot require authentication methods");
|
|
856
|
+
}
|
|
835
857
|
this.#authMethods = this.validateAuthMethods(authMethods);
|
|
836
858
|
return this;
|
|
837
859
|
}
|
|
@@ -887,6 +909,9 @@ var SlateActionBuilder = class {
|
|
|
887
909
|
validateScopes(scopes);
|
|
888
910
|
}
|
|
889
911
|
let authMethods = this.validateAuthMethods(this.#authMethods ?? this.params.authMethods);
|
|
912
|
+
if (this.isPublicTool && authMethods) {
|
|
913
|
+
throw new SlateDeclarationError("Public tools cannot require authentication methods");
|
|
914
|
+
}
|
|
890
915
|
if (!this.#inputSchema) {
|
|
891
916
|
throw new SlateDeclarationError("Input schema is not defined");
|
|
892
917
|
}
|
|
@@ -903,6 +928,7 @@ var SlateActionBuilder = class {
|
|
|
903
928
|
...this.params,
|
|
904
929
|
scopes,
|
|
905
930
|
authMethods,
|
|
931
|
+
isPublic: this.isPublicTool === true,
|
|
906
932
|
configSchema: this.#configSchema,
|
|
907
933
|
authSchema: this.#authSchema,
|
|
908
934
|
inputSchema: this.#inputSchema,
|
|
@@ -922,16 +948,40 @@ var SlateTool = class _SlateTool extends SlateAction {
|
|
|
922
948
|
}
|
|
923
949
|
static create(spec2, params) {
|
|
924
950
|
return new SlateActionBuilder("tool", spec2, params, (params2) => {
|
|
925
|
-
|
|
926
|
-
return new _SlateTool(spec2, params2.inputSchema, params2.outputSchema, params2);
|
|
951
|
+
return _SlateTool.fromCreateParameters(spec2, params2);
|
|
927
952
|
});
|
|
928
953
|
}
|
|
954
|
+
static fromCreateParameters(spec2, params) {
|
|
955
|
+
if (params.type !== "tool") throw new Error("Invalid action type for tool");
|
|
956
|
+
return new _SlateTool(spec2, params.inputSchema, params.outputSchema, params);
|
|
957
|
+
}
|
|
929
958
|
get handleInvocation() {
|
|
930
959
|
return this.#handleInvocation;
|
|
931
960
|
}
|
|
932
961
|
};
|
|
933
962
|
var tool = (spec2, params) => SlateTool.create(spec2, params);
|
|
934
963
|
|
|
964
|
+
// src/action/publicTool.ts
|
|
965
|
+
var SlatePublicTool = class {
|
|
966
|
+
constructor() {
|
|
967
|
+
}
|
|
968
|
+
static create(spec2, params) {
|
|
969
|
+
return new SlateActionBuilder(
|
|
970
|
+
"tool",
|
|
971
|
+
spec2,
|
|
972
|
+
params,
|
|
973
|
+
(params2) => {
|
|
974
|
+
return SlateTool.fromCreateParameters(spec2, {
|
|
975
|
+
...params2,
|
|
976
|
+
isPublic: true
|
|
977
|
+
});
|
|
978
|
+
},
|
|
979
|
+
true
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
};
|
|
983
|
+
var publicTool = (spec2, params) => SlatePublicTool.create(spec2, params);
|
|
984
|
+
|
|
935
985
|
// src/action/trigger.ts
|
|
936
986
|
var SlateDefaultPollingIntervalSeconds = 60 * 10;
|
|
937
987
|
var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
@@ -1014,6 +1064,135 @@ var createTextAttachment = (content, mimeType) => ({
|
|
|
1014
1064
|
}
|
|
1015
1065
|
});
|
|
1016
1066
|
|
|
1067
|
+
// src/adapter/adapter.ts
|
|
1068
|
+
var SlateAdapter = class {
|
|
1069
|
+
constructor(_spec, _tools, _triggers) {
|
|
1070
|
+
this._spec = _spec;
|
|
1071
|
+
this._tools = _tools;
|
|
1072
|
+
this._triggers = _triggers;
|
|
1073
|
+
}
|
|
1074
|
+
_spec;
|
|
1075
|
+
_tools;
|
|
1076
|
+
_triggers;
|
|
1077
|
+
get spec() {
|
|
1078
|
+
return this._spec;
|
|
1079
|
+
}
|
|
1080
|
+
get id() {
|
|
1081
|
+
return this._spec.id;
|
|
1082
|
+
}
|
|
1083
|
+
get name() {
|
|
1084
|
+
return this._spec.name;
|
|
1085
|
+
}
|
|
1086
|
+
get capabilities() {
|
|
1087
|
+
return this._spec.capabilities;
|
|
1088
|
+
}
|
|
1089
|
+
get tools() {
|
|
1090
|
+
return this._tools;
|
|
1091
|
+
}
|
|
1092
|
+
get triggers() {
|
|
1093
|
+
return this._triggers;
|
|
1094
|
+
}
|
|
1095
|
+
get actions() {
|
|
1096
|
+
return [...this._triggers, ...this._tools];
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
|
|
1100
|
+
// src/adapter/spec.ts
|
|
1101
|
+
var SlateAdapterSpec = class _SlateAdapterSpec {
|
|
1102
|
+
constructor(_params) {
|
|
1103
|
+
this._params = _params;
|
|
1104
|
+
}
|
|
1105
|
+
_params;
|
|
1106
|
+
static create(params) {
|
|
1107
|
+
let id = params.id?.trim();
|
|
1108
|
+
let name = params.name?.trim();
|
|
1109
|
+
if (!id) {
|
|
1110
|
+
throw new SlateDeclarationError("Adapter id must be a non-empty string");
|
|
1111
|
+
}
|
|
1112
|
+
if (!name) {
|
|
1113
|
+
throw new SlateDeclarationError("Adapter name must be a non-empty string");
|
|
1114
|
+
}
|
|
1115
|
+
return new _SlateAdapterSpec({
|
|
1116
|
+
id,
|
|
1117
|
+
name,
|
|
1118
|
+
capabilities: validateCapabilities(params.capabilities ?? [])
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
get id() {
|
|
1122
|
+
return this._params.id;
|
|
1123
|
+
}
|
|
1124
|
+
get name() {
|
|
1125
|
+
return this._params.name;
|
|
1126
|
+
}
|
|
1127
|
+
get capabilities() {
|
|
1128
|
+
return this._params.capabilities;
|
|
1129
|
+
}
|
|
1130
|
+
get parameters() {
|
|
1131
|
+
return this._params;
|
|
1132
|
+
}
|
|
1133
|
+
tool(spec2, params) {
|
|
1134
|
+
return SlateTool.create(spec2, this.linkAction(params));
|
|
1135
|
+
}
|
|
1136
|
+
publicTool(spec2, params) {
|
|
1137
|
+
return SlatePublicTool.create(spec2, this.linkAction(params));
|
|
1138
|
+
}
|
|
1139
|
+
trigger(spec2, params) {
|
|
1140
|
+
return SlateTrigger.create(spec2, this.linkAction(params));
|
|
1141
|
+
}
|
|
1142
|
+
register(params) {
|
|
1143
|
+
let actions = [...params.tools, ...params.triggers];
|
|
1144
|
+
let seenKeys = /* @__PURE__ */ new Set();
|
|
1145
|
+
for (let action of actions) {
|
|
1146
|
+
if (action.adapter && action.adapter !== this.id) {
|
|
1147
|
+
throw new SlateDeclarationError(
|
|
1148
|
+
`Action "${action.key}" is linked to adapter "${action.adapter}", not "${this.id}"`
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
if (!action.adapter) {
|
|
1152
|
+
throw new SlateDeclarationError(
|
|
1153
|
+
`Action "${action.key}" must be created with this adapter's tool(), publicTool(), or trigger() helpers`
|
|
1154
|
+
);
|
|
1155
|
+
}
|
|
1156
|
+
if (seenKeys.has(action.key)) {
|
|
1157
|
+
throw new SlateDeclarationError(
|
|
1158
|
+
`Adapter "${this.id}" already has an action with key "${action.key}"`
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
seenKeys.add(action.key);
|
|
1162
|
+
}
|
|
1163
|
+
return new SlateAdapter(this, params.tools, params.triggers);
|
|
1164
|
+
}
|
|
1165
|
+
linkAction(params) {
|
|
1166
|
+
if (params.adapter != null && params.adapter !== this.id) {
|
|
1167
|
+
throw new SlateDeclarationError(
|
|
1168
|
+
`Action "${params.key}" cannot be linked to adapter "${this.id}" because it is already linked to "${params.adapter}"`
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
return {
|
|
1172
|
+
...params,
|
|
1173
|
+
adapter: this.id
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
var adapterSpec = (params) => SlateAdapterSpec.create(params);
|
|
1178
|
+
var validateCapabilities = (capabilities) => {
|
|
1179
|
+
let seenIds = /* @__PURE__ */ new Set();
|
|
1180
|
+
return capabilities.map((capability) => {
|
|
1181
|
+
let id = capability.id?.trim();
|
|
1182
|
+
if (!id) {
|
|
1183
|
+
throw new SlateDeclarationError("Adapter capability ids must be non-empty strings");
|
|
1184
|
+
}
|
|
1185
|
+
if (seenIds.has(id)) {
|
|
1186
|
+
throw new SlateDeclarationError(`Adapter capability "${id}" is defined more than once`);
|
|
1187
|
+
}
|
|
1188
|
+
seenIds.add(id);
|
|
1189
|
+
return {
|
|
1190
|
+
id,
|
|
1191
|
+
value: capability.value
|
|
1192
|
+
};
|
|
1193
|
+
});
|
|
1194
|
+
};
|
|
1195
|
+
|
|
1017
1196
|
// src/auth/auth.ts
|
|
1018
1197
|
var SlateAuth = class _SlateAuth {
|
|
1019
1198
|
#outputSchema = null;
|
|
@@ -1813,26 +1992,19 @@ var SlateConfig = class _SlateConfig {
|
|
|
1813
1992
|
var config = (schema) => SlateConfig.create(schema);
|
|
1814
1993
|
|
|
1815
1994
|
// src/context/context.ts
|
|
1816
|
-
var
|
|
1817
|
-
constructor(
|
|
1995
|
+
var SlatePublicContext = class {
|
|
1996
|
+
constructor(input, spec2, logger) {
|
|
1818
1997
|
this.spec = spec2;
|
|
1819
1998
|
this.logger = logger;
|
|
1820
|
-
this.#config = config2;
|
|
1821
1999
|
this.#input = input;
|
|
1822
|
-
this.#auth = auth2;
|
|
1823
2000
|
}
|
|
1824
2001
|
spec;
|
|
1825
2002
|
logger;
|
|
1826
|
-
#config;
|
|
1827
2003
|
#input;
|
|
1828
|
-
#auth;
|
|
1829
2004
|
#httpTraces = [];
|
|
1830
2005
|
get specification() {
|
|
1831
2006
|
return this.spec;
|
|
1832
2007
|
}
|
|
1833
|
-
get config() {
|
|
1834
|
-
return Object.freeze(this.#config);
|
|
1835
|
-
}
|
|
1836
2008
|
get input() {
|
|
1837
2009
|
return Object.freeze(this.#input);
|
|
1838
2010
|
}
|
|
@@ -1850,9 +2022,6 @@ var SlateContext = class {
|
|
|
1850
2022
|
this.#input.registrationDetails
|
|
1851
2023
|
);
|
|
1852
2024
|
}
|
|
1853
|
-
get auth() {
|
|
1854
|
-
return Object.freeze(this.#auth);
|
|
1855
|
-
}
|
|
1856
2025
|
recordHttpTrace(trace) {
|
|
1857
2026
|
this.#httpTraces.push(trace);
|
|
1858
2027
|
}
|
|
@@ -1887,6 +2056,21 @@ var SlateContext = class {
|
|
|
1887
2056
|
this.logger.progress(message);
|
|
1888
2057
|
}
|
|
1889
2058
|
};
|
|
2059
|
+
var SlateContext = class extends SlatePublicContext {
|
|
2060
|
+
#config;
|
|
2061
|
+
#auth;
|
|
2062
|
+
constructor(config2, input, auth2, spec2, logger) {
|
|
2063
|
+
super(input, spec2, logger);
|
|
2064
|
+
this.#config = config2;
|
|
2065
|
+
this.#auth = auth2;
|
|
2066
|
+
}
|
|
2067
|
+
get config() {
|
|
2068
|
+
return Object.freeze(this.#config);
|
|
2069
|
+
}
|
|
2070
|
+
get auth() {
|
|
2071
|
+
return Object.freeze(this.#auth);
|
|
2072
|
+
}
|
|
2073
|
+
};
|
|
1890
2074
|
|
|
1891
2075
|
// src/crypto/hmac.ts
|
|
1892
2076
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
@@ -2035,14 +2219,40 @@ var setIfDefined = (target, key, value) => {
|
|
|
2035
2219
|
|
|
2036
2220
|
// src/specification/slate.ts
|
|
2037
2221
|
var Slate = class _Slate {
|
|
2038
|
-
constructor(_spec, _actions) {
|
|
2222
|
+
constructor(_spec, _actions, _adapters) {
|
|
2039
2223
|
this._spec = _spec;
|
|
2040
2224
|
this._actions = _actions;
|
|
2225
|
+
this._adapters = _adapters;
|
|
2041
2226
|
}
|
|
2042
2227
|
_spec;
|
|
2043
2228
|
_actions;
|
|
2229
|
+
_adapters;
|
|
2044
2230
|
static create(params) {
|
|
2045
|
-
|
|
2231
|
+
let adapters = params.adapters ?? [];
|
|
2232
|
+
let actions = [...params.triggers, ...params.tools];
|
|
2233
|
+
let seenAdapterIds = /* @__PURE__ */ new Set();
|
|
2234
|
+
let seenActionKeys = new Map(actions.map((action) => [action.key, action]));
|
|
2235
|
+
for (let adapter of adapters) {
|
|
2236
|
+
if (seenAdapterIds.has(adapter.id)) {
|
|
2237
|
+
throw new SlateDeclarationError(
|
|
2238
|
+
`Adapter "${adapter.id}" is registered more than once`
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2241
|
+
seenAdapterIds.add(adapter.id);
|
|
2242
|
+
for (let action of adapter.actions) {
|
|
2243
|
+
let existing = seenActionKeys.get(action.key);
|
|
2244
|
+
if (existing && existing !== action) {
|
|
2245
|
+
throw new SlateDeclarationError(
|
|
2246
|
+
`Adapter "${adapter.id}" action "${action.key}" conflicts with another action`
|
|
2247
|
+
);
|
|
2248
|
+
}
|
|
2249
|
+
if (!existing) {
|
|
2250
|
+
actions.push(action);
|
|
2251
|
+
seenActionKeys.set(action.key, action);
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
return new _Slate(params.spec, actions, adapters);
|
|
2046
2256
|
}
|
|
2047
2257
|
get spec() {
|
|
2048
2258
|
return this._spec;
|
|
@@ -2050,6 +2260,9 @@ var Slate = class _Slate {
|
|
|
2050
2260
|
get actions() {
|
|
2051
2261
|
return this._actions;
|
|
2052
2262
|
}
|
|
2263
|
+
get adapters() {
|
|
2264
|
+
return this._adapters;
|
|
2265
|
+
}
|
|
2053
2266
|
};
|
|
2054
2267
|
|
|
2055
2268
|
// src/specification/specification.ts
|
|
@@ -2151,6 +2364,9 @@ var getMetaWebhookVerificationResponse = (request, expectedVerifyToken) => {
|
|
|
2151
2364
|
export {
|
|
2152
2365
|
Slate,
|
|
2153
2366
|
SlateAction,
|
|
2367
|
+
SlateActionBuilder,
|
|
2368
|
+
SlateAdapter,
|
|
2369
|
+
SlateAdapterSpec,
|
|
2154
2370
|
SlateAuth,
|
|
2155
2371
|
SlateConfig,
|
|
2156
2372
|
SlateContext,
|
|
@@ -2158,9 +2374,12 @@ export {
|
|
|
2158
2374
|
SlateDefaultPollingIntervalSeconds,
|
|
2159
2375
|
SlateError,
|
|
2160
2376
|
SlateLogger,
|
|
2377
|
+
SlatePublicContext,
|
|
2378
|
+
SlatePublicTool,
|
|
2161
2379
|
SlateSpecification,
|
|
2162
2380
|
SlateTool,
|
|
2163
2381
|
SlateTrigger,
|
|
2382
|
+
adapterSpec,
|
|
2164
2383
|
allOf,
|
|
2165
2384
|
anyOf,
|
|
2166
2385
|
auth,
|
|
@@ -2197,6 +2416,7 @@ export {
|
|
|
2197
2416
|
metaWebhookHttp,
|
|
2198
2417
|
normalizeOAuthTokenResponse,
|
|
2199
2418
|
pickDefined,
|
|
2419
|
+
publicTool,
|
|
2200
2420
|
requestAxios,
|
|
2201
2421
|
requestAxiosData,
|
|
2202
2422
|
runWithContext,
|
package/package.json
CHANGED
package/src/action/action.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
|
-
import type { SlateContext } from '../context';
|
|
2
|
+
import type { SlateContext, SlatePublicContext } from '../context';
|
|
3
3
|
import type { SlateActionDocsReference } from '../docs';
|
|
4
4
|
import type { SlateSpecification } from '../specification/specification';
|
|
5
5
|
import type { SlateAttachment } from './attachment';
|
|
@@ -29,6 +29,8 @@ export interface SlateActionParameters {
|
|
|
29
29
|
scopes?: SlateActionScopes;
|
|
30
30
|
authMethods?: string[];
|
|
31
31
|
docs?: SlateActionDocsReference[];
|
|
32
|
+
adapter?: string | null;
|
|
33
|
+
isPublic?: boolean;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
export type SlateToolInvocationHandler<
|
|
@@ -42,6 +44,14 @@ export type SlateToolInvocationHandler<
|
|
|
42
44
|
attachments?: SlateAttachment[];
|
|
43
45
|
}>;
|
|
44
46
|
|
|
47
|
+
export type SlatePublicToolInvocationHandler<InputType extends {}, OutputType extends {}> = (
|
|
48
|
+
context: SlatePublicContext<InputType>
|
|
49
|
+
) => Promise<{
|
|
50
|
+
output: OutputType;
|
|
51
|
+
message: string;
|
|
52
|
+
attachments?: SlateAttachment[];
|
|
53
|
+
}>;
|
|
54
|
+
|
|
45
55
|
export type SlateTriggerMappingHandler<
|
|
46
56
|
ConfigType extends {},
|
|
47
57
|
AuthType extends {},
|
|
@@ -258,4 +268,12 @@ export abstract class SlateAction<
|
|
|
258
268
|
get docs() {
|
|
259
269
|
return this._params.docs;
|
|
260
270
|
}
|
|
271
|
+
|
|
272
|
+
get adapter() {
|
|
273
|
+
return this._params.adapter ?? null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
get isPublic() {
|
|
277
|
+
return this._params.isPublic === true;
|
|
278
|
+
}
|
|
261
279
|
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { SlateAuth } from '../auth';
|
|
4
|
+
import { SlateConfig } from '../config';
|
|
5
|
+
import { SlatePublicContext } from '../context';
|
|
6
|
+
import { SlateSpecification } from '../specification/specification';
|
|
7
|
+
import { SlatePublicTool } from './publicTool';
|
|
8
|
+
import { SlateTool } from './tool';
|
|
9
|
+
|
|
10
|
+
let createTestSpec = () => {
|
|
11
|
+
let config = SlateConfig.create(
|
|
12
|
+
z.object({
|
|
13
|
+
prefix: z.string()
|
|
14
|
+
})
|
|
15
|
+
);
|
|
16
|
+
let auth = SlateAuth.create<{ token: string }>().output(
|
|
17
|
+
z.object({
|
|
18
|
+
token: z.string()
|
|
19
|
+
})
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
return SlateSpecification.create({
|
|
23
|
+
key: 'demo',
|
|
24
|
+
name: 'Demo',
|
|
25
|
+
config,
|
|
26
|
+
auth
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
describe('SlateActionBuilder.lockInterface', () => {
|
|
31
|
+
it('prevents changing input and output schemas after the interface is locked', () => {
|
|
32
|
+
let spec = createTestSpec();
|
|
33
|
+
let builder = SlateTool.create(spec, {
|
|
34
|
+
key: 'send',
|
|
35
|
+
name: 'Send'
|
|
36
|
+
})
|
|
37
|
+
.input(z.object({ to: z.string() }))
|
|
38
|
+
.output(z.object({ id: z.string() }))
|
|
39
|
+
.lockInterface();
|
|
40
|
+
|
|
41
|
+
expect(() => builder.input(z.object({}))).toThrow(
|
|
42
|
+
'Adapter contract input schema cannot be changed'
|
|
43
|
+
);
|
|
44
|
+
expect(() => builder.output(z.object({}))).toThrow(
|
|
45
|
+
'Adapter contract output schema cannot be changed'
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('SlatePublicTool', () => {
|
|
51
|
+
it('builds a public tool that omits config and auth from the handler context', async () => {
|
|
52
|
+
let spec = createTestSpec();
|
|
53
|
+
let tool = SlatePublicTool.create(spec, {
|
|
54
|
+
key: 'setup',
|
|
55
|
+
name: 'Setup'
|
|
56
|
+
})
|
|
57
|
+
.input(
|
|
58
|
+
z.object({
|
|
59
|
+
name: z.string()
|
|
60
|
+
})
|
|
61
|
+
)
|
|
62
|
+
.output(
|
|
63
|
+
z.object({
|
|
64
|
+
greeting: z.string()
|
|
65
|
+
})
|
|
66
|
+
)
|
|
67
|
+
.handleInvocation(async ctx => {
|
|
68
|
+
expect(ctx).not.toHaveProperty('config');
|
|
69
|
+
expect(ctx).not.toHaveProperty('auth');
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
output: { greeting: `Hello ${ctx.input.name}` },
|
|
73
|
+
message: 'ok'
|
|
74
|
+
};
|
|
75
|
+
})
|
|
76
|
+
.build();
|
|
77
|
+
|
|
78
|
+
expect(tool.isPublic).toBe(true);
|
|
79
|
+
expect(tool.key).toBe('setup');
|
|
80
|
+
|
|
81
|
+
let result = await tool.handleInvocation(
|
|
82
|
+
new SlatePublicContext({ name: 'Ada' }, spec, {
|
|
83
|
+
debug: () => {},
|
|
84
|
+
error: () => {},
|
|
85
|
+
info: () => {},
|
|
86
|
+
progress: () => {},
|
|
87
|
+
warn: () => {}
|
|
88
|
+
} as any) as any
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
expect(result.output).toEqual({ greeting: 'Hello Ada' });
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('keeps regular tools private by default', () => {
|
|
95
|
+
let spec = createTestSpec();
|
|
96
|
+
let tool = SlateTool.create(spec, {
|
|
97
|
+
key: 'send',
|
|
98
|
+
name: 'Send'
|
|
99
|
+
})
|
|
100
|
+
.input(z.object({}))
|
|
101
|
+
.output(z.object({}))
|
|
102
|
+
.handleInvocation(async () => ({
|
|
103
|
+
output: {},
|
|
104
|
+
message: 'ok'
|
|
105
|
+
}))
|
|
106
|
+
.build();
|
|
107
|
+
|
|
108
|
+
expect(tool.isPublic).toBe(false);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('rejects authentication methods on public tools', () => {
|
|
112
|
+
let spec = createTestSpec();
|
|
113
|
+
|
|
114
|
+
expect(() =>
|
|
115
|
+
SlatePublicTool.create(spec, {
|
|
116
|
+
key: 'setup',
|
|
117
|
+
name: 'Setup'
|
|
118
|
+
}).authMethods(['token_auth'])
|
|
119
|
+
).toThrow('Public tools cannot require authentication methods');
|
|
120
|
+
|
|
121
|
+
expect(() =>
|
|
122
|
+
SlatePublicTool.create(spec, {
|
|
123
|
+
key: 'setup',
|
|
124
|
+
name: 'Setup',
|
|
125
|
+
authMethods: ['token_auth']
|
|
126
|
+
})
|
|
127
|
+
.input(z.object({}))
|
|
128
|
+
.output(z.object({}))
|
|
129
|
+
.handleInvocation(async () => ({
|
|
130
|
+
output: {},
|
|
131
|
+
message: 'ok'
|
|
132
|
+
}))
|
|
133
|
+
.build()
|
|
134
|
+
).toThrow('Public tools cannot require authentication methods');
|
|
135
|
+
});
|
|
136
|
+
});
|