picorpc
Version:
A tiny RPC library and spec, inspired by JSON-RPC 2.0 and tRPC.
55 lines (54 loc) • 3.52 kB
JavaScript
/* 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;