UNPKG

json-rpc-protocol

Version:

JSON-RPC 2 protocol messages parsing and formatting

163 lines 5.45 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.parse = exports.isResponsePayload = exports.isErrorPayload = exports.isRequestPayload = exports.isNotificationPayload = void 0; // =================================================================== var types_1 = require("./types"); var errors_1 = require("./errors"); // =================================================================== var defineProperty = Object.defineProperty; var setMessageType = function (message, type) { return defineProperty(message, 'type', { configurable: true, value: type, writable: true }); }; var getType = function (value) { return (value === null ? 'null' : typeof value); }; var checkError = function (error, version) { if (version === '1.0') { if (error == null) { throw new errors_1.InvalidRequest("invalid error " + getType(error)); } } else if (error == null || !types_1.isInteger(error.code) || !types_1.isString(error.message)) { throw new errors_1.InvalidRequest("invalid error: " + getType(error) + " instead of {code, message}"); } }; var checkId = function (id) { if (!types_1.isNumber(id) && !types_1.isString(id)) { throw new errors_1.InvalidRequest("invalid identifier: " + getType(id) + " instead of number or string"); } }; var checkParams = function (params, version) { if (version === '2.0') { if (params !== undefined && !Array.isArray(params) && !types_1.isObject(params)) { throw new errors_1.InvalidRequest("invalid params: " + getType(params) + " instead of undefined, array or object"); } } else { if (!Array.isArray(params)) { throw new errors_1.InvalidRequest("invalid params: " + getType(params) + " instead of array"); } } }; var detectJsonRpcVersion = function (_a) { var jsonrpc = _a.jsonrpc; if (jsonrpc === undefined) { return '1.0'; } if (jsonrpc === '2.0') { return '2.0'; } throw new errors_1.InvalidRequest("invalid version: " + getType(jsonrpc) + " instead of undefined or '2.0'"); }; var isNotificationId = function (id, version) { return id === (version === '2.0' ? undefined : null); }; var isErrorResponse = function (_a, version) { var error = _a.error; return error !== (version === '2.0' ? undefined : null); }; exports.isNotificationPayload = function (message, version) { if (types_1.isString(message.method)) { var id = message.id; if (isNotificationId(id, version)) { checkParams(message.params, version); return true; } } return false; }; exports.isRequestPayload = function (message, version) { if (types_1.isString(message.method)) { var id = message.id; if (!isNotificationId(id, version)) { checkId(id); checkParams(message.params, version); return true; } } return false; }; exports.isErrorPayload = function (message, version) { if (!types_1.isString(message.method)) { if (isErrorResponse(message, version)) { var id = message.id; if (id !== null) { checkId(id); } checkError(message.error, version); return true; } } return false; }; exports.isResponsePayload = function (message, version) { if (!types_1.isString(message.method)) { if (!isErrorResponse(message, version)) { checkId(message.id); return true; } } return false; }; // Parses, normalizes and validates a JSON-RPC message. // // The returns value is an object containing the normalized fields of // the JSON-RPC message and an additional `type` field which contains // one of the following: `notification`, request`, `response` or // `error`. function parse(message) { if (types_1.isString(message)) { try { message = JSON.parse(message); } catch (error) { if (error instanceof SyntaxError) { throw new errors_1.InvalidJson(); } throw error; } } // Properly handle array of requests. if (Array.isArray(message)) { return message.map(parse); } var version = detectJsonRpcVersion(message); if (exports.isNotificationPayload(message, version)) { setMessageType(message, 'notification'); } else if (exports.isRequestPayload(message, version)) { setMessageType(message, 'request'); } else if (exports.isErrorPayload(message, version)) { setMessageType(message, 'error'); } else if (exports.isResponsePayload(message, version)) { setMessageType(message, 'response'); } else { throw new errors_1.InvalidJson(); } return message; } exports.parse = parse; exports.default = parse; // Parses a response/error message // // Returns the result of the response or throws the error. parse.result = function result(message) { var parsed = parse(message); if (!Array.isArray(parsed)) { if (parsed.type === 'error') { throw parsed.error; } if (parsed.type === 'response') { return parsed.result; } } throw new TypeError('message should be response or error JSON-RPC message'); }; //# sourceMappingURL=parse.js.map