Skip to content

Commit bd58428

Browse files
committed
fix: resolve merge leftovers in implemented-by websocket changes
1 parent fa77ef7 commit bd58428

5 files changed

Lines changed: 73 additions & 71 deletions

File tree

src/plugins.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { MethodObject } from "@open-rpc/meta-schema";
2+
import { RouterPlugin } from "./router";
3+
4+
const getImplementedBy = (methodObject?: MethodObject): string[] => {
5+
if (!methodObject) {
6+
return [];
7+
}
8+
9+
const implementedBy = (methodObject as MethodObject & { [key: string]: unknown })["x-implementedBy"];
10+
if (implementedBy === undefined) {
11+
return ["server"];
12+
}
13+
14+
if (implementedBy instanceof Array) {
15+
return implementedBy.filter((role): role is string => typeof role === "string");
16+
}
17+
18+
return [];
19+
};
20+
21+
export const implementedByPlugin = (): RouterPlugin => ({
22+
name: "implemented-by",
23+
isMethodImplemented: ({ methodName, methodObject, context }) => {
24+
if (methodName === "rpc.discover") {
25+
return true;
26+
}
27+
28+
const participant = (context?.participant as string | undefined) || "server";
29+
return getImplementedBy(methodObject).includes(participant);
30+
},
31+
listMethods: ({ methods, context }) => {
32+
const participant = (context?.participant as string | undefined) || "server";
33+
return methods
34+
.filter((method) => getImplementedBy(method).includes(participant))
35+
.map((method) => method.name);
36+
},
37+
mapHandlerParams: ({ paramsAsArray, context }) => {
38+
if (!context || context.client === undefined) {
39+
return paramsAsArray;
40+
}
41+
return [...paramsAsArray, context.client];
42+
},
43+
});
44+

src/router.test.ts

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -145,51 +145,30 @@ describe("router", () => {
145145
const { result } = await router.call("addition", [6, 2]);
146146
expect(typeof result).toBe("number");
147147
});
148-
<<<<<<< Updated upstream
149-
it("does not expose x-implementedBy client methods as inbound server methods", async () => {
150-
const exampleWithClientMethod = _.cloneDeep(parsedExample);
151-
const additionMethod = (exampleWithClientMethod.methods as MethodObject[]).find((method) => method.name === "addition") as MethodObject;
152-
(additionMethod as MethodObject & { [key: string]: unknown })["x-implementedBy"] = ["client"];
153-
const router = new Router(exampleWithClientMethod, makeMethodMapping(exampleWithClientMethod.methods as MethodObject[]));
154-
=======
155148

156-
it("plugin blocks methods not implemented by server", async () => {
149+
it("does not expose x-implementedBy client methods as inbound server methods", async () => {
157150
const exampleWithClientMethod = _.cloneDeep(parsedExample);
158151
const additionMethod = (exampleWithClientMethod.methods as MethodObject[])
159152
.find((method) => method.name === "addition") as MethodObject;
160153
(additionMethod as MethodObject & { [key: string]: unknown })["x-implementedBy"] = ["client"];
161-
162-
const router = new Router(
163-
exampleWithClientMethod,
164-
makeMethodMapping(exampleWithClientMethod.methods as MethodObject[]),
165-
{ plugins: [implementedByPlugin()] },
166-
);
167-
>>>>>>> Stashed changes
154+
const router = new Router(exampleWithClientMethod, makeMethodMapping(exampleWithClientMethod.methods as MethodObject[]));
168155
const { error } = await router.call("addition", [2, 2]);
169156
expect((error as JSONRPCErrorObject).code).toBe(-32601);
170157
});
171158

172-
<<<<<<< Updated upstream
173159
it("reports methods implemented by a given participant", async () => {
174160
const exampleWithClientMethod = _.cloneDeep(parsedExample);
175161
const methods = exampleWithClientMethod.methods as MethodObject[];
176-
=======
177-
it("plugin reports available methods using plugin context", () => {
178-
const exampleWithRoles = _.cloneDeep(parsedExample);
179-
const methods = exampleWithRoles.methods as MethodObject[];
180-
>>>>>>> Stashed changes
181162
const additionMethod = methods.find((method) => method.name === "addition") as MethodObject;
182163
const subtractionMethod = methods.find((method) => method.name === "subtraction") as MethodObject;
183164
(additionMethod as MethodObject & { [key: string]: unknown })["x-implementedBy"] = ["client"];
184165
(subtractionMethod as MethodObject & { [key: string]: unknown })["x-implementedBy"] = ["server", "client"];
185166

186-
<<<<<<< Updated upstream
187167
const router = new Router(exampleWithClientMethod, makeMethodMapping(methods));
188168
expect(router.getMethodsImplementedBy("client")).toEqual(expect.arrayContaining(["addition", "subtraction"]));
189169
expect(router.getMethodsImplementedBy("server")).toContain("subtraction");
190170
});
191171

192-
193172
it("defaults x-implementedBy to server when extension is omitted", async () => {
194173
const exampleWithoutExtension = _.cloneDeep(parsedExample);
195174
const additionMethod = (exampleWithoutExtension.methods as MethodObject[])
@@ -207,7 +186,14 @@ describe("router", () => {
207186
expect(router.getMethodsImplementedBy("server")).not.toContain("rpc.discover");
208187
});
209188

210-
=======
189+
it("plugin reports available methods using plugin context", () => {
190+
const exampleWithRoles = _.cloneDeep(parsedExample);
191+
const methods = exampleWithRoles.methods as MethodObject[];
192+
const additionMethod = methods.find((method) => method.name === "addition") as MethodObject;
193+
const subtractionMethod = methods.find((method) => method.name === "subtraction") as MethodObject;
194+
(additionMethod as MethodObject & { [key: string]: unknown })["x-implementedBy"] = ["client"];
195+
(subtractionMethod as MethodObject & { [key: string]: unknown })["x-implementedBy"] = ["server", "client"];
196+
211197
const router = new Router(
212198
exampleWithRoles,
213199
makeMethodMapping(methods),
@@ -235,7 +221,6 @@ describe("router", () => {
235221
const { result } = await router.call("addition", [2, 2], { client: expectedClient });
236222
expect(result).toBe(4);
237223
});
238-
>>>>>>> Stashed changes
239224
}
240225

241226
});

src/router.ts

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,8 @@ export class Router {
127127
this.plugins = options.plugins || [];
128128
}
129129

130-
<<<<<<< Updated upstream
131-
public async call(methodName: string, params: any, context?: { client?: unknown }) {
132-
if (!this.getImplementedBy(methodName).includes("server") && methodName !== "rpc.discover") {
133-
=======
134130
public async call(methodName: string, params: any, context?: RouterCallContext) {
135131
if (!this.isMethodImplemented(methodName, context)) {
136-
>>>>>>> Stashed changes
137132
return Router.methodNotFoundHandler(methodName);
138133
}
139134

@@ -152,11 +147,7 @@ export class Router {
152147
let paramsAsArray = params instanceof Array ? params : toArray(methodObject, params);
153148

154149
try {
155-
<<<<<<< Updated upstream
156-
if (context && context.client !== undefined) {
157-
return { result: await this.methods[methodName](...paramsAsArray, context.client) };
158-
}
159-
=======
150+
let paramsMappedByPlugin = false;
160151
for (const plugin of this.plugins) {
161152
if (!plugin.mapHandlerParams) {
162153
continue;
@@ -174,10 +165,14 @@ export class Router {
174165

175166
if (mappedParams !== undefined) {
176167
paramsAsArray = mappedParams;
168+
paramsMappedByPlugin = true;
177169
}
178170
}
179171

180-
>>>>>>> Stashed changes
172+
if (!paramsMappedByPlugin && context && context.client !== undefined) {
173+
paramsAsArray = [...paramsAsArray, context.client];
174+
}
175+
181176
return { result: await this.methods[methodName](...paramsAsArray) };
182177
} catch (e) {
183178
if (e instanceof JSONRPCError) {
@@ -187,17 +182,6 @@ export class Router {
187182
}
188183
}
189184

190-
<<<<<<< Updated upstream
191-
public isMethodImplemented(methodName: string): boolean {
192-
return this.methods[methodName] !== undefined && this.getImplementedBy(methodName).includes("server");
193-
}
194-
195-
public getMethodsImplementedBy(participant: string): string[] {
196-
return (this.openrpcDocument.methods as MethodObject[])
197-
.filter((method) => this.getImplementedBy(method.name).includes(participant))
198-
.map((method) => method.name)
199-
.filter((methodName) => methodName !== "rpc.discover");
200-
=======
201185
public isMethodImplemented(methodName: string, context?: RouterCallContext): boolean {
202186
const methodObject = (this.openrpcDocument.methods as MethodObject[]).find((m) => m.name === methodName);
203187
const hasLocalHandler = this.methods[methodName] !== undefined;
@@ -206,6 +190,10 @@ export class Router {
206190
return false;
207191
}
208192

193+
if (methodName === "rpc.discover") {
194+
return true;
195+
}
196+
209197
for (const plugin of this.plugins) {
210198
if (!plugin.isMethodImplemented) {
211199
continue;
@@ -222,7 +210,14 @@ export class Router {
222210
}
223211
}
224212

225-
return true;
213+
return this.getImplementedBy(methodName).includes("server");
214+
}
215+
216+
public getMethodsImplementedBy(participant: string): string[] {
217+
return (this.openrpcDocument.methods as MethodObject[])
218+
.filter((method) => this.getImplementedBy(method.name).includes(participant))
219+
.map((method) => method.name)
220+
.filter((methodName) => methodName !== "rpc.discover");
226221
}
227222

228223
public getAvailableMethods(context?: RouterCallContext): string[] {
@@ -246,8 +241,7 @@ export class Router {
246241
return methods
247242
.map((method) => method.name)
248243
.filter((methodName) => methodName !== "rpc.discover")
249-
.filter((methodName) => this.isMethodImplemented(methodName));
250-
>>>>>>> Stashed changes
244+
.filter((methodName) => this.isMethodImplemented(methodName, context));
251245
}
252246

253247
private serviceDiscoveryHandler(): Promise<OpenrpcDocument> {

src/transports/server-transport.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,7 @@ export abstract class ServerTransport {
4141
throw new Error("Transport missing stop implementation");
4242
}
4343

44-
<<<<<<< Updated upstream
45-
protected async routerHandler({ id, method, params }: JSONRPCRequest, context?: { client?: unknown }): Promise<JSONRPCResponse> {
46-
=======
4744
protected async routerHandler({ id, method, params }: JSONRPCRequest, context?: RouterCallContext): Promise<JSONRPCResponse> {
48-
>>>>>>> Stashed changes
4945
if (this.routers.length === 0) {
5046
console.warn("transport method called without a router configured."); // tslint:disable-line
5147
throw new Error("No router configured");

src/transports/websocket.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ export default class WebSocketServerTransport extends ServerTransport {
7373
this.wss = new WebSocket.Server({ server: this.server as any });
7474

7575
this.wss.on("connection", (ws: WebSocket) => {
76-
<<<<<<< Updated upstream
7776
const client = {
7877
id: `client-${this.nextClientId++}`,
7978
methods: this.buildClientMethodsProxy(ws),
@@ -84,13 +83,6 @@ export default class WebSocketServerTransport extends ServerTransport {
8483
void this.handleWebSocketMessage(message, ws);
8584
});
8685
ws.on("close", () => this.handleClientClose(ws));
87-
=======
88-
ws.on(
89-
"message",
90-
(message: string) => this.webSocketRouterHandler(JSON.parse(message), ws, ws.send.bind(ws)),
91-
);
92-
ws.on("close", () => ws.removeAllListeners());
93-
>>>>>>> Stashed changes
9486
});
9587
}
9688

@@ -143,7 +135,6 @@ export default class WebSocketServerTransport extends ServerTransport {
143135
});
144136
}
145137

146-
<<<<<<< Updated upstream
147138
private handleClientClose(ws: WebSocket) {
148139
ws.removeAllListeners();
149140
this.clientDetails.delete(ws);
@@ -188,14 +179,6 @@ export default class WebSocketServerTransport extends ServerTransport {
188179
ws.send(JSON.stringify(filteredResponses));
189180
}
190181
return;
191-
=======
192-
private async webSocketRouterHandler(req: any, ws: WebSocket, respondWith: any) {
193-
let result = null;
194-
if (req instanceof Array) {
195-
result = await Promise.all(req.map((r: JSONRPCRequest) => super.routerHandler(r, { client: ws })));
196-
} else {
197-
result = await super.routerHandler(req, { client: ws });
198-
>>>>>>> Stashed changes
199182
}
200183

201184
const response = await this.routePayload(payload, ws);

0 commit comments

Comments
 (0)