@slates/provider 1.0.0-rc.16 → 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 +639 -21
- package/dist/index.d.cts +290 -29
- package/dist/index.d.ts +290 -29
- package/dist/index.module.js +606 -18
- package/package.json +2 -2
- package/src/action/action.ts +64 -2
- package/src/action/builder.test.ts +136 -0
- package/src/action/builder.ts +73 -13
- package/src/action/index.ts +2 -1
- package/src/action/publicTool.ts +36 -0
- package/src/action/tool.ts +15 -3
- package/src/action/trigger.ts +9 -1
- 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/auth/index.ts +1 -0
- package/src/auth/oauth.test.ts +83 -0
- package/src/auth/oauth.ts +150 -0
- package/src/auth/types.ts +22 -6
- package/src/axios/http.test.ts +83 -0
- package/src/axios/index.ts +59 -1
- package/src/axios/trace.ts +3 -3
- package/src/context/context.ts +37 -14
- package/src/context/hook.ts +5 -10
- package/src/crypto/hmac.test.ts +40 -0
- package/src/crypto/hmac.ts +32 -0
- package/src/crypto/index.ts +1 -0
- package/src/error/api.test.ts +114 -0
- package/src/error/api.ts +236 -0
- package/src/error/index.ts +1 -0
- package/src/file/index.test.ts +36 -0
- package/src/file/index.ts +27 -0
- package/src/index.ts +5 -0
- package/src/object/index.test.ts +38 -0
- package/src/object/index.ts +12 -0
- package/src/specification/slate.ts +38 -2
- package/src/webhook/graph.test.ts +37 -0
- package/src/webhook/graph.ts +22 -0
- package/src/webhook/index.ts +2 -0
- package/src/webhook/meta.test.ts +52 -0
- package/src/webhook/meta.ts +43 -0
package/dist/index.module.js
CHANGED
|
@@ -54,6 +54,130 @@ 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
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/error/api.ts
|
|
66
|
+
import { badRequestError, ServiceError } from "@lowerdeck/error";
|
|
67
|
+
var DEFAULT_DETAIL_KEYS = ["message", "detail", "error", "error_description", "code"];
|
|
68
|
+
var DEFAULT_NESTED_KEYS = ["errors"];
|
|
69
|
+
var isApiErrorRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70
|
+
var pushDetail = (details, value, options = {}) => {
|
|
71
|
+
if (typeof value !== "string" && (options.includeNumbers === false || typeof value !== "number")) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
let detail = String(value).trim();
|
|
75
|
+
if (detail && !details.includes(detail)) {
|
|
76
|
+
details.push(detail);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var collectApiErrorDetails = (value, details, options = {}) => {
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
for (let item of value) {
|
|
82
|
+
collectApiErrorDetails(item, details, options);
|
|
83
|
+
}
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!isApiErrorRecord(value)) {
|
|
87
|
+
pushDetail(details, value, options);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
for (let key of options.detailKeys ?? DEFAULT_DETAIL_KEYS) {
|
|
91
|
+
pushDetail(details, value[key], options);
|
|
92
|
+
}
|
|
93
|
+
for (let key of options.nestedKeys ?? DEFAULT_NESTED_KEYS) {
|
|
94
|
+
collectApiErrorDetails(value[key], details, options);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
var getSlateErrorResponse = (error) => {
|
|
98
|
+
if (error.name !== "SlateError" || !isApiErrorRecord(error.data)) {
|
|
99
|
+
return void 0;
|
|
100
|
+
}
|
|
101
|
+
let data = error.data;
|
|
102
|
+
let upstream = isApiErrorRecord(data.upstream) ? data.upstream : void 0;
|
|
103
|
+
let status = upstream?.status ?? data.status;
|
|
104
|
+
return typeof status === "number" || typeof status === "string" ? { status } : void 0;
|
|
105
|
+
};
|
|
106
|
+
var getApiErrorResponse = (error) => {
|
|
107
|
+
if (!isApiErrorRecord(error)) {
|
|
108
|
+
return void 0;
|
|
109
|
+
}
|
|
110
|
+
if (!isApiErrorRecord(error.response)) {
|
|
111
|
+
return getSlateErrorResponse(error);
|
|
112
|
+
}
|
|
113
|
+
let response = error.response;
|
|
114
|
+
return {
|
|
115
|
+
status: typeof response.status === "number" || typeof response.status === "string" ? response.status : void 0,
|
|
116
|
+
statusText: typeof response.statusText === "string" ? response.statusText : void 0,
|
|
117
|
+
data: response.data
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
var getApiErrorStatus = (error) => getApiErrorResponse(error)?.status;
|
|
121
|
+
var statusLabelForApiError = (status, statusText) => status !== void 0 ? `HTTP ${status}${statusText ? ` ${statusText}` : ""}: ` : "";
|
|
122
|
+
var extractApiErrorMessage = (error, options = {}) => {
|
|
123
|
+
let details = [];
|
|
124
|
+
let response = options.response ?? getApiErrorResponse(error);
|
|
125
|
+
collectApiErrorDetails(response?.data, details, options);
|
|
126
|
+
if (details.length > 0) {
|
|
127
|
+
return details.join(options.separator ?? " - ");
|
|
128
|
+
}
|
|
129
|
+
if (error instanceof Error && error.message) {
|
|
130
|
+
return error.message;
|
|
131
|
+
}
|
|
132
|
+
return options.fallbackMessage ?? "Unknown error";
|
|
133
|
+
};
|
|
134
|
+
var createApiServiceError = (message, options = {}) => {
|
|
135
|
+
let error = new ServiceError(badRequestError({ message }));
|
|
136
|
+
if (options.reason !== void 0) {
|
|
137
|
+
error.data.reason = options.reason;
|
|
138
|
+
}
|
|
139
|
+
if ("upstreamStatus" in options) {
|
|
140
|
+
error.data.upstreamStatus = options.upstreamStatus;
|
|
141
|
+
}
|
|
142
|
+
if ("upstreamCode" in options) {
|
|
143
|
+
error.data.upstreamCode = options.upstreamCode;
|
|
144
|
+
}
|
|
145
|
+
if (options.parent instanceof Error) {
|
|
146
|
+
error.setParent(options.parent);
|
|
147
|
+
}
|
|
148
|
+
return error;
|
|
149
|
+
};
|
|
150
|
+
var helpers = {
|
|
151
|
+
collectDetails: collectApiErrorDetails,
|
|
152
|
+
extractMessage: extractApiErrorMessage,
|
|
153
|
+
getResponse: getApiErrorResponse,
|
|
154
|
+
getStatus: getApiErrorStatus,
|
|
155
|
+
isRecord: isApiErrorRecord,
|
|
156
|
+
statusLabelFor: statusLabelForApiError
|
|
157
|
+
};
|
|
158
|
+
var buildApiServiceError = (error, options) => {
|
|
159
|
+
if (error instanceof ServiceError) {
|
|
160
|
+
return error;
|
|
161
|
+
}
|
|
162
|
+
let operation = options.operation ?? "request";
|
|
163
|
+
let response = options.extractResponse?.(error, helpers) ?? getApiErrorResponse(error);
|
|
164
|
+
let status = options.extractStatus?.(error, response, helpers) ?? response?.status;
|
|
165
|
+
let message = options.extractMessage?.(error, helpers) ?? extractApiErrorMessage(error, { ...options, response });
|
|
166
|
+
let statusLabel = statusLabelForApiError(status, response?.statusText);
|
|
167
|
+
let fullMessage = options.formatMessage?.({
|
|
168
|
+
providerLabel: options.providerLabel,
|
|
169
|
+
operation,
|
|
170
|
+
statusLabel,
|
|
171
|
+
message,
|
|
172
|
+
response,
|
|
173
|
+
status
|
|
174
|
+
}) ?? `${options.providerLabel} API ${operation} failed: ${statusLabel}${message}`;
|
|
175
|
+
return createApiServiceError(fullMessage, {
|
|
176
|
+
reason: options.reason,
|
|
177
|
+
upstreamStatus: status,
|
|
178
|
+
upstreamCode: options.extractUpstreamCode?.(error, response, helpers),
|
|
179
|
+
parent: options.parent ?? error
|
|
180
|
+
});
|
|
57
181
|
};
|
|
58
182
|
|
|
59
183
|
// src/error/axios.ts
|
|
@@ -680,11 +804,12 @@ var isScopes = (value) => typeof value === "object" && value !== null && "AND" i
|
|
|
680
804
|
|
|
681
805
|
// src/action/builder.ts
|
|
682
806
|
var SlateActionBuilder = class {
|
|
683
|
-
constructor(type, spec2, params, factory) {
|
|
807
|
+
constructor(type, spec2, params, factory, isPublicTool = false) {
|
|
684
808
|
this.type = type;
|
|
685
809
|
this.spec = spec2;
|
|
686
810
|
this.params = params;
|
|
687
811
|
this.factory = factory;
|
|
812
|
+
this.isPublicTool = isPublicTool;
|
|
688
813
|
this.#configSchema = spec2.configSchema;
|
|
689
814
|
this.#authSchema = spec2.authSchema;
|
|
690
815
|
}
|
|
@@ -692,6 +817,7 @@ var SlateActionBuilder = class {
|
|
|
692
817
|
spec;
|
|
693
818
|
params;
|
|
694
819
|
factory;
|
|
820
|
+
isPublicTool;
|
|
695
821
|
#configSchema;
|
|
696
822
|
#authSchema;
|
|
697
823
|
#inputSchema = null;
|
|
@@ -700,20 +826,34 @@ var SlateActionBuilder = class {
|
|
|
700
826
|
#authMethods;
|
|
701
827
|
#toolParams = null;
|
|
702
828
|
#triggerParams = null;
|
|
829
|
+
#interfaceLocked = false;
|
|
703
830
|
input(schema) {
|
|
831
|
+
if (this.#interfaceLocked) {
|
|
832
|
+
throw new SlateDeclarationError("Adapter contract input schema cannot be changed");
|
|
833
|
+
}
|
|
704
834
|
this.#inputSchema = schema;
|
|
705
835
|
return this;
|
|
706
836
|
}
|
|
707
837
|
output(schema) {
|
|
838
|
+
if (this.#interfaceLocked) {
|
|
839
|
+
throw new SlateDeclarationError("Adapter contract output schema cannot be changed");
|
|
840
|
+
}
|
|
708
841
|
this.#outputSchema = schema;
|
|
709
842
|
return this;
|
|
710
843
|
}
|
|
844
|
+
lockInterface() {
|
|
845
|
+
this.#interfaceLocked = true;
|
|
846
|
+
return this;
|
|
847
|
+
}
|
|
711
848
|
scopes(scopes) {
|
|
712
849
|
validateScopes(scopes);
|
|
713
850
|
this.#scopes = scopes;
|
|
714
851
|
return this;
|
|
715
852
|
}
|
|
716
853
|
authMethods(authMethods) {
|
|
854
|
+
if (this.isPublicTool) {
|
|
855
|
+
throw new SlateDeclarationError("Public tools cannot require authentication methods");
|
|
856
|
+
}
|
|
717
857
|
this.#authMethods = this.validateAuthMethods(authMethods);
|
|
718
858
|
return this;
|
|
719
859
|
}
|
|
@@ -745,7 +885,8 @@ var SlateActionBuilder = class {
|
|
|
745
885
|
handleEvent: props.handleEvent,
|
|
746
886
|
handleRequest: props.handleRequest,
|
|
747
887
|
autoRegisterWebhook: props.autoRegisterWebhook,
|
|
748
|
-
autoUnregisterWebhook: props.autoUnregisterWebhook
|
|
888
|
+
autoUnregisterWebhook: props.autoUnregisterWebhook,
|
|
889
|
+
http: props.http
|
|
749
890
|
};
|
|
750
891
|
return this;
|
|
751
892
|
}
|
|
@@ -768,6 +909,9 @@ var SlateActionBuilder = class {
|
|
|
768
909
|
validateScopes(scopes);
|
|
769
910
|
}
|
|
770
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
|
+
}
|
|
771
915
|
if (!this.#inputSchema) {
|
|
772
916
|
throw new SlateDeclarationError("Input schema is not defined");
|
|
773
917
|
}
|
|
@@ -784,6 +928,7 @@ var SlateActionBuilder = class {
|
|
|
784
928
|
...this.params,
|
|
785
929
|
scopes,
|
|
786
930
|
authMethods,
|
|
931
|
+
isPublic: this.isPublicTool === true,
|
|
787
932
|
configSchema: this.#configSchema,
|
|
788
933
|
authSchema: this.#authSchema,
|
|
789
934
|
inputSchema: this.#inputSchema,
|
|
@@ -803,16 +948,40 @@ var SlateTool = class _SlateTool extends SlateAction {
|
|
|
803
948
|
}
|
|
804
949
|
static create(spec2, params) {
|
|
805
950
|
return new SlateActionBuilder("tool", spec2, params, (params2) => {
|
|
806
|
-
|
|
807
|
-
return new _SlateTool(spec2, params2.inputSchema, params2.outputSchema, params2);
|
|
951
|
+
return _SlateTool.fromCreateParameters(spec2, params2);
|
|
808
952
|
});
|
|
809
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
|
+
}
|
|
810
958
|
get handleInvocation() {
|
|
811
959
|
return this.#handleInvocation;
|
|
812
960
|
}
|
|
813
961
|
};
|
|
814
962
|
var tool = (spec2, params) => SlateTool.create(spec2, params);
|
|
815
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
|
+
|
|
816
985
|
// src/action/trigger.ts
|
|
817
986
|
var SlateDefaultPollingIntervalSeconds = 60 * 10;
|
|
818
987
|
var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
@@ -820,6 +989,7 @@ var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
|
820
989
|
#polling;
|
|
821
990
|
#handleEvent;
|
|
822
991
|
#handleRequest;
|
|
992
|
+
#http;
|
|
823
993
|
#pollEvents;
|
|
824
994
|
#autoRegisterWebhook;
|
|
825
995
|
#autoUnregisterWebhook;
|
|
@@ -831,6 +1001,7 @@ var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
|
831
1001
|
};
|
|
832
1002
|
this.#handleEvent = params.handleEvent;
|
|
833
1003
|
this.#handleRequest = params.handleRequest;
|
|
1004
|
+
this.#http = params.http;
|
|
834
1005
|
this.#pollEvents = params.pollEvents;
|
|
835
1006
|
this.#autoRegisterWebhook = params.autoRegisterWebhook;
|
|
836
1007
|
this.#autoUnregisterWebhook = params.autoUnregisterWebhook;
|
|
@@ -853,6 +1024,9 @@ var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
|
853
1024
|
get handleRequest() {
|
|
854
1025
|
return this.#handleRequest;
|
|
855
1026
|
}
|
|
1027
|
+
get http() {
|
|
1028
|
+
return this.#http;
|
|
1029
|
+
}
|
|
856
1030
|
get pollEvents() {
|
|
857
1031
|
return this.#pollEvents;
|
|
858
1032
|
}
|
|
@@ -890,6 +1064,135 @@ var createTextAttachment = (content, mimeType) => ({
|
|
|
890
1064
|
}
|
|
891
1065
|
});
|
|
892
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
|
+
|
|
893
1196
|
// src/auth/auth.ts
|
|
894
1197
|
var SlateAuth = class _SlateAuth {
|
|
895
1198
|
#outputSchema = null;
|
|
@@ -947,6 +1250,90 @@ var SlateAuth = class _SlateAuth {
|
|
|
947
1250
|
};
|
|
948
1251
|
var auth = () => SlateAuth.create();
|
|
949
1252
|
|
|
1253
|
+
// src/auth/oauth.ts
|
|
1254
|
+
var isOAuthTokenResponse = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1255
|
+
var formatOAuthTokenResponseMessage = (fieldLabel, providerLabel = "OAuth provider", operation = "token response") => `${providerLabel} OAuth ${operation} did not return ${fieldLabel}.`;
|
|
1256
|
+
var getOAuthExpiresAtFromExpiresIn = (expiresIn, options = {}) => {
|
|
1257
|
+
let {
|
|
1258
|
+
nowMs = Date.now(),
|
|
1259
|
+
providerLabel,
|
|
1260
|
+
operation,
|
|
1261
|
+
required = false,
|
|
1262
|
+
expiresInType = "numberLike",
|
|
1263
|
+
message
|
|
1264
|
+
} = options;
|
|
1265
|
+
if (expiresIn === void 0 || expiresIn === null || expiresIn === "") {
|
|
1266
|
+
if (required) {
|
|
1267
|
+
throw createApiServiceError(
|
|
1268
|
+
message ?? formatOAuthTokenResponseMessage(
|
|
1269
|
+
"a valid expires_in value",
|
|
1270
|
+
providerLabel,
|
|
1271
|
+
operation
|
|
1272
|
+
),
|
|
1273
|
+
{ reason: "oauth_token_response" }
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
return void 0;
|
|
1277
|
+
}
|
|
1278
|
+
let seconds = typeof expiresIn === "number" ? expiresIn : expiresInType === "numberLike" && typeof expiresIn === "string" ? Number(expiresIn) : Number.NaN;
|
|
1279
|
+
if (!Number.isFinite(seconds)) {
|
|
1280
|
+
throw createApiServiceError(
|
|
1281
|
+
message ?? formatOAuthTokenResponseMessage("a valid expires_in value", providerLabel, operation),
|
|
1282
|
+
{ reason: "oauth_token_response" }
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
return new Date(nowMs + seconds * 1e3).toISOString();
|
|
1286
|
+
};
|
|
1287
|
+
var getRefreshToken = (refreshToken, previousRefreshToken, fallbackMode) => {
|
|
1288
|
+
if (typeof refreshToken === "string") {
|
|
1289
|
+
if (fallbackMode === "falsy" && !refreshToken) {
|
|
1290
|
+
return previousRefreshToken;
|
|
1291
|
+
}
|
|
1292
|
+
return refreshToken;
|
|
1293
|
+
}
|
|
1294
|
+
if (fallbackMode === "falsy" && !refreshToken) {
|
|
1295
|
+
return previousRefreshToken;
|
|
1296
|
+
}
|
|
1297
|
+
return refreshToken === void 0 || refreshToken === null ? previousRefreshToken : void 0;
|
|
1298
|
+
};
|
|
1299
|
+
var normalizeOAuthTokenResponse = (data, options = {}) => {
|
|
1300
|
+
let {
|
|
1301
|
+
providerLabel,
|
|
1302
|
+
operation,
|
|
1303
|
+
previousRefreshToken,
|
|
1304
|
+
refreshTokenFallbackMode = "nullish",
|
|
1305
|
+
accessTokenMessage,
|
|
1306
|
+
expiresInMessage,
|
|
1307
|
+
...expiresAtOptions
|
|
1308
|
+
} = options;
|
|
1309
|
+
if (!isOAuthTokenResponse(data)) {
|
|
1310
|
+
throw createApiServiceError(
|
|
1311
|
+
accessTokenMessage ?? formatOAuthTokenResponseMessage("a token response object", providerLabel, operation),
|
|
1312
|
+
{ reason: "oauth_token_response" }
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
if (typeof data.access_token !== "string" || !data.access_token) {
|
|
1316
|
+
throw createApiServiceError(
|
|
1317
|
+
accessTokenMessage ?? formatOAuthTokenResponseMessage("an access token", providerLabel, operation),
|
|
1318
|
+
{ reason: "oauth_token_response" }
|
|
1319
|
+
);
|
|
1320
|
+
}
|
|
1321
|
+
return {
|
|
1322
|
+
token: data.access_token,
|
|
1323
|
+
refreshToken: getRefreshToken(
|
|
1324
|
+
data.refresh_token,
|
|
1325
|
+
previousRefreshToken,
|
|
1326
|
+
refreshTokenFallbackMode
|
|
1327
|
+
),
|
|
1328
|
+
expiresAt: getOAuthExpiresAtFromExpiresIn(data.expires_in, {
|
|
1329
|
+
...expiresAtOptions,
|
|
1330
|
+
providerLabel,
|
|
1331
|
+
operation,
|
|
1332
|
+
message: expiresInMessage
|
|
1333
|
+
})
|
|
1334
|
+
};
|
|
1335
|
+
};
|
|
1336
|
+
|
|
950
1337
|
// src/axios/index.ts
|
|
951
1338
|
import baseAxios, { getAdapter, isAxiosError as isAxiosError2 } from "axios";
|
|
952
1339
|
|
|
@@ -1530,6 +1917,35 @@ var createAxios = (config2) => {
|
|
|
1530
1917
|
applySlateInterceptors(instance, errorMapping);
|
|
1531
1918
|
return instance;
|
|
1532
1919
|
};
|
|
1920
|
+
var createAuthenticatedAxios = (config2) => {
|
|
1921
|
+
let { authHeader, contentType = "application/json", errorAdapter, ...axiosConfig } = config2;
|
|
1922
|
+
let instance = createAxios({
|
|
1923
|
+
...axiosConfig,
|
|
1924
|
+
headers: {
|
|
1925
|
+
...contentType === false ? {} : { "Content-Type": contentType },
|
|
1926
|
+
...authHeader ? { [authHeader.name ?? "Authorization"]: authHeader.value } : {},
|
|
1927
|
+
...axiosConfig.headers
|
|
1928
|
+
}
|
|
1929
|
+
});
|
|
1930
|
+
if (errorAdapter) {
|
|
1931
|
+
instance.interceptors.response.use(
|
|
1932
|
+
(response) => response,
|
|
1933
|
+
(error) => Promise.reject(errorAdapter(error))
|
|
1934
|
+
);
|
|
1935
|
+
}
|
|
1936
|
+
return instance;
|
|
1937
|
+
};
|
|
1938
|
+
var requestAxios = async (operation, request, errorAdapter) => {
|
|
1939
|
+
try {
|
|
1940
|
+
return await request();
|
|
1941
|
+
} catch (error) {
|
|
1942
|
+
throw errorAdapter(error, operation);
|
|
1943
|
+
}
|
|
1944
|
+
};
|
|
1945
|
+
var requestAxiosData = async (operation, request, errorAdapter) => {
|
|
1946
|
+
let response = await requestAxios(operation, request, errorAdapter);
|
|
1947
|
+
return response.data;
|
|
1948
|
+
};
|
|
1533
1949
|
var axios = createAxios();
|
|
1534
1950
|
|
|
1535
1951
|
// src/config/config.ts
|
|
@@ -1576,26 +1992,19 @@ var SlateConfig = class _SlateConfig {
|
|
|
1576
1992
|
var config = (schema) => SlateConfig.create(schema);
|
|
1577
1993
|
|
|
1578
1994
|
// src/context/context.ts
|
|
1579
|
-
var
|
|
1580
|
-
constructor(
|
|
1995
|
+
var SlatePublicContext = class {
|
|
1996
|
+
constructor(input, spec2, logger) {
|
|
1581
1997
|
this.spec = spec2;
|
|
1582
1998
|
this.logger = logger;
|
|
1583
|
-
this.#config = config2;
|
|
1584
1999
|
this.#input = input;
|
|
1585
|
-
this.#auth = auth2;
|
|
1586
2000
|
}
|
|
1587
2001
|
spec;
|
|
1588
2002
|
logger;
|
|
1589
|
-
#config;
|
|
1590
2003
|
#input;
|
|
1591
|
-
#auth;
|
|
1592
2004
|
#httpTraces = [];
|
|
1593
2005
|
get specification() {
|
|
1594
2006
|
return this.spec;
|
|
1595
2007
|
}
|
|
1596
|
-
get config() {
|
|
1597
|
-
return Object.freeze(this.#config);
|
|
1598
|
-
}
|
|
1599
2008
|
get input() {
|
|
1600
2009
|
return Object.freeze(this.#input);
|
|
1601
2010
|
}
|
|
@@ -1608,8 +2017,10 @@ var SlateContext = class {
|
|
|
1608
2017
|
get request() {
|
|
1609
2018
|
return Object.freeze(this.#input.request);
|
|
1610
2019
|
}
|
|
1611
|
-
get
|
|
1612
|
-
return Object.freeze(
|
|
2020
|
+
get registrationDetails() {
|
|
2021
|
+
return Object.freeze(
|
|
2022
|
+
this.#input.registrationDetails
|
|
2023
|
+
);
|
|
1613
2024
|
}
|
|
1614
2025
|
recordHttpTrace(trace) {
|
|
1615
2026
|
this.#httpTraces.push(trace);
|
|
@@ -1645,6 +2056,60 @@ var SlateContext = class {
|
|
|
1645
2056
|
this.logger.progress(message);
|
|
1646
2057
|
}
|
|
1647
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
|
+
};
|
|
2074
|
+
|
|
2075
|
+
// src/crypto/hmac.ts
|
|
2076
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
2077
|
+
var createHmacSignature = ({
|
|
2078
|
+
secret,
|
|
2079
|
+
payload,
|
|
2080
|
+
algorithm = "sha256",
|
|
2081
|
+
digest,
|
|
2082
|
+
prefix = ""
|
|
2083
|
+
}) => `${prefix}${createHmac(algorithm, secret).update(payload).digest(digest)}`;
|
|
2084
|
+
var verifyHmacSignature = (options) => {
|
|
2085
|
+
let expected = createHmacSignature(options);
|
|
2086
|
+
let expectedBytes = Buffer.from(expected);
|
|
2087
|
+
let signatureBytes = Buffer.from(options.signature);
|
|
2088
|
+
let lengthsMatch = signatureBytes.length === expectedBytes.length;
|
|
2089
|
+
let comparableSignature = lengthsMatch ? signatureBytes : Buffer.alloc(expectedBytes.length);
|
|
2090
|
+
return timingSafeEqual(comparableSignature, expectedBytes) && lengthsMatch;
|
|
2091
|
+
};
|
|
2092
|
+
|
|
2093
|
+
// src/file/index.ts
|
|
2094
|
+
var getResponseHeaderValue = (headers, name) => {
|
|
2095
|
+
if (!headers) return void 0;
|
|
2096
|
+
if (typeof headers.get === "function") {
|
|
2097
|
+
let value = headers.get(name);
|
|
2098
|
+
return typeof value === "string" ? value : void 0;
|
|
2099
|
+
}
|
|
2100
|
+
if (typeof headers !== "object") return void 0;
|
|
2101
|
+
let lowerName = name.toLowerCase();
|
|
2102
|
+
for (let [headerName, value] of Object.entries(headers)) {
|
|
2103
|
+
if (headerName.toLowerCase() !== lowerName) continue;
|
|
2104
|
+
if (Array.isArray(value)) {
|
|
2105
|
+
let first = value.find((item) => typeof item === "string");
|
|
2106
|
+
return typeof first === "string" ? first : void 0;
|
|
2107
|
+
}
|
|
2108
|
+
return typeof value === "string" ? value : void 0;
|
|
2109
|
+
}
|
|
2110
|
+
return void 0;
|
|
2111
|
+
};
|
|
2112
|
+
var getBase64ByteLength = (contentBase64) => Buffer.from(contentBase64, "base64").byteLength;
|
|
1648
2113
|
|
|
1649
2114
|
// src/logger/logger.ts
|
|
1650
2115
|
import { encode } from "@toon-format/toon";
|
|
@@ -1741,16 +2206,53 @@ var SlateLogger = class {
|
|
|
1741
2206
|
}
|
|
1742
2207
|
};
|
|
1743
2208
|
|
|
2209
|
+
// src/object/index.ts
|
|
2210
|
+
var pickDefined = (value) => Object.fromEntries(
|
|
2211
|
+
Object.entries(value).filter(([, child]) => child !== void 0)
|
|
2212
|
+
);
|
|
2213
|
+
var setIfDefined = (target, key, value) => {
|
|
2214
|
+
if (value !== void 0) {
|
|
2215
|
+
target[key] = value;
|
|
2216
|
+
}
|
|
2217
|
+
return target;
|
|
2218
|
+
};
|
|
2219
|
+
|
|
1744
2220
|
// src/specification/slate.ts
|
|
1745
2221
|
var Slate = class _Slate {
|
|
1746
|
-
constructor(_spec, _actions) {
|
|
2222
|
+
constructor(_spec, _actions, _adapters) {
|
|
1747
2223
|
this._spec = _spec;
|
|
1748
2224
|
this._actions = _actions;
|
|
2225
|
+
this._adapters = _adapters;
|
|
1749
2226
|
}
|
|
1750
2227
|
_spec;
|
|
1751
2228
|
_actions;
|
|
2229
|
+
_adapters;
|
|
1752
2230
|
static create(params) {
|
|
1753
|
-
|
|
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);
|
|
1754
2256
|
}
|
|
1755
2257
|
get spec() {
|
|
1756
2258
|
return this._spec;
|
|
@@ -1758,6 +2260,9 @@ var Slate = class _Slate {
|
|
|
1758
2260
|
get actions() {
|
|
1759
2261
|
return this._actions;
|
|
1760
2262
|
}
|
|
2263
|
+
get adapters() {
|
|
2264
|
+
return this._adapters;
|
|
2265
|
+
}
|
|
1761
2266
|
};
|
|
1762
2267
|
|
|
1763
2268
|
// src/specification/specification.ts
|
|
@@ -1803,9 +2308,65 @@ var SlateSpecification = class _SlateSpecification {
|
|
|
1803
2308
|
}
|
|
1804
2309
|
};
|
|
1805
2310
|
var spec = (params) => SlateSpecification.create(params);
|
|
2311
|
+
|
|
2312
|
+
// src/webhook/graph.ts
|
|
2313
|
+
var graphWebhookHttp = {
|
|
2314
|
+
methods: ["POST"],
|
|
2315
|
+
sync: {
|
|
2316
|
+
mode: "match",
|
|
2317
|
+
match: [{ hasQueryParam: "validationToken" }]
|
|
2318
|
+
}
|
|
2319
|
+
};
|
|
2320
|
+
var getGraphWebhookValidationResponse = (request) => {
|
|
2321
|
+
let validationToken = new URL(request.url).searchParams.get("validationToken");
|
|
2322
|
+
if (validationToken === null) return null;
|
|
2323
|
+
return {
|
|
2324
|
+
status: 200,
|
|
2325
|
+
headers: { "content-type": "text/plain" },
|
|
2326
|
+
body: validationToken
|
|
2327
|
+
};
|
|
2328
|
+
};
|
|
2329
|
+
|
|
2330
|
+
// src/webhook/meta.ts
|
|
2331
|
+
var metaWebhookHttp = {
|
|
2332
|
+
methods: ["GET", "POST"],
|
|
2333
|
+
sync: {
|
|
2334
|
+
mode: "match",
|
|
2335
|
+
match: [{ method: "GET", hasQueryParam: "hub.mode" }]
|
|
2336
|
+
}
|
|
2337
|
+
};
|
|
2338
|
+
var getMetaWebhookVerificationResponse = (request, expectedVerifyToken) => {
|
|
2339
|
+
if (request.method !== "GET") return null;
|
|
2340
|
+
let url = new URL(request.url);
|
|
2341
|
+
let mode = url.searchParams.get("hub.mode");
|
|
2342
|
+
let verifyToken = url.searchParams.get("hub.verify_token");
|
|
2343
|
+
let challenge = url.searchParams.get("hub.challenge");
|
|
2344
|
+
if (mode !== "subscribe" || challenge === null) {
|
|
2345
|
+
return {
|
|
2346
|
+
status: 400,
|
|
2347
|
+
headers: { "content-type": "text/plain" },
|
|
2348
|
+
body: "invalid webhook verification request"
|
|
2349
|
+
};
|
|
2350
|
+
}
|
|
2351
|
+
if (expectedVerifyToken !== void 0 && verifyToken !== expectedVerifyToken) {
|
|
2352
|
+
return {
|
|
2353
|
+
status: 403,
|
|
2354
|
+
headers: { "content-type": "text/plain" },
|
|
2355
|
+
body: "invalid verify token"
|
|
2356
|
+
};
|
|
2357
|
+
}
|
|
2358
|
+
return {
|
|
2359
|
+
status: 200,
|
|
2360
|
+
headers: { "content-type": "text/plain" },
|
|
2361
|
+
body: challenge
|
|
2362
|
+
};
|
|
2363
|
+
};
|
|
1806
2364
|
export {
|
|
1807
2365
|
Slate,
|
|
1808
2366
|
SlateAction,
|
|
2367
|
+
SlateActionBuilder,
|
|
2368
|
+
SlateAdapter,
|
|
2369
|
+
SlateAdapterSpec,
|
|
1809
2370
|
SlateAuth,
|
|
1810
2371
|
SlateConfig,
|
|
1811
2372
|
SlateContext,
|
|
@@ -1813,31 +2374,58 @@ export {
|
|
|
1813
2374
|
SlateDefaultPollingIntervalSeconds,
|
|
1814
2375
|
SlateError,
|
|
1815
2376
|
SlateLogger,
|
|
2377
|
+
SlatePublicContext,
|
|
2378
|
+
SlatePublicTool,
|
|
1816
2379
|
SlateSpecification,
|
|
1817
2380
|
SlateTool,
|
|
1818
2381
|
SlateTrigger,
|
|
2382
|
+
adapterSpec,
|
|
1819
2383
|
allOf,
|
|
1820
2384
|
anyOf,
|
|
1821
2385
|
auth,
|
|
1822
2386
|
axios,
|
|
2387
|
+
buildApiServiceError,
|
|
2388
|
+
collectApiErrorDetails,
|
|
1823
2389
|
config,
|
|
2390
|
+
createApiServiceError,
|
|
2391
|
+
createAuthenticatedAxios,
|
|
1824
2392
|
createAxios,
|
|
1825
2393
|
createBase64Attachment,
|
|
2394
|
+
createHmacSignature,
|
|
1826
2395
|
createSlateError,
|
|
1827
2396
|
createTextAttachment,
|
|
1828
2397
|
createUrlAttachment,
|
|
2398
|
+
extractApiErrorMessage,
|
|
2399
|
+
getApiErrorResponse,
|
|
2400
|
+
getApiErrorStatus,
|
|
2401
|
+
getBase64ByteLength,
|
|
1829
2402
|
getCurrentContext,
|
|
2403
|
+
getGraphWebhookValidationResponse,
|
|
2404
|
+
getMetaWebhookVerificationResponse,
|
|
2405
|
+
getOAuthExpiresAtFromExpiresIn,
|
|
2406
|
+
getResponseHeaderValue,
|
|
1830
2407
|
getServiceErrorData,
|
|
2408
|
+
graphWebhookHttp,
|
|
1831
2409
|
inferSlateErrorFromAxios,
|
|
2410
|
+
isApiErrorRecord,
|
|
1832
2411
|
isAxiosErrorLike,
|
|
1833
2412
|
isServiceErrorData,
|
|
1834
2413
|
mapServiceErrorCode,
|
|
1835
2414
|
mapServiceErrorToSlateErrorInput,
|
|
1836
2415
|
mergeScopes,
|
|
2416
|
+
metaWebhookHttp,
|
|
2417
|
+
normalizeOAuthTokenResponse,
|
|
2418
|
+
pickDefined,
|
|
2419
|
+
publicTool,
|
|
2420
|
+
requestAxios,
|
|
2421
|
+
requestAxiosData,
|
|
1837
2422
|
runWithContext,
|
|
1838
2423
|
scopeClause,
|
|
2424
|
+
setIfDefined,
|
|
1839
2425
|
spec,
|
|
2426
|
+
statusLabelForApiError,
|
|
1840
2427
|
tool,
|
|
1841
2428
|
trigger,
|
|
1842
|
-
validateScopes
|
|
2429
|
+
validateScopes,
|
|
2430
|
+
verifyHmacSignature
|
|
1843
2431
|
};
|