@superblocksteam/sdk 1.4.2 → 1.5.0

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.
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyResources = exports.signResource = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const axios_1 = tslib_1.__importDefault(require("axios"));
6
+ const utils_1 = require("../utils");
7
+ async function signResource({ token, branchName, resource, agentUrls, }) {
8
+ const requestResource = {
9
+ branchName: branchName !== null && branchName !== void 0 ? branchName : "main",
10
+ };
11
+ if (resource.api) {
12
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
13
+ requestResource.api = (0, utils_1.getSanitizedApi)(resource.api);
14
+ }
15
+ else {
16
+ requestResource.literal = resource.literal;
17
+ }
18
+ try {
19
+ const resp = await callAgentFallBack({
20
+ baseUrls: agentUrls,
21
+ path: "v1/signature/sign",
22
+ method: "post",
23
+ token: token,
24
+ data: { resource: requestResource },
25
+ });
26
+ return resp.signature;
27
+ }
28
+ catch (e) {
29
+ throw new Error("No agents available to sign the resource");
30
+ }
31
+ }
32
+ exports.signResource = signResource;
33
+ async function verifyResources({ agentUrls, token, branchName, resources, }) {
34
+ try {
35
+ await callAgentFallBack({
36
+ baseUrls: agentUrls,
37
+ path: "v1/signature/verify",
38
+ method: "post",
39
+ token: token,
40
+ data: {
41
+ resources: resources.map((res) => {
42
+ if (res.api) {
43
+ return {
44
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
45
+ api: (0, utils_1.getSanitizedApi)(res.api),
46
+ branchName: branchName !== null && branchName !== void 0 ? branchName : "main",
47
+ };
48
+ }
49
+ return {
50
+ ...res,
51
+ branchName: branchName !== null && branchName !== void 0 ? branchName : "main",
52
+ };
53
+ }),
54
+ },
55
+ });
56
+ }
57
+ catch (e) {
58
+ throw new Error("No agents available to verify the resource");
59
+ }
60
+ }
61
+ exports.verifyResources = verifyResources;
62
+ async function callAgentFallBack({ baseUrls, path, method, token, data, }) {
63
+ for (const baseUrl of baseUrls) {
64
+ try {
65
+ const url = new URL(path, baseUrl);
66
+ const config = {
67
+ url: url.toString(),
68
+ method: method,
69
+ headers: {
70
+ Authorization: "Bearer " + token,
71
+ },
72
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
73
+ data: data,
74
+ };
75
+ const resp = await (0, axios_1.default)(config);
76
+ return resp.data;
77
+ }
78
+ catch (e) { }
79
+ }
80
+ throw new Error("Failed to request ");
81
+ }
@@ -0,0 +1,16 @@
1
+ /// <reference types="ws" />
2
+ import WebSocket from "isomorphic-ws";
3
+ import { ISocketClient, MethodHandlers } from "../types";
4
+ export declare class ISocket<ImplementedMethods, CallableMethods, RequestContext> {
5
+ private readonly ws;
6
+ private readonly requestHandlers;
7
+ private readonly responseHandler;
8
+ private peerAuthorization?;
9
+ private nxtRequestId;
10
+ constructor(ws: WebSocket, requestHandlers: MethodHandlers<ImplementedMethods, CallableMethods, RequestContext>);
11
+ request<Params, Result>(method: string, params: Params, authorization?: string): Promise<Result>;
12
+ private respond;
13
+ private respondError;
14
+ close(): void;
15
+ }
16
+ export declare function createISocketClient<CallableMethods, ImplementedMethods, RequestContext>(socket: ISocket<ImplementedMethods, CallableMethods, RequestContext>): ISocketClient<CallableMethods>;
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createISocketClient = exports.ISocket = void 0;
4
+ class ISocket {
5
+ constructor(ws, requestHandlers) {
6
+ this.responseHandler = {};
7
+ this.ws = ws;
8
+ this.requestHandlers = requestHandlers;
9
+ this.nxtRequestId = 0;
10
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
11
+ // @ts-ignore
12
+ this.ws.addEventListener("message", async (event) => {
13
+ const eventData = JSON.parse(event.data.toString());
14
+ if (eventData.request) {
15
+ // Split the method string into parts
16
+ const parts = eventData.request.method.split(".");
17
+ let handlers = this.requestHandlers;
18
+ for (const part of parts) {
19
+ // @ts-ignore
20
+ handlers = handlers[part];
21
+ if (!handlers) {
22
+ return await this.respondError(eventData.request.id, {
23
+ code: 2,
24
+ message: `unknown method ${eventData.request.method}`,
25
+ });
26
+ }
27
+ }
28
+ if (!Array.isArray(handlers)) {
29
+ return await this.respondError(eventData.request.id, {
30
+ code: 2,
31
+ message: "unknown method",
32
+ });
33
+ }
34
+ if (eventData.request.setAuthorization) {
35
+ this.peerAuthorization = eventData.request.setAuthorization;
36
+ }
37
+ const middlewareHandlers = handlers.slice(0, -1);
38
+ const handler = handlers[handlers.length - 1];
39
+ const reqCtx = {};
40
+ let response;
41
+ // TODO(george): maybe we should not create a new client for each request
42
+ const client = createISocketClient(this);
43
+ try {
44
+ for (const middlewareHandler of middlewareHandlers) {
45
+ await middlewareHandler(eventData.request.payload, this.peerAuthorization, client, reqCtx);
46
+ }
47
+ response = await handler(eventData.request.payload, client, reqCtx);
48
+ }
49
+ catch (error) {
50
+ return await this.respondError(eventData.request.id, {
51
+ code: 3,
52
+ message: error.toString(),
53
+ });
54
+ }
55
+ await this.respond(eventData.request.id, response);
56
+ }
57
+ else if (eventData.response && eventData.response.id) {
58
+ if (!this.responseHandler[eventData.response.id]) {
59
+ return;
60
+ }
61
+ if (eventData.response.error) {
62
+ this.responseHandler[eventData.response.id].reject(eventData.response.error);
63
+ }
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ this.responseHandler[eventData.response.id].resolve(eventData.response.payload);
66
+ delete this.responseHandler[eventData.response.id];
67
+ }
68
+ else {
69
+ return await this.respondError(-1, {
70
+ code: 3,
71
+ message: "unknown request id",
72
+ });
73
+ }
74
+ });
75
+ }
76
+ request(method, params, authorization) {
77
+ return new Promise((resolve, reject) => {
78
+ const requestId = ++this.nxtRequestId;
79
+ this.responseHandler[requestId] = {
80
+ resolve: (result) => resolve(result),
81
+ reject: (error) => reject(error),
82
+ };
83
+ const toSend = {
84
+ request: {
85
+ method,
86
+ payload: params,
87
+ id: requestId,
88
+ setAuthorization: authorization,
89
+ },
90
+ };
91
+ this.ws.send(JSON.stringify(toSend));
92
+ });
93
+ }
94
+ async respond(requestId, result) {
95
+ const toSend = {
96
+ response: {
97
+ payload: result,
98
+ id: requestId,
99
+ error: null,
100
+ },
101
+ };
102
+ return this.ws.send(JSON.stringify(toSend));
103
+ }
104
+ async respondError(requestId, error) {
105
+ const toSend = {
106
+ response: {
107
+ payload: null,
108
+ id: requestId,
109
+ error: error,
110
+ },
111
+ };
112
+ return this.ws.send(JSON.stringify(toSend));
113
+ }
114
+ close() {
115
+ this.ws.close();
116
+ }
117
+ }
118
+ exports.ISocket = ISocket;
119
+ const proxyTarget = Object.freeze(() => {
120
+ /* return nothing */
121
+ });
122
+ function createIsocketProxy(socket,
123
+ // if path is undefined, it means the current object is the root object
124
+ path) {
125
+ return new Proxy(proxyTarget, {
126
+ get(_target, prop) {
127
+ const childPath = path ? `${path}.${prop}` : prop;
128
+ // sometimes, when `createISocketClient` is called from an async function, JS will implicitly call the `then` method on
129
+ // its return value, because promises can be arbitrarily nested
130
+ // so return undefined for the `then` method to avoid this
131
+ if (childPath === "then") {
132
+ return undefined;
133
+ }
134
+ return createIsocketProxy(socket, childPath);
135
+ },
136
+ apply(_target, _thisArg, args) {
137
+ if (path === undefined) {
138
+ throw new Error("The root object is not callable");
139
+ }
140
+ if (path.endsWith(".apply") &&
141
+ args.length === 2 &&
142
+ Array.isArray(args[1])) {
143
+ path = path.slice(0, -".apply".length);
144
+ args = args[1];
145
+ }
146
+ return socket.request(path, args[0]);
147
+ },
148
+ });
149
+ }
150
+ function createISocketClient(socket) {
151
+ return {
152
+ close: () => socket.close(),
153
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment
154
+ call: createIsocketProxy(socket, undefined),
155
+ };
156
+ }
157
+ exports.createISocketClient = createISocketClient;
@@ -0,0 +1,111 @@
1
+ export interface UserMeDto {
2
+ user: User;
3
+ organizations: Organization[];
4
+ agents: Agent[];
5
+ flagBootstrap: FlagBootstrap;
6
+ }
7
+ export interface FlagBootstrap {
8
+ "ui.enable-resource-signing"?: boolean;
9
+ }
10
+ export type User = {
11
+ id: string;
12
+ email: string;
13
+ currentOrganizationId: string;
14
+ organizationIds: string[];
15
+ username: string;
16
+ name: string;
17
+ anonymousId: string;
18
+ isAnonymous: boolean;
19
+ isAdmin: boolean;
20
+ metadata: Record<string, unknown>;
21
+ };
22
+ export interface Organization {
23
+ id: string;
24
+ name: string;
25
+ displayName: string;
26
+ agents?: Agent[];
27
+ apiKey: string;
28
+ agentType: AgentType;
29
+ minExternalAgentVersion: string;
30
+ profiles?: Profile[];
31
+ }
32
+ export type Agent = {
33
+ id: string;
34
+ key: string;
35
+ environment: string;
36
+ status: AgentStatus;
37
+ version: string;
38
+ versionExternal: string;
39
+ url: string;
40
+ type: AgentType;
41
+ updated: Date;
42
+ created: Date;
43
+ tags: AgentTags;
44
+ verificationKeyIds?: null | string[];
45
+ signingKeyId?: null | string;
46
+ };
47
+ export declare enum AgentStatus {
48
+ ACTIVE = "Active",
49
+ DISCONNECTED = "Disconnected",
50
+ BROWSER_UNREACHABLE = "Browser Unreachable",
51
+ PENDING_REGISTRATION = "Pending Registration",
52
+ STALE = "Stale"
53
+ }
54
+ export declare enum AgentType {
55
+ MULTITENANT = 0,
56
+ DEDICATED = 1,
57
+ ONPREMISE = 2
58
+ }
59
+ export type AgentTags = Record<string, string[]>;
60
+ export declare class Profile {
61
+ id: string;
62
+ key: string;
63
+ displayName: string;
64
+ description: string;
65
+ type: ProfileType;
66
+ constructor({ id, key, displayName, description, type, }: {
67
+ id: string;
68
+ key: string;
69
+ displayName: string;
70
+ description: string;
71
+ type: ProfileType;
72
+ });
73
+ }
74
+ export declare enum ProfileType {
75
+ RESERVED = "RESERVED",
76
+ CUSTOM = "CUSTOM"
77
+ }
78
+ export type Api = {
79
+ metadata: {
80
+ name: string;
81
+ id: string;
82
+ organization: string;
83
+ timestamps?: {
84
+ created: string;
85
+ updated: string;
86
+ deactivated: boolean;
87
+ };
88
+ creator?: {
89
+ id: string;
90
+ name: string;
91
+ };
92
+ folder?: string;
93
+ };
94
+ blocks?: any[];
95
+ trigger: any;
96
+ signature?: Signature;
97
+ };
98
+ /** A signature, as produced by the agent. */
99
+ export interface Signature {
100
+ /** The id of the key used to sign the data. */
101
+ keyId: string;
102
+ /** The actual signature, in base64. */
103
+ data: string;
104
+ }
105
+ export interface RemoteCommitDto {
106
+ commitId: string;
107
+ remoteCommitId: string;
108
+ remoteCommitDate: Date;
109
+ branchName: string;
110
+ repositoryId: string;
111
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProfileType = exports.Profile = exports.AgentType = exports.AgentStatus = void 0;
4
+ var AgentStatus;
5
+ (function (AgentStatus) {
6
+ AgentStatus["ACTIVE"] = "Active";
7
+ AgentStatus["DISCONNECTED"] = "Disconnected";
8
+ AgentStatus["BROWSER_UNREACHABLE"] = "Browser Unreachable";
9
+ // TODO: remove PENDING_REGISTRATION after the DB migration
10
+ AgentStatus["PENDING_REGISTRATION"] = "Pending Registration";
11
+ AgentStatus["STALE"] = "Stale";
12
+ })(AgentStatus || (exports.AgentStatus = AgentStatus = {}));
13
+ var AgentType;
14
+ (function (AgentType) {
15
+ AgentType[AgentType["MULTITENANT"] = 0] = "MULTITENANT";
16
+ AgentType[AgentType["DEDICATED"] = 1] = "DEDICATED";
17
+ AgentType[AgentType["ONPREMISE"] = 2] = "ONPREMISE";
18
+ })(AgentType || (exports.AgentType = AgentType = {}));
19
+ class Profile {
20
+ constructor({ id, key, displayName, description, type, }) {
21
+ this.id = id;
22
+ this.key = key;
23
+ this.displayName = displayName;
24
+ this.description = description;
25
+ this.type = type;
26
+ }
27
+ }
28
+ exports.Profile = Profile;
29
+ var ProfileType;
30
+ (function (ProfileType) {
31
+ ProfileType["RESERVED"] = "RESERVED";
32
+ ProfileType["CUSTOM"] = "CUSTOM";
33
+ })(ProfileType || (exports.ProfileType = ProfileType = {}));
@@ -0,0 +1,4 @@
1
+ export * from "./common";
2
+ export * from "./socket";
3
+ export * from "./plugin";
4
+ export * from "./signing";
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./common"), exports);
5
+ tslib_1.__exportStar(require("./socket"), exports);
6
+ tslib_1.__exportStar(require("./plugin"), exports);
7
+ tslib_1.__exportStar(require("./signing"), exports);
@@ -0,0 +1,2 @@
1
+ export declare const transcribeAudioToTextTranslateToEnglishTruthyValues: (string | boolean)[];
2
+ export declare const OpenAiPluginId = "openai";
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenAiPluginId = exports.transcribeAudioToTextTranslateToEnglishTruthyValues = void 0;
4
+ exports.transcribeAudioToTextTranslateToEnglishTruthyValues = [
5
+ "checked",
6
+ "true",
7
+ true,
8
+ ];
9
+ exports.OpenAiPluginId = "openai";
@@ -0,0 +1,51 @@
1
+ import { Api as ApiPb, Signature } from "./common";
2
+ export type SignatureResponse = {
3
+ signature: Signature;
4
+ };
5
+ export type ApiResource = {
6
+ api: ApiPb;
7
+ };
8
+ export type GenericResource = {
9
+ literal: {
10
+ data: any;
11
+ signature?: Signature;
12
+ };
13
+ };
14
+ interface PageHash {
15
+ /** The version of the page DSL. */
16
+ version: number;
17
+ /** The SHA-256 hash of the page DSL (i.e. `page.layouts[0].dsl`), in base64. */
18
+ hash: string;
19
+ }
20
+ export interface ApplicationSettingsHashes {
21
+ /** The SHA-256 hash of all custom components related properties from settings, in base64. */
22
+ components: string;
23
+ /** The SHA-256 hash of settings without the custom components related properties, in base64. */
24
+ rest: string;
25
+ }
26
+ export interface ApplicationSignatureTree {
27
+ /** The version of the signature tree. */
28
+ v: 1;
29
+ settings: ApplicationSettingsHashes;
30
+ page: PageHash;
31
+ }
32
+ export interface ApplicationSignatureTreeSigned {
33
+ /** The SHA-256 hash of `root`, in base64. */
34
+ signature: Signature;
35
+ root: ApplicationSignatureTree;
36
+ }
37
+ export type AppToSign = {
38
+ rootHash: string;
39
+ };
40
+ export type AppToVerify = {
41
+ rootHash: string;
42
+ signature?: Signature;
43
+ };
44
+ export type ApiToSign = {
45
+ apiPb: ApiPb;
46
+ };
47
+ export type ApiToVerify = {
48
+ apiPb: ApiPb;
49
+ signature?: Signature;
50
+ };
51
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ export type MethodHandler<Params, Result, PeerMethods, RequestContext> = (params: Params, peer: ISocketClient<PeerMethods>, ctx: RequestContext) => Promise<Result>;
2
+ export type MiddlewareHandler<Params, PeerMethods, RequestContext> = (params: Params, peerAuthorization: string | undefined, peer: ISocketClient<PeerMethods>, ctx: RequestContext) => Promise<void>;
3
+ export type MethodHandlers<Methods, PeerMethods, RequestContext> = {
4
+ [Key in keyof Methods]: Methods[Key] extends (params: infer Params) => Promise<infer Result> ? [
5
+ ...middlewareHandlers: MiddlewareHandler<Params, PeerMethods, RequestContext>[],
6
+ handler: MethodHandler<Params, Result, PeerMethods, RequestContext>
7
+ ] : Methods[Key] extends Record<string, unknown> ? MethodHandlers<Methods[Key], PeerMethods, RequestContext> : never;
8
+ };
9
+ type ISocketClientMethodCall<Methods> = {
10
+ [Key in keyof Methods]: Methods[Key] extends (params: infer P) => Promise<infer R> ? (params: P) => Promise<R> : Methods[Key] extends Record<string, unknown> ? ISocketClientMethodCall<Methods[Key]> : never;
11
+ };
12
+ export type ISocketClient<Methods> = {
13
+ close: () => void;
14
+ call: ISocketClientMethodCall<Methods>;
15
+ };
16
+ export type MethodSchema<Params, Response> = (params: Params) => Promise<Response>;
17
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ import { Agent, AgentType, Api } from "./types";
2
+ export declare function getAgentUrls(agents: Agent[], agentType: AgentType): string[];
3
+ export declare const sanitizeV2RequestBody: (apiBody: Record<string, unknown>) => Record<string, unknown>;
4
+ export declare const getSanitizedApi: (api: Api) => any;
package/dist/utils.js ADDED
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSanitizedApi = exports.sanitizeV2RequestBody = exports.getAgentUrls = void 0;
4
+ const types_1 = require("./types");
5
+ function getAgentUrls(agents, agentType) {
6
+ const filtered = agents.filter((a) => a.type === agentType && a.status === types_1.AgentStatus.ACTIVE);
7
+ return filtered.map((f) => f.url);
8
+ }
9
+ exports.getAgentUrls = getAgentUrls;
10
+ const sanitizeV2RequestBody = (apiBody) => {
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ const traverseJSON = (obj) => {
13
+ for (const key in obj) {
14
+ if (key === "step" && obj.step[types_1.OpenAiPluginId]) {
15
+ const value = obj.step[types_1.OpenAiPluginId].transcribeAudioToTextTranslateToEnglish;
16
+ obj.step[types_1.OpenAiPluginId].transcribeAudioToTextTranslateToEnglish =
17
+ types_1.transcribeAudioToTextTranslateToEnglishTruthyValues.includes(value);
18
+ }
19
+ else if (typeof obj[key] === "object") {
20
+ (0, exports.sanitizeV2RequestBody)(obj[key]);
21
+ }
22
+ }
23
+ };
24
+ traverseJSON(apiBody);
25
+ return apiBody;
26
+ };
27
+ exports.sanitizeV2RequestBody = sanitizeV2RequestBody;
28
+ const getSanitizedApi = (api) => {
29
+ var _a, _b;
30
+ const sanitizedBlocks = (_b = ((_a = api.blocks) !== null && _a !== void 0 ? _a : [])) === null || _b === void 0 ? void 0 : _b.map((block) => (0, exports.sanitizeV2RequestBody)(block));
31
+ return {
32
+ ...api,
33
+ blocks: sanitizedBlocks,
34
+ };
35
+ };
36
+ exports.getSanitizedApi = getSanitizedApi;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superblocksteam/sdk",
3
- "version": "1.4.2",
3
+ "version": "1.5.0",
4
4
  "description": "Superblocks JS SDK",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -22,6 +22,7 @@
22
22
  },
23
23
  "license": "Superblocks Community Software License",
24
24
  "devDependencies": {
25
+ "@types/ws": "^8.5.10",
25
26
  "@typescript-eslint/eslint-plugin": "^5.60.1",
26
27
  "@typescript-eslint/parser": "^5.60.1",
27
28
  "eslint": "^8.48.0",
@@ -30,8 +31,9 @@
30
31
  "typescript": "^5.1.3"
31
32
  },
32
33
  "dependencies": {
33
- "@superblocksteam/util": "1.4.2",
34
- "axios": "^1.3.5"
34
+ "@superblocksteam/util": "1.5.0",
35
+ "axios": "^1.3.5",
36
+ "isomorphic-ws": "^5.0.0"
35
37
  },
36
38
  "homepage": "https://www.superblocks.com",
37
39
  "engines": {