UNPKG

picorpc

Version:

A tiny RPC library and spec, inspired by JSON-RPC 2.0 and tRPC.

55 lines (54 loc) 3.52 kB
/* IMPORT */ import { ERROR_CODE_INVALID_REQUEST, ERROR_MESS_INVALID_REQUEST } from '../constants.js'; import { ERROR_CODE_INVALID_VERSION, ERROR_MESS_INVALID_VERSION } from '../constants.js'; import { ERROR_CODE_UNSUPPORTED_VERSION, ERROR_MESS_UNSUPPORTED_VERSION } from '../constants.js'; import { ERROR_CODE_INVALID_ID, ERROR_MESS_INVALID_ID } from '../constants.js'; import { ERROR_CODE_INVALID_PROCEDURE_NAME, ERROR_MESS_INVALID_PROCEDURE_NAME } from '../constants.js'; import { ERROR_CODE_INVALID_PROCEDURE_PARAMS, ERROR_MESS_INVALID_PROCEDURE_PARAMS } from '../constants.js'; import { ERROR_CODE_INVALID_CONTEXT, ERROR_MESS_INVALID_CONTEXT } from '../constants.js'; import { ERROR_CODE_FAILED_PROCEDURE_EXEC, ERROR_MESS_FAILED_PROCEDURE_EXEC } from '../constants.js'; import { FALLBACK_RESPONSE_ID } from '../constants.js'; import { VERSION } from '../constants.js'; import ResponseError from '../objects/response_error.js'; import ResponseSuccess from '../objects/response_success.js'; import { castError, isArray, isInteger, isObject, isString, isUndefined, isVersionCompatible } from '../utils.js'; /* MAIN */ const createAbstractServer = (options) => { const { procedures, handler } = options; return { handle: async (request) => { if (!isObject(request)) return new ResponseError(handler, FALLBACK_RESPONSE_ID, ERROR_CODE_INVALID_REQUEST, ERROR_MESS_INVALID_REQUEST); if (!isString(request.id)) return new ResponseError(handler, FALLBACK_RESPONSE_ID, ERROR_CODE_INVALID_ID, ERROR_MESS_INVALID_ID); if (!isString(request.version)) return new ResponseError(handler, request.id, ERROR_CODE_INVALID_VERSION, ERROR_MESS_INVALID_VERSION); if (!isVersionCompatible(request.version, VERSION)) return new ResponseError(handler, request.id, ERROR_CODE_UNSUPPORTED_VERSION, ERROR_MESS_UNSUPPORTED_VERSION); if (!isString(request.method) || !procedures.hasOwnProperty(request.method)) return new ResponseError(handler, request.id, ERROR_CODE_INVALID_PROCEDURE_NAME, ERROR_MESS_INVALID_PROCEDURE_NAME); if (!Array.isArray(request.params) && !isUndefined(request.params)) return new ResponseError(handler, request.id, ERROR_CODE_INVALID_PROCEDURE_PARAMS, ERROR_MESS_INVALID_PROCEDURE_PARAMS); if ((!isObject(request.context) && !isUndefined(request.context)) || isArray(request.context)) return new ResponseError(handler, request.id, ERROR_CODE_INVALID_CONTEXT, ERROR_MESS_INVALID_CONTEXT); try { const id = request.id; const method = request.method; const params = request.params || []; const context = request.context; const result = await procedures[method].apply(context, params); return new ResponseSuccess(handler, id, result); } catch (exception) { const id = request.id; const error = castError(exception); const code = isInteger(error.code) && (error.code >= 0) ? error.code : ERROR_CODE_FAILED_PROCEDURE_EXEC; const message = isString(error.message) ? error.message : ERROR_MESS_FAILED_PROCEDURE_EXEC; const data = error.data; return new ResponseError(handler, id, code, message, data); } } }; }; /* EXPORT */ export default createAbstractServer;