UNPKG

ws-rmi

Version:

A Remote Method Invocation implementation written in JavaScript utilising the WebSocket protocol

63 lines (62 loc) 2.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.exposeFunctions = exports.handleRequest = void 0; const RMIRequest_1 = require("./types/RMIRequest"); const RMIRemoteResult_1 = require("./types/RMIRemoteResult"); const RMIRemoteError_1 = require("./types/RMIRemoteError"); /** * Handles an {@link RMIRequest} and produces either an {@link RMIRemoteResult} if the specified target: * 1. Exists * 2. Is a function * 3. Doesn't throw an Error * * Otherwise, an {@link RMIRemoteError} is produced detailing that an error occurred. For security purposes, a generic * error message is generated. If an Error is thrown, it is propagated back to {@link exposeFunctions} where a given * error handler can handle it further (e.g. console logs, output to a log file, etc.) * * @param rmi The request body * @param functions A class / object containing functions that can be invoked. */ const handleRequest = async ({ rmi }, functions) => { const { data, id } = rmi; const { target, args } = data; const functionToInvoke = functions[target]; if (typeof functionToInvoke !== "function") return (0, RMIRemoteError_1.createRMIRemoteError)(id, `Target "${target}" is not invokable!`); const result = await functionToInvoke(...args); return (0, RMIRemoteResult_1.createRMIRemoteResult)(id, result); }; exports.handleRequest = handleRequest; const exposeFunctions = ({ ws, config: { logger: log } }, functions) => { ws.addEventListener("message", async ({ data }) => { log.debug(`Client sent "${data}"`); let request; try { request = JSON.parse(data); } catch (e) { log.debug(`Error parsing "${data}"; Cause:\n${e}`); return; } log.debug("Data is valid JSON. Validating as RMI Request..."); if (!(0, RMIRequest_1.validateRMIRequest)(request)) { log.debug(`Request was invalid! Request was\n${request}`); return; } if (request.rmi.type !== "REQUEST") return; let response; try { log.info("Client sent a valid RMI Request. Attempting to invoke function..."); response = await (0, exports.handleRequest)(request, functions); } catch (e) { log.info(`There was an error during invocation of a function. Request was:\n${request}\nError was:\n${e}`); response = (0, RMIRemoteError_1.createRMIRemoteError)(request.rmi.id, "An unexpected error occurred during invocation."); } const responseString = JSON.stringify(response); log.info(`Request handled; Sending the following back to client:\n${responseString}`); ws.send(responseString); }); }; exports.exposeFunctions = exposeFunctions;