@covenant-rpc/server 0.2.0 → 0.4.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/dist/adapters/vanilla.d.ts +3 -0
- package/dist/adapters/vanilla.d.ts.map +1 -0
- package/dist/adapters/vanilla.js +7 -0
- package/dist/adapters/vanilla.js.map +1 -0
- package/{lib/index.ts → dist/index.d.ts} +1 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/direct.d.ts +4 -0
- package/dist/interfaces/direct.d.ts.map +1 -0
- package/dist/interfaces/direct.js +98 -0
- package/dist/interfaces/direct.js.map +1 -0
- package/dist/interfaces/empty.d.ts +3 -0
- package/dist/interfaces/empty.d.ts.map +1 -0
- package/dist/interfaces/empty.js +8 -0
- package/dist/interfaces/empty.js.map +1 -0
- package/dist/interfaces/http.d.ts +4 -0
- package/dist/interfaces/http.d.ts.map +1 -0
- package/dist/interfaces/http.js +92 -0
- package/dist/interfaces/http.js.map +1 -0
- package/dist/interfaces/mock.d.ts +4 -0
- package/dist/interfaces/mock.d.ts.map +1 -0
- package/dist/interfaces/mock.js +28 -0
- package/dist/interfaces/mock.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +60 -0
- package/dist/logger.js.map +1 -0
- package/dist/server.d.ts +46 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +342 -0
- package/dist/server.js.map +1 -0
- package/dist/sidekick/handlers.d.ts +15 -0
- package/dist/sidekick/handlers.d.ts.map +1 -0
- package/dist/sidekick/handlers.js +143 -0
- package/dist/sidekick/handlers.js.map +1 -0
- package/dist/sidekick/index.d.ts +33 -0
- package/dist/sidekick/index.d.ts.map +1 -0
- package/dist/sidekick/index.js +72 -0
- package/dist/sidekick/index.js.map +1 -0
- package/dist/sidekick/socket.d.ts +4 -0
- package/dist/sidekick/socket.d.ts.map +1 -0
- package/dist/sidekick/socket.js +5 -0
- package/dist/sidekick/socket.js.map +1 -0
- package/package.json +13 -10
- package/CHANGELOG.md +0 -17
- package/lib/adapters/vanilla.ts +0 -9
- package/lib/interfaces/direct.ts +0 -116
- package/lib/interfaces/empty.ts +0 -9
- package/lib/interfaces/http.ts +0 -111
- package/lib/interfaces/mock.ts +0 -32
- package/lib/logger.ts +0 -79
- package/lib/server.ts +0 -453
- package/lib/sidekick/handlers.ts +0 -173
- package/lib/sidekick/index.ts +0 -109
- package/lib/sidekick/socket.ts +0 -5
- package/tests/channel-http.test.ts +0 -481
- package/tests/channel.test.ts +0 -689
- package/tests/procedure.test.ts +0 -238
- package/tests/sidekick.test.ts +0 -23
- package/tests/validation-types.test.ts +0 -122
- package/tests/validation.test.ts +0 -144
package/dist/server.js
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { procedureRequestBodySchema } from "@covenant-rpc/core/procedure";
|
|
2
|
+
import { err, issuesToString, ok } from "@covenant-rpc/core/utils";
|
|
3
|
+
import { channelConnectionRequestSchema, serverMessageWithContext } from "@covenant-rpc/core/channel";
|
|
4
|
+
import { v } from "@covenant-rpc/core/validation";
|
|
5
|
+
import { procedureErrorFromUnknown, ThrowableProcedureError, ThrowableChannelError, channelErrorFromUnknown } from "@covenant-rpc/core/errors";
|
|
6
|
+
import { Logger } from "./logger";
|
|
7
|
+
import ION from "@covenant-rpc/ion";
|
|
8
|
+
export class CovenantServer {
|
|
9
|
+
covenant;
|
|
10
|
+
contextGenerator;
|
|
11
|
+
derivation;
|
|
12
|
+
sidekickConnection;
|
|
13
|
+
procedureDefinitions;
|
|
14
|
+
channelDefinitions;
|
|
15
|
+
logger;
|
|
16
|
+
constructor(covenant, { contextGenerator, derivation, sidekickConnection, logLevel, }) {
|
|
17
|
+
this.covenant = covenant;
|
|
18
|
+
this.contextGenerator = contextGenerator;
|
|
19
|
+
this.derivation = derivation;
|
|
20
|
+
this.sidekickConnection = sidekickConnection;
|
|
21
|
+
this.logger = new Logger(logLevel ?? "info", [
|
|
22
|
+
() => new Date().toUTCString(),
|
|
23
|
+
]);
|
|
24
|
+
// both of these fail. We leave them emtpy and let the user
|
|
25
|
+
// define them later. The `assertAllDefined can be used to do`
|
|
26
|
+
// a check to ensure all channels and procedures are defined
|
|
27
|
+
//
|
|
28
|
+
//@ts-expect-error see above
|
|
29
|
+
this.procedureDefinitions = {};
|
|
30
|
+
//@ts-expect-error see above
|
|
31
|
+
this.channelDefinitions = {};
|
|
32
|
+
}
|
|
33
|
+
defineProcedure(name, definition) {
|
|
34
|
+
if (this.procedureDefinitions[name] !== undefined) {
|
|
35
|
+
throw new Error(`Tried to define ${String(name)} twice!`);
|
|
36
|
+
}
|
|
37
|
+
this.procedureDefinitions[name] = definition;
|
|
38
|
+
}
|
|
39
|
+
defineChannel(name, definition) {
|
|
40
|
+
if (this.channelDefinitions[name] !== undefined) {
|
|
41
|
+
throw new Error(`Tried to define ${String(name)} twice!`);
|
|
42
|
+
}
|
|
43
|
+
this.channelDefinitions[name] = definition;
|
|
44
|
+
}
|
|
45
|
+
async sendMessage(name, params, message) {
|
|
46
|
+
this.logger.info(`Sending message to ${String(name)} with params ${JSON.stringify(params)}`);
|
|
47
|
+
return await this.sidekickConnection.postMessage({
|
|
48
|
+
channel: String(name),
|
|
49
|
+
params,
|
|
50
|
+
data: message,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async postChannelMessage(name, params, message) {
|
|
54
|
+
return await this.sendMessage(name, params, message);
|
|
55
|
+
}
|
|
56
|
+
async processChannelMessage(channelName, params, data, context) {
|
|
57
|
+
let l = this.logger.sublogger(`CHANNEL ${channelName}`);
|
|
58
|
+
try {
|
|
59
|
+
const declaration = this.covenant.channels[channelName];
|
|
60
|
+
const definition = this.channelDefinitions[channelName];
|
|
61
|
+
if (!declaration || !definition) {
|
|
62
|
+
return {
|
|
63
|
+
fault: "server",
|
|
64
|
+
message: `Channel ${channelName} not found`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Validate client message
|
|
68
|
+
const validation = await declaration.clientMessage["~standard"].validate(data);
|
|
69
|
+
if (validation.issues) {
|
|
70
|
+
return {
|
|
71
|
+
fault: "client",
|
|
72
|
+
message: `Invalid message data: ${issuesToString(validation.issues)}`,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Call onMessage handler
|
|
76
|
+
try {
|
|
77
|
+
await definition.onMessage({
|
|
78
|
+
inputs: validation.value,
|
|
79
|
+
params: params,
|
|
80
|
+
context,
|
|
81
|
+
error(reason, cause) {
|
|
82
|
+
throw new ThrowableChannelError(reason, channelName, params, cause);
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
l.info(`Processed message successfully`);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
const error = channelErrorFromUnknown(e, channelName, params);
|
|
90
|
+
l.error(`Message processing failed: ${error.message}`);
|
|
91
|
+
return {
|
|
92
|
+
fault: error.fault === "sidekick" ? "server" : error.fault,
|
|
93
|
+
message: error.message,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
const error = e instanceof Error ? e.message : String(e);
|
|
99
|
+
l.error(`Unexpected error: ${error}`);
|
|
100
|
+
return {
|
|
101
|
+
fault: "server",
|
|
102
|
+
message: error,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
assertAllDefined() {
|
|
107
|
+
for (const p of Object.keys(this.covenant.procedures)) {
|
|
108
|
+
if (this.procedureDefinitions[p] === undefined) {
|
|
109
|
+
this.logger.fatal(`Procedure ${p} was not defined`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
for (const c of Object.keys(this.covenant.channels)) {
|
|
113
|
+
if (this.channelDefinitions[c] === undefined) {
|
|
114
|
+
this.logger.fatal(`Channel ${c} was not defined`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async processProcedure(request, newHeaders) {
|
|
119
|
+
let l = this.logger.sublogger(`PROCEDURE ${request.procedure}`);
|
|
120
|
+
try {
|
|
121
|
+
const declaration = this.covenant.procedures[request.procedure];
|
|
122
|
+
const definition = this.procedureDefinitions[request.procedure];
|
|
123
|
+
if (!declaration || !definition) {
|
|
124
|
+
throw new ThrowableProcedureError(`Procedure ${request.procedure} not found`, 404);
|
|
125
|
+
}
|
|
126
|
+
const validationResult = await declaration.input["~standard"].validate(request.input);
|
|
127
|
+
if (validationResult.issues) {
|
|
128
|
+
throw new ThrowableProcedureError(`Error parsing procedure inputs: ${issuesToString(validationResult.issues)}`, 404);
|
|
129
|
+
}
|
|
130
|
+
const initialInputs = {
|
|
131
|
+
inputs: validationResult.value,
|
|
132
|
+
request,
|
|
133
|
+
ctx: undefined,
|
|
134
|
+
derived: undefined,
|
|
135
|
+
logger: l,
|
|
136
|
+
setHeader(name, value) {
|
|
137
|
+
newHeaders.set(name, value);
|
|
138
|
+
},
|
|
139
|
+
deleteHeader(name) {
|
|
140
|
+
newHeaders.delete(name);
|
|
141
|
+
},
|
|
142
|
+
error(message, code) {
|
|
143
|
+
throw new ThrowableProcedureError(message, code);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const ctx = await this.contextGenerator(initialInputs);
|
|
147
|
+
const derived = await this.derivation({ ...initialInputs, ctx });
|
|
148
|
+
const result = await definition.procedure({ ...initialInputs, ctx, derived });
|
|
149
|
+
const resources = await definition.resources({ inputs: validationResult.value, ctx, outputs: result, logger: l });
|
|
150
|
+
if (declaration.type === "mutation") {
|
|
151
|
+
this.sidekickConnection.update(resources).then((e) => {
|
|
152
|
+
if (e !== null) {
|
|
153
|
+
l.error(`Failed to send resource updates for ${resources.toString()} - ${e.message}`);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
l.info("Returning OK");
|
|
158
|
+
return {
|
|
159
|
+
status: "OK",
|
|
160
|
+
data: result,
|
|
161
|
+
resources,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
const error = procedureErrorFromUnknown(e);
|
|
166
|
+
l.error(`Returning ERR ${error.code} - ${error.message}`);
|
|
167
|
+
return {
|
|
168
|
+
status: "ERR",
|
|
169
|
+
error,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async handleProcedure(request) {
|
|
174
|
+
const { data: parsed, error, success } = await parseRequest(request);
|
|
175
|
+
if (!success) {
|
|
176
|
+
this.logger.error(`Failed parsing procedure request: ${error.message}`);
|
|
177
|
+
return new Response(`Error parsing request body. If you're a dev seeing this then this is probably my bad not yours. Create an issue on the covenant rpc github: ${error.message}`);
|
|
178
|
+
}
|
|
179
|
+
const headers = new Headers();
|
|
180
|
+
headers.set("Content-Type", "application/json");
|
|
181
|
+
const res = await this.processProcedure(parsed, headers);
|
|
182
|
+
const status = res.status === "OK" ? 201 : res.error.code;
|
|
183
|
+
return new Response(ION.stringify(res), {
|
|
184
|
+
headers,
|
|
185
|
+
status,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
async handleChannelMessage(request) {
|
|
189
|
+
let l = this.logger.sublogger(`CHANNEL_MESSAGE`);
|
|
190
|
+
try {
|
|
191
|
+
const bodyText = await request.text();
|
|
192
|
+
const body = ION.parse(bodyText);
|
|
193
|
+
const validation = v.parseSafe(body, serverMessageWithContext);
|
|
194
|
+
if (validation === null) {
|
|
195
|
+
throw new Error(`Invalid channel message: ${JSON.stringify(body)}`);
|
|
196
|
+
}
|
|
197
|
+
const { channel, params, data, context } = validation;
|
|
198
|
+
const result = await this.processChannelMessage(channel, params, data, context);
|
|
199
|
+
if (result !== null) {
|
|
200
|
+
l.error(`Channel message processing failed: ${result.fault} - ${result.message}`);
|
|
201
|
+
return new Response(ION.stringify(result), {
|
|
202
|
+
status: 400,
|
|
203
|
+
headers: { "Content-Type": "application/json" },
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return new Response(null, {
|
|
207
|
+
status: 204,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
const error = e instanceof Error ? e.message : String(e);
|
|
212
|
+
l.error(`Channel message failed: ${error}`);
|
|
213
|
+
return new Response(ION.stringify({ error }), {
|
|
214
|
+
status: 500,
|
|
215
|
+
headers: { "Content-Type": "application/json" },
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async handleConnectionRequest(request) {
|
|
220
|
+
let l = this.logger.sublogger(`CONNECTION`);
|
|
221
|
+
let channelName = "unknown";
|
|
222
|
+
let params = {};
|
|
223
|
+
try {
|
|
224
|
+
const bodyText = await request.text();
|
|
225
|
+
const body = ION.parse(bodyText);
|
|
226
|
+
const validation = v.parseSafe(body, channelConnectionRequestSchema);
|
|
227
|
+
if (validation === null) {
|
|
228
|
+
throw new Error(`Invalid connection request: ${JSON.stringify(body)}`);
|
|
229
|
+
}
|
|
230
|
+
channelName = validation.channel;
|
|
231
|
+
params = validation.params;
|
|
232
|
+
const data = validation.data;
|
|
233
|
+
const declaration = this.covenant.channels[channelName];
|
|
234
|
+
const definition = this.channelDefinitions[channelName];
|
|
235
|
+
if (!declaration || !definition) {
|
|
236
|
+
throw new ThrowableChannelError(`Channel ${channelName} not found`, channelName, params, "server");
|
|
237
|
+
}
|
|
238
|
+
// Validate connection request data
|
|
239
|
+
const connectionRequestValidation = await declaration.connectionRequest["~standard"].validate(data);
|
|
240
|
+
if (connectionRequestValidation.issues) {
|
|
241
|
+
throw new ThrowableChannelError(`Invalid connection request data: ${issuesToString(connectionRequestValidation.issues)}`, channelName, params, "client");
|
|
242
|
+
}
|
|
243
|
+
// Call onConnect handler
|
|
244
|
+
const context = await definition.onConnect({
|
|
245
|
+
inputs: connectionRequestValidation.value,
|
|
246
|
+
params: params,
|
|
247
|
+
reject(reason, cause) {
|
|
248
|
+
throw new ThrowableChannelError(reason, channelName, params, cause);
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
// Generate token
|
|
252
|
+
const token = globalThis.crypto.randomUUID();
|
|
253
|
+
// Add connection to sidekick
|
|
254
|
+
await this.sidekickConnection.addConnection({
|
|
255
|
+
token,
|
|
256
|
+
channel: channelName,
|
|
257
|
+
params,
|
|
258
|
+
context,
|
|
259
|
+
});
|
|
260
|
+
l.info(`Connection established for ${channelName} with token ${token}`);
|
|
261
|
+
const response = {
|
|
262
|
+
channel: channelName,
|
|
263
|
+
params,
|
|
264
|
+
result: {
|
|
265
|
+
type: "OK",
|
|
266
|
+
token,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
return new Response(ION.stringify(response), {
|
|
270
|
+
status: 200,
|
|
271
|
+
headers: { "Content-Type": "application/json" },
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch (e) {
|
|
275
|
+
if (e instanceof ThrowableChannelError) {
|
|
276
|
+
const error = e.toChannelError();
|
|
277
|
+
l.error(`Connection rejected: ${error.message}`);
|
|
278
|
+
const response = {
|
|
279
|
+
channel: channelName,
|
|
280
|
+
params,
|
|
281
|
+
result: {
|
|
282
|
+
type: "ERROR",
|
|
283
|
+
error,
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
return new Response(ION.stringify(response), {
|
|
287
|
+
status: 400,
|
|
288
|
+
headers: { "Content-Type": "application/json" },
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
const error = e instanceof Error ? e.message : String(e);
|
|
292
|
+
l.error(`Connection failed: ${error}`);
|
|
293
|
+
return new Response(ION.stringify({ error }), {
|
|
294
|
+
status: 500,
|
|
295
|
+
headers: { "Content-Type": "application/json" },
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async handle(request) {
|
|
300
|
+
const url = new URL(request.url);
|
|
301
|
+
const type = url.searchParams.get("type") ?? "procedure";
|
|
302
|
+
if (request.method !== "POST") {
|
|
303
|
+
return new Response("Covenant servers only handle POST requests", { status: 404 });
|
|
304
|
+
}
|
|
305
|
+
let response = new Response();
|
|
306
|
+
switch (type) {
|
|
307
|
+
case "channel":
|
|
308
|
+
response = await this.handleChannelMessage(request);
|
|
309
|
+
break;
|
|
310
|
+
case "procedure":
|
|
311
|
+
response = await this.handleProcedure(request);
|
|
312
|
+
break;
|
|
313
|
+
case "connect":
|
|
314
|
+
response = await this.handleConnectionRequest(request);
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
return response;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
export async function parseRequest(request) {
|
|
321
|
+
try {
|
|
322
|
+
const bodyText = await request.text();
|
|
323
|
+
const body = ION.parse(bodyText);
|
|
324
|
+
const result = v.parseSafe(body, procedureRequestBodySchema);
|
|
325
|
+
if (result === null) {
|
|
326
|
+
throw new Error(`Failed to parse body as a ProcedureRequestBody: ${JSON.stringify(body)}`);
|
|
327
|
+
}
|
|
328
|
+
const url = new URL(request.url);
|
|
329
|
+
return ok({
|
|
330
|
+
headers: request.headers,
|
|
331
|
+
input: result.inputs,
|
|
332
|
+
procedure: result.procedure,
|
|
333
|
+
path: url.pathname,
|
|
334
|
+
url: url.toString(),
|
|
335
|
+
req: request
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
catch (e) {
|
|
339
|
+
return err(e instanceof Error ? e : new Error(`Unknown error: ${e}`));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PublishFunction, SidekickClient, SidekickState } from ".";
|
|
2
|
+
import type { Logger } from "@covenant-rpc/core/logger";
|
|
3
|
+
import type { ListenMessage, SendMessage, SubscribeMessage, UnlistenMessage, UnsubscribeMessage } from "@covenant-rpc/core/sidekick/protocol";
|
|
4
|
+
export interface SidekickHandlerContext {
|
|
5
|
+
state: SidekickState;
|
|
6
|
+
client: SidekickClient;
|
|
7
|
+
publish: PublishFunction;
|
|
8
|
+
logger: Logger;
|
|
9
|
+
}
|
|
10
|
+
export declare function handleListenMessage(message: ListenMessage, { client, logger }: SidekickHandlerContext): Promise<void>;
|
|
11
|
+
export declare function handleUnlistenMessage(message: UnlistenMessage, { client, logger }: SidekickHandlerContext): Promise<void>;
|
|
12
|
+
export declare function handleSendMessage(message: SendMessage, { client, logger, state }: SidekickHandlerContext): Promise<void>;
|
|
13
|
+
export declare function handleSubscribeMessage(message: SubscribeMessage, { client, logger, state }: SidekickHandlerContext): Promise<void>;
|
|
14
|
+
export declare function handleUnsubscribeMessage(message: UnsubscribeMessage, { client, logger, state }: SidekickHandlerContext): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../sidekick/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAI9I,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,sBAAsB,iBAW3G;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,sBAAsB,iBAU/G;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,sBAAsB,iBA+D9G;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,sBAAsB,iBAqCxH;AAED,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,sBAAsB,iBA8B5H"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { getChannelTopicName, getMapId, getResourceTopicName } from "@covenant-rpc/core/sidekick/protocol";
|
|
2
|
+
export async function handleListenMessage(message, { client, logger }) {
|
|
3
|
+
for (const resource of message.resources) {
|
|
4
|
+
client.subscribe(getResourceTopicName(resource));
|
|
5
|
+
}
|
|
6
|
+
logger.info(`Listened to ${message.resources.toString()}`);
|
|
7
|
+
client.directMessage({
|
|
8
|
+
type: "listening",
|
|
9
|
+
resources: message.resources,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export async function handleUnlistenMessage(message, { client, logger }) {
|
|
13
|
+
for (const resource of message.resources) {
|
|
14
|
+
client.unsubscribe(getResourceTopicName(resource));
|
|
15
|
+
}
|
|
16
|
+
logger.info(`Unlistened to ${message.resources.toString()}`);
|
|
17
|
+
client.directMessage({
|
|
18
|
+
type: "unlistening",
|
|
19
|
+
resources: message.resources,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export async function handleSendMessage(message, { client, logger, state }) {
|
|
23
|
+
// Check if token exists in unused tokens (not yet subscribed)
|
|
24
|
+
let payload = state.tokenMap.get(message.token);
|
|
25
|
+
let context = undefined;
|
|
26
|
+
if (payload) {
|
|
27
|
+
// Token exists but client hasn't subscribed yet - use the context from the payload
|
|
28
|
+
context = payload.context;
|
|
29
|
+
// Verify the channel and params match
|
|
30
|
+
if (payload.channel !== message.channel) {
|
|
31
|
+
logger.error(`Token is for channel ${payload.channel} but message is for ${message.channel}`);
|
|
32
|
+
client.directMessage({
|
|
33
|
+
type: "error",
|
|
34
|
+
error: {
|
|
35
|
+
channel: message.channel,
|
|
36
|
+
params: message.params,
|
|
37
|
+
fault: "client",
|
|
38
|
+
message: "Token channel mismatch",
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Check if token has been used (client is subscribed)
|
|
46
|
+
const usedToken = state.usedTokenMap.get(message.token);
|
|
47
|
+
if (!usedToken || usedToken.id !== client.getId()) {
|
|
48
|
+
logger.error(`Invalid or unauthorized token for send`);
|
|
49
|
+
client.directMessage({
|
|
50
|
+
type: "error",
|
|
51
|
+
error: {
|
|
52
|
+
channel: message.channel,
|
|
53
|
+
params: message.params,
|
|
54
|
+
fault: "client",
|
|
55
|
+
message: "Invalid or unauthorized token",
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Get context from context map
|
|
61
|
+
const topic = getChannelTopicName(usedToken.channel, usedToken.params);
|
|
62
|
+
const mapId = getMapId(client.getId(), topic);
|
|
63
|
+
context = state.contextMap.get(mapId);
|
|
64
|
+
}
|
|
65
|
+
const result = await state.serverConnection.sendMessage({
|
|
66
|
+
params: message.params,
|
|
67
|
+
channel: message.channel,
|
|
68
|
+
data: message.data,
|
|
69
|
+
context,
|
|
70
|
+
});
|
|
71
|
+
if (result !== null) {
|
|
72
|
+
logger.error(`Got bad response sending message: ${result.fault} - ${result.message}`);
|
|
73
|
+
client.directMessage({
|
|
74
|
+
type: "error",
|
|
75
|
+
error: result,
|
|
76
|
+
});
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
logger.info(`Processed message successfully`);
|
|
80
|
+
}
|
|
81
|
+
export async function handleSubscribeMessage(message, { client, logger, state }) {
|
|
82
|
+
const payload = state.tokenMap.get(message.token);
|
|
83
|
+
if (!payload) {
|
|
84
|
+
logger.error("Failed to subscribe: bad input token");
|
|
85
|
+
// TODO - add a time delay here to avoid brute forcing input tokens?
|
|
86
|
+
// probably not. This level of abstraction doesn't feel right for that
|
|
87
|
+
client.directMessage({
|
|
88
|
+
type: "error",
|
|
89
|
+
error: {
|
|
90
|
+
fault: "client",
|
|
91
|
+
message: "Inputted invalid token for subscription",
|
|
92
|
+
channel: "???unknown",
|
|
93
|
+
params: {},
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const topic = getChannelTopicName(payload.channel, payload.params);
|
|
99
|
+
const mapId = getMapId(client.getId(), topic);
|
|
100
|
+
state.tokenMap.delete(message.token);
|
|
101
|
+
state.contextMap.set(mapId, payload.context);
|
|
102
|
+
client.subscribe(topic);
|
|
103
|
+
state.usedTokenMap.set(message.token, {
|
|
104
|
+
id: client.getId(),
|
|
105
|
+
channel: payload.channel,
|
|
106
|
+
params: payload.params,
|
|
107
|
+
});
|
|
108
|
+
logger.info(`Subscribed to ${topic}`);
|
|
109
|
+
client.directMessage({
|
|
110
|
+
type: "subscribed",
|
|
111
|
+
channel: payload.channel,
|
|
112
|
+
params: payload.params,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
export async function handleUnsubscribeMessage(message, { client, logger, state }) {
|
|
116
|
+
const data = state.usedTokenMap.get(message.token);
|
|
117
|
+
const id = client.getId();
|
|
118
|
+
if (!data || data.id !== id) {
|
|
119
|
+
logger.error("Failed to unsubscribe: bad input token");
|
|
120
|
+
client.directMessage({
|
|
121
|
+
type: "error",
|
|
122
|
+
error: {
|
|
123
|
+
fault: "client",
|
|
124
|
+
message: "Inputted invalid token for unsubscription",
|
|
125
|
+
channel: "???unknown",
|
|
126
|
+
params: {},
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const topic = getChannelTopicName(data.channel, data.params);
|
|
132
|
+
const mapId = getMapId(id, topic);
|
|
133
|
+
state.usedTokenMap.delete(message.token);
|
|
134
|
+
state.contextMap.delete(mapId);
|
|
135
|
+
client.unsubscribe(topic);
|
|
136
|
+
logger.info(`Unsubscribed from ${topic}`);
|
|
137
|
+
client.directMessage({
|
|
138
|
+
type: "unsubscribed",
|
|
139
|
+
channel: data.channel,
|
|
140
|
+
params: data.params,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../sidekick/handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ChannelConnectionPayload, ServerMessage } from "@covenant-rpc/core/channel";
|
|
2
|
+
import type { SidekickToServerConnection } from "@covenant-rpc/core/interfaces";
|
|
3
|
+
import type { LoggerLevel } from "@covenant-rpc/core/logger";
|
|
4
|
+
import { type SidekickIncomingMessage, type SidekickOutgoingMessage } from "@covenant-rpc/core/sidekick/protocol";
|
|
5
|
+
export interface SidekickClient {
|
|
6
|
+
subscribe(topic: string): void;
|
|
7
|
+
unsubscribe(topic: string): void;
|
|
8
|
+
getId(): string;
|
|
9
|
+
directMessage(message: SidekickOutgoingMessage): void;
|
|
10
|
+
}
|
|
11
|
+
export interface SidekickState {
|
|
12
|
+
contextMap: Map<string, unknown>;
|
|
13
|
+
tokenMap: Map<string, ChannelConnectionPayload>;
|
|
14
|
+
usedTokenMap: Map<string, {
|
|
15
|
+
channel: string;
|
|
16
|
+
params: Record<string, string>;
|
|
17
|
+
id: string;
|
|
18
|
+
}>;
|
|
19
|
+
serverConnection: SidekickToServerConnection;
|
|
20
|
+
}
|
|
21
|
+
export type PublishFunction = (topic: string, message: SidekickOutgoingMessage) => Promise<void>;
|
|
22
|
+
export declare class Sidekick {
|
|
23
|
+
private publish;
|
|
24
|
+
private state;
|
|
25
|
+
private logger;
|
|
26
|
+
constructor(publishFunction: PublishFunction, logLevel?: LoggerLevel);
|
|
27
|
+
updateResources(resources: string[]): Promise<void>;
|
|
28
|
+
postServerMessage(message: ServerMessage): Promise<void>;
|
|
29
|
+
addConnection(payload: ChannelConnectionPayload): void;
|
|
30
|
+
handleClientMessage(client: SidekickClient, message: SidekickIncomingMessage): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export type UpdateListener = (resources: string[]) => Promise<void> | void;
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../sidekick/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAG7D,OAAO,EAA6C,KAAK,uBAAuB,EAAE,KAAK,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAE7J,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,KAAK,IAAI,MAAM,CAAC;IAChB,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAChD,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC9B,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC,CAAA;IACF,gBAAgB,EAAE,0BAA0B,CAAC;CAC9C;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAGjG,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAKX;IACF,OAAO,CAAC,MAAM,CAAS;gBAEX,eAAe,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,WAAW;IAO9D,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE;IAiBnC,iBAAiB,CAAC,OAAO,EAAE,aAAa;IAQ9C,aAAa,CAAC,OAAO,EAAE,wBAAwB;IAIzC,mBAAmB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,uBAAuB;CA8BnF;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { httpSidekickToServer } from "../interfaces/http";
|
|
2
|
+
import { Logger } from "../logger";
|
|
3
|
+
import { handleListenMessage, handleSendMessage, handleSubscribeMessage, handleUnlistenMessage, handleUnsubscribeMessage } from "./handlers";
|
|
4
|
+
import { getChannelTopicName, getResourceTopicName } from "@covenant-rpc/core/sidekick/protocol";
|
|
5
|
+
export class Sidekick {
|
|
6
|
+
publish;
|
|
7
|
+
state = {
|
|
8
|
+
contextMap: new Map(),
|
|
9
|
+
tokenMap: new Map(),
|
|
10
|
+
usedTokenMap: new Map(),
|
|
11
|
+
serverConnection: httpSidekickToServer("", ""),
|
|
12
|
+
};
|
|
13
|
+
logger;
|
|
14
|
+
constructor(publishFunction, logLevel) {
|
|
15
|
+
this.publish = publishFunction;
|
|
16
|
+
this.logger = new Logger(logLevel ?? "info", [
|
|
17
|
+
() => new Date().toUTCString(),
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
async updateResources(resources) {
|
|
21
|
+
const promises = [];
|
|
22
|
+
for (const r of resources) {
|
|
23
|
+
promises.push(async () => {
|
|
24
|
+
const topic = getResourceTopicName(r);
|
|
25
|
+
await this.publish(topic, {
|
|
26
|
+
type: "updated",
|
|
27
|
+
resource: r,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
await Promise.all(promises.map(p => p()));
|
|
32
|
+
}
|
|
33
|
+
async postServerMessage(message) {
|
|
34
|
+
const topic = getChannelTopicName(message.channel, message.params);
|
|
35
|
+
await this.publish(topic, {
|
|
36
|
+
type: "message",
|
|
37
|
+
...message
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
addConnection(payload) {
|
|
41
|
+
this.state.tokenMap.set(payload.token, payload);
|
|
42
|
+
}
|
|
43
|
+
async handleClientMessage(client, message) {
|
|
44
|
+
const logger = this.logger.clone()
|
|
45
|
+
.pushPrefix(`Client: ${client.getId()}`)
|
|
46
|
+
.pushPrefix(`Type: ${message.type}`);
|
|
47
|
+
const ctx = {
|
|
48
|
+
client,
|
|
49
|
+
logger,
|
|
50
|
+
state: this.state,
|
|
51
|
+
publish: this.publish,
|
|
52
|
+
};
|
|
53
|
+
switch (message.type) {
|
|
54
|
+
case "unsubscribe":
|
|
55
|
+
await handleUnsubscribeMessage(message, ctx);
|
|
56
|
+
break;
|
|
57
|
+
case "subscribe":
|
|
58
|
+
await handleSubscribeMessage(message, ctx);
|
|
59
|
+
break;
|
|
60
|
+
case "listen":
|
|
61
|
+
await handleListenMessage(message, ctx);
|
|
62
|
+
break;
|
|
63
|
+
case "unlisten":
|
|
64
|
+
await handleUnlistenMessage(message, ctx);
|
|
65
|
+
break;
|
|
66
|
+
case "send":
|
|
67
|
+
await handleSendMessage(message, ctx);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../sidekick/index.ts"],"names":[],"mappings":"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"}
|