@superblocksteam/sdk 1.4.1 → 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.
- package/.eslintrc.json +3 -0
- package/dist/client.d.ts +21 -14
- package/dist/client.js +198 -79
- package/dist/flag.d.ts +2 -0
- package/dist/flag.js +8 -0
- package/dist/sdk.d.ts +8 -7
- package/dist/sdk.js +16 -8
- package/dist/socket/handlers.d.ts +105 -0
- package/dist/socket/handlers.js +85 -0
- package/dist/socket/index.d.ts +27 -0
- package/dist/socket/index.js +69 -0
- package/dist/socket/signing.d.ts +13 -0
- package/dist/socket/signing.js +81 -0
- package/dist/socket/socket.d.ts +16 -0
- package/dist/socket/socket.js +157 -0
- package/dist/types/common.d.ts +111 -0
- package/dist/types/common.js +33 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +7 -0
- package/dist/types/plugin.d.ts +2 -0
- package/dist/types/plugin.js +9 -0
- package/dist/types/signing.d.ts +51 -0
- package/dist/types/signing.js +2 -0
- package/dist/types/socket.d.ts +17 -0
- package/dist/types/socket.js +2 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +36 -0
- package/package.json +5 -3
- package/src/client.ts +258 -83
- package/src/flag.ts +5 -0
- package/src/sdk.ts +48 -14
- package/src/socket/handlers.ts +228 -0
- package/src/socket/index.ts +164 -0
- package/src/socket/signing.ts +113 -0
- package/src/socket/socket.ts +253 -0
- package/src/types/common.ts +138 -0
- package/src/types/index.ts +4 -0
- package/src/types/plugin.ts +7 -0
- package/src/types/signing.ts +61 -0
- package/src/types/socket.ts +48 -0
- package/src/utils.ts +45 -0
- package/tsconfig.json +3 -1
package/dist/sdk.js
CHANGED
|
@@ -6,14 +6,17 @@ const client_1 = require("./client");
|
|
|
6
6
|
// Exporting here instead of index.ts because only sdk.ts is exposed outside in package.json
|
|
7
7
|
tslib_1.__exportStar(require("./errors"), exports);
|
|
8
8
|
class SuperblocksSdk {
|
|
9
|
-
constructor(accessToken, superblocksBaseUrl) {
|
|
9
|
+
constructor(accessToken, superblocksBaseUrl, cliVersion) {
|
|
10
10
|
this.token = "";
|
|
11
11
|
this.superblocksBaseUrl = "";
|
|
12
|
+
this.cliVersion = "";
|
|
12
13
|
this.token = accessToken;
|
|
13
14
|
this.superblocksBaseUrl = superblocksBaseUrl;
|
|
15
|
+
this.cliVersion = cliVersion;
|
|
14
16
|
}
|
|
15
17
|
async fetchApplication({ applicationId, branch, headers = {}, viewMode = "export-live", }) {
|
|
16
18
|
return (0, client_1.fetchApplication)({
|
|
19
|
+
cliVersion: this.cliVersion,
|
|
17
20
|
applicationId,
|
|
18
21
|
branch,
|
|
19
22
|
token: this.token,
|
|
@@ -24,6 +27,7 @@ class SuperblocksSdk {
|
|
|
24
27
|
}
|
|
25
28
|
async fetchApplicationBranches(applicationId, headers = {}) {
|
|
26
29
|
return (0, client_1.fetchApplicationBranches)({
|
|
30
|
+
cliVersion: this.cliVersion,
|
|
27
31
|
applicationId,
|
|
28
32
|
token: this.token,
|
|
29
33
|
superblocksBaseUrl: this.superblocksBaseUrl,
|
|
@@ -32,6 +36,7 @@ class SuperblocksSdk {
|
|
|
32
36
|
}
|
|
33
37
|
async fetchApplicationWithComponents({ applicationId, branch, headers = {}, viewMode = "export-live", }) {
|
|
34
38
|
return (0, client_1.fetchApplicationWithComponents)({
|
|
39
|
+
cliVersion: this.cliVersion,
|
|
35
40
|
applicationId,
|
|
36
41
|
branch,
|
|
37
42
|
token: this.token,
|
|
@@ -41,22 +46,23 @@ class SuperblocksSdk {
|
|
|
41
46
|
});
|
|
42
47
|
}
|
|
43
48
|
async fetchApplications(headers) {
|
|
44
|
-
return (0, client_1.fetchApplications)(this.token, this.superblocksBaseUrl, headers);
|
|
49
|
+
return (0, client_1.fetchApplications)(this.cliVersion, this.token, this.superblocksBaseUrl, headers);
|
|
45
50
|
}
|
|
46
|
-
async fetchApi(apiId, viewMode = "export-live") {
|
|
47
|
-
return (0, client_1.fetchApi)(apiId, this.token, this.superblocksBaseUrl, viewMode);
|
|
51
|
+
async fetchApi(apiId, viewMode = "export-live", branch) {
|
|
52
|
+
return (0, client_1.fetchApi)(this.cliVersion, apiId, this.token, this.superblocksBaseUrl, viewMode, branch);
|
|
48
53
|
}
|
|
49
54
|
async fetchApis() {
|
|
50
|
-
return (0, client_1.fetchApis)(this.token, this.superblocksBaseUrl);
|
|
55
|
+
return (0, client_1.fetchApis)(this.cliVersion, this.token, this.superblocksBaseUrl);
|
|
51
56
|
}
|
|
52
57
|
async validateGitSetup(resourceId, resourceType, event, localGitRepoState, injectedHeaders) {
|
|
53
|
-
return (0, client_1.validateGitSetup)(resourceId, resourceType, event, localGitRepoState, this.token, this.superblocksBaseUrl, injectedHeaders);
|
|
58
|
+
return (0, client_1.validateGitSetup)(this.cliVersion, resourceId, resourceType, event, localGitRepoState, this.token, this.superblocksBaseUrl, injectedHeaders);
|
|
54
59
|
}
|
|
55
60
|
async registerComponents(applicationId, componentConfigs, branch, injectedHeaders) {
|
|
56
|
-
return (0, client_1.registerComponents)(applicationId, componentConfigs, this.token, this.superblocksBaseUrl, branch, injectedHeaders);
|
|
61
|
+
return (0, client_1.registerComponents)(this.cliVersion, applicationId, componentConfigs, this.token, this.superblocksBaseUrl, branch, injectedHeaders);
|
|
57
62
|
}
|
|
58
63
|
async uploadComponents(applicationId, componentConfigs, files, branch) {
|
|
59
64
|
return (0, client_1.uploadComponents)({
|
|
65
|
+
cliVersion: this.cliVersion,
|
|
60
66
|
applicationId,
|
|
61
67
|
componentConfigs,
|
|
62
68
|
files,
|
|
@@ -66,10 +72,11 @@ class SuperblocksSdk {
|
|
|
66
72
|
});
|
|
67
73
|
}
|
|
68
74
|
async fetchCurrentUser() {
|
|
69
|
-
return (0, client_1.fetchCurrentUser)(this.token, this.superblocksBaseUrl);
|
|
75
|
+
return (0, client_1.fetchCurrentUser)(this.cliVersion, this.token, this.superblocksBaseUrl);
|
|
70
76
|
}
|
|
71
77
|
async pushApplication({ applicationId, applicationConfig, branch, headers = {}, }) {
|
|
72
78
|
return (0, client_1.pushApplication)({
|
|
79
|
+
cliVersion: this.cliVersion,
|
|
73
80
|
applicationId,
|
|
74
81
|
token: this.token,
|
|
75
82
|
superblocksBaseUrl: this.superblocksBaseUrl,
|
|
@@ -80,6 +87,7 @@ class SuperblocksSdk {
|
|
|
80
87
|
}
|
|
81
88
|
async pushApi({ apiId, apiConfig, branch, headers = {}, }) {
|
|
82
89
|
return (0, client_1.pushApi)({
|
|
90
|
+
cliVersion: this.cliVersion,
|
|
83
91
|
apiId,
|
|
84
92
|
apiConfig,
|
|
85
93
|
token: this.token,
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ApiToSign, ApiToVerify, AppToSign, AppToVerify, MethodHandlers, RemoteCommitDto, Signature } from "../types";
|
|
2
|
+
type MethodSchema<Params, Response> = (params: Params) => Promise<Response>;
|
|
3
|
+
export interface ClientMethods {
|
|
4
|
+
v1: {
|
|
5
|
+
signing: {
|
|
6
|
+
signApplication: MethodSchema<{
|
|
7
|
+
branchName: string;
|
|
8
|
+
toSign: AppToSign;
|
|
9
|
+
}, {
|
|
10
|
+
signature: Signature;
|
|
11
|
+
}>;
|
|
12
|
+
signApis: MethodSchema<{
|
|
13
|
+
branchName: string;
|
|
14
|
+
toSign: ApiToSign[];
|
|
15
|
+
}, {
|
|
16
|
+
signatures: Signature[];
|
|
17
|
+
}>;
|
|
18
|
+
verifyApplication: MethodSchema<{
|
|
19
|
+
branchName: string;
|
|
20
|
+
toVerify: AppToVerify;
|
|
21
|
+
}, {
|
|
22
|
+
ok: boolean;
|
|
23
|
+
}>;
|
|
24
|
+
verifyApi: MethodSchema<{
|
|
25
|
+
branchName: string;
|
|
26
|
+
toVerify: ApiToVerify[];
|
|
27
|
+
}, {
|
|
28
|
+
ok: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
type ServerMethodSchema<Params, Response> = MethodSchema<Params, ResponseDto<Response>>;
|
|
34
|
+
type ResponseDto<T> = {
|
|
35
|
+
responseMeta: ResponseMeta;
|
|
36
|
+
data: T;
|
|
37
|
+
};
|
|
38
|
+
export type ResponseMeta = {
|
|
39
|
+
status: number;
|
|
40
|
+
success: boolean;
|
|
41
|
+
error?: APIResponseError;
|
|
42
|
+
};
|
|
43
|
+
type APIResponseError = {
|
|
44
|
+
code: number;
|
|
45
|
+
message: string;
|
|
46
|
+
};
|
|
47
|
+
export interface ServerMethods {
|
|
48
|
+
v1: {
|
|
49
|
+
echo: MethodSchema<{
|
|
50
|
+
message: string;
|
|
51
|
+
}, {
|
|
52
|
+
message: string;
|
|
53
|
+
}>;
|
|
54
|
+
public: {
|
|
55
|
+
application: {
|
|
56
|
+
component: {
|
|
57
|
+
register: ServerMethodSchema<{
|
|
58
|
+
applicationId: string;
|
|
59
|
+
branchName: string;
|
|
60
|
+
cliVersion: string;
|
|
61
|
+
componentEvent: string;
|
|
62
|
+
components: Record<string, unknown>;
|
|
63
|
+
}, {
|
|
64
|
+
success: boolean;
|
|
65
|
+
}>;
|
|
66
|
+
update: ServerMethodSchema<{
|
|
67
|
+
applicationId: string;
|
|
68
|
+
branchName?: string;
|
|
69
|
+
srcFiles: string[];
|
|
70
|
+
buildFiles: string[];
|
|
71
|
+
registeredComponents: Record<string, unknown>;
|
|
72
|
+
cliVersion: string | undefined;
|
|
73
|
+
componentBaseUrl: string;
|
|
74
|
+
signingRequired: boolean;
|
|
75
|
+
}, {
|
|
76
|
+
success: boolean;
|
|
77
|
+
}>;
|
|
78
|
+
};
|
|
79
|
+
pushCommit: ServerMethodSchema<{
|
|
80
|
+
applicationId: string;
|
|
81
|
+
branchName: string;
|
|
82
|
+
commitId: string;
|
|
83
|
+
commitMessage: string;
|
|
84
|
+
application: Record<string, unknown>;
|
|
85
|
+
page: Record<string, unknown>;
|
|
86
|
+
apis: Record<string, unknown>[];
|
|
87
|
+
}, RemoteCommitDto>;
|
|
88
|
+
};
|
|
89
|
+
api: {
|
|
90
|
+
pushCommit: ServerMethodSchema<{
|
|
91
|
+
apiId: string;
|
|
92
|
+
branchName: string;
|
|
93
|
+
commitId: string;
|
|
94
|
+
commitMessage: string;
|
|
95
|
+
apiPb: Record<string, unknown>;
|
|
96
|
+
}, RemoteCommitDto>;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export declare function createRequestHandlers({ agentUrls, token, }: {
|
|
102
|
+
token: string;
|
|
103
|
+
agentUrls: string[];
|
|
104
|
+
}): MethodHandlers<ClientMethods, ServerMethods, unknown>;
|
|
105
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRequestHandlers = void 0;
|
|
4
|
+
const signing_1 = require("./signing");
|
|
5
|
+
function createRequestHandlers({ agentUrls, token, }) {
|
|
6
|
+
const requestHandlers = {
|
|
7
|
+
v1: {
|
|
8
|
+
signing: {
|
|
9
|
+
signApplication: [
|
|
10
|
+
async ({ branchName, toSign, }) => {
|
|
11
|
+
const signature = await (0, signing_1.signResource)({
|
|
12
|
+
agentUrls,
|
|
13
|
+
token: token,
|
|
14
|
+
branchName,
|
|
15
|
+
resource: {
|
|
16
|
+
literal: {
|
|
17
|
+
data: toSign.rootHash,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
return { signature: signature };
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
signApis: [
|
|
25
|
+
async ({ branchName, toSign, }) => {
|
|
26
|
+
const signatures = [];
|
|
27
|
+
for (const { apiPb } of toSign) {
|
|
28
|
+
const signature = await (0, signing_1.signResource)({
|
|
29
|
+
agentUrls,
|
|
30
|
+
token: token,
|
|
31
|
+
branchName,
|
|
32
|
+
resource: { api: apiPb },
|
|
33
|
+
});
|
|
34
|
+
signatures.push(signature);
|
|
35
|
+
}
|
|
36
|
+
return { signatures };
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
verifyApplication: [
|
|
40
|
+
async ({ branchName, toVerify, }) => {
|
|
41
|
+
try {
|
|
42
|
+
await (0, signing_1.verifyResources)({
|
|
43
|
+
agentUrls,
|
|
44
|
+
token,
|
|
45
|
+
branchName,
|
|
46
|
+
resources: [
|
|
47
|
+
{
|
|
48
|
+
literal: {
|
|
49
|
+
data: toVerify.rootHash,
|
|
50
|
+
signature: toVerify.signature,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
return { ok: true };
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return { ok: false };
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
verifyApi: [
|
|
63
|
+
async ({ branchName, toVerify, }) => {
|
|
64
|
+
try {
|
|
65
|
+
await (0, signing_1.verifyResources)({
|
|
66
|
+
agentUrls,
|
|
67
|
+
token,
|
|
68
|
+
branchName,
|
|
69
|
+
resources: toVerify.map(({ apiPb }) => ({
|
|
70
|
+
api: apiPb,
|
|
71
|
+
})),
|
|
72
|
+
});
|
|
73
|
+
return { ok: true };
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return { ok: false };
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
return requestHandlers;
|
|
84
|
+
}
|
|
85
|
+
exports.createRequestHandlers = createRequestHandlers;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/// <reference types="ws" />
|
|
2
|
+
import WebSocket from "isomorphic-ws";
|
|
3
|
+
import { ServerMethods } from "./handlers";
|
|
4
|
+
export type StdISocketRPCClient = ISocketClient<ServerMethods>;
|
|
5
|
+
export declare function connectToISocketRPCServer({ superblocksBaseUrl, agentUrls, token, }: {
|
|
6
|
+
superblocksBaseUrl: string;
|
|
7
|
+
agentUrls: string[];
|
|
8
|
+
token: string;
|
|
9
|
+
}): Promise<StdISocketRPCClient>;
|
|
10
|
+
export declare function connectISocket<CallableMethods, ImplementedMethods, RequestContext = never>(wsUrl: string, authorization: string | undefined, requestHandlers: MethodHandlers<ImplementedMethods, CallableMethods, RequestContext>): Promise<ISocketClient<CallableMethods>>;
|
|
11
|
+
export declare function connectWebSocket(wsUrl: string): Promise<WebSocket>;
|
|
12
|
+
type MethodHandler<Params, Result, PeerMethods, RequestContext> = (params: Params, peer: ISocketClient<PeerMethods>, ctx: RequestContext) => Promise<Result>;
|
|
13
|
+
type MiddlewareHandler<Params, PeerMethods, RequestContext> = (params: Params, peerAuthorization: string | undefined, peer: ISocketClient<PeerMethods>, ctx: RequestContext) => Promise<void>;
|
|
14
|
+
type MethodHandlers<Methods, PeerMethods, RequestContext> = {
|
|
15
|
+
[Key in keyof Methods]: Methods[Key] extends (params: infer Params) => Promise<infer Result> ? [
|
|
16
|
+
...middlewareHandlers: MiddlewareHandler<Params, PeerMethods, RequestContext>[],
|
|
17
|
+
handler: MethodHandler<Params, Result, PeerMethods, RequestContext>
|
|
18
|
+
] : Methods[Key] extends Record<string, unknown> ? MethodHandlers<Methods[Key], PeerMethods, RequestContext> : never;
|
|
19
|
+
};
|
|
20
|
+
type ISocketClientMethodCall<Methods> = {
|
|
21
|
+
[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;
|
|
22
|
+
};
|
|
23
|
+
type ISocketClient<Methods> = {
|
|
24
|
+
close: () => void;
|
|
25
|
+
call: ISocketClientMethodCall<Methods>;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.connectWebSocket = exports.connectISocket = exports.connectToISocketRPCServer = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const isomorphic_ws_1 = tslib_1.__importDefault(require("isomorphic-ws"));
|
|
6
|
+
const handlers_1 = require("./handlers");
|
|
7
|
+
const socket_1 = require("./socket");
|
|
8
|
+
async function connectToISocketRPCServer({ superblocksBaseUrl, agentUrls, token, }) {
|
|
9
|
+
const requestHandlers = (0, handlers_1.createRequestHandlers)({
|
|
10
|
+
agentUrls,
|
|
11
|
+
token,
|
|
12
|
+
});
|
|
13
|
+
const authorization = `Bearer ${token}`;
|
|
14
|
+
const wsUrl = new URL("api/v1/rpc-ws", superblocksBaseUrl);
|
|
15
|
+
if (wsUrl.protocol === "http:") {
|
|
16
|
+
wsUrl.protocol = "ws:";
|
|
17
|
+
}
|
|
18
|
+
else if (wsUrl.protocol === "https:") {
|
|
19
|
+
wsUrl.protocol = "wss:";
|
|
20
|
+
}
|
|
21
|
+
if (wsUrl.host === "localhost:3000") {
|
|
22
|
+
wsUrl.host = "127.0.0.1:8080";
|
|
23
|
+
}
|
|
24
|
+
else if (wsUrl.hostname === "localhost") {
|
|
25
|
+
wsUrl.hostname = "127.0.0.1";
|
|
26
|
+
}
|
|
27
|
+
return await connectISocket(wsUrl.href, authorization, requestHandlers);
|
|
28
|
+
}
|
|
29
|
+
exports.connectToISocketRPCServer = connectToISocketRPCServer;
|
|
30
|
+
// a subclass of ISocket that sends an auth token on the first request
|
|
31
|
+
// this is useful for client-side sockets that need to authenticate
|
|
32
|
+
// TODO(george): if we start using this for long-lived connections, we should add a way to refresh the token
|
|
33
|
+
class ISocketWithClientAuth extends socket_1.ISocket {
|
|
34
|
+
constructor(ws, authorization, requestHandlers) {
|
|
35
|
+
super(ws, requestHandlers);
|
|
36
|
+
this.hasSentAuth = false;
|
|
37
|
+
this.authorization = authorization;
|
|
38
|
+
}
|
|
39
|
+
// override `request` from the base class to send `authorization` when appropriate
|
|
40
|
+
async request(method, params) {
|
|
41
|
+
// only send `authorization` on the first request
|
|
42
|
+
const authorization = this.hasSentAuth ? undefined : this.authorization;
|
|
43
|
+
const result = await super.request(method, params, authorization);
|
|
44
|
+
this.hasSentAuth = true;
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function connectISocket(wsUrl, authorization, requestHandlers) {
|
|
49
|
+
const ws = await connectWebSocket(wsUrl);
|
|
50
|
+
const isocket = new ISocketWithClientAuth(ws, authorization, requestHandlers);
|
|
51
|
+
return (0, socket_1.createISocketClient)(isocket);
|
|
52
|
+
}
|
|
53
|
+
exports.connectISocket = connectISocket;
|
|
54
|
+
function connectWebSocket(wsUrl) {
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
const ws = new isomorphic_ws_1.default(wsUrl);
|
|
57
|
+
ws.addEventListener("open", () => {
|
|
58
|
+
// Resolve the promise with the WebSocket instance when the connection is open
|
|
59
|
+
resolve(ws);
|
|
60
|
+
});
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
ws.addEventListener("error", (error) => {
|
|
64
|
+
// Reject the promise if there's an error
|
|
65
|
+
reject(error);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
exports.connectWebSocket = connectWebSocket;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ApiResource, GenericResource, Signature } from "../types";
|
|
2
|
+
export declare function signResource({ token, branchName, resource, agentUrls, }: {
|
|
3
|
+
token: string;
|
|
4
|
+
branchName: string;
|
|
5
|
+
resource: ApiResource | GenericResource;
|
|
6
|
+
agentUrls: string[];
|
|
7
|
+
}): Promise<Signature>;
|
|
8
|
+
export declare function verifyResources({ agentUrls, token, branchName, resources, }: {
|
|
9
|
+
resources: Array<GenericResource | ApiResource>;
|
|
10
|
+
token: string;
|
|
11
|
+
branchName: string;
|
|
12
|
+
agentUrls: string[];
|
|
13
|
+
}): Promise<void>;
|
|
@@ -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;
|