json-rpc-protocol
Version:
JSON-RPC 2 protocol messages parsing and formatting
163 lines • 5.45 kB
JavaScript
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
;