UNPKG

nd-json-rpc-protocol

Version:

A protocol encapsulating json-rpc massages with new line delimited json attached data

142 lines (125 loc) 2.9 kB
import * as jsonRpcProtocol from 'json-rpc-protocol' const { format: _format, InvalidJson, JsonRpcError, parse: _parse } = jsonRpcProtocol export class NdJsonRpcError extends JsonRpcError {} const _do = ({_f, method, error, id, data, params = {}}) => { if (!Array.isArray(data)) { throw new NdJsonRpcError('data is expected as an Array') } if (params.size !== undefined) { throw new NdJsonRpcError('size is a reserved nd-json-rpc response property') } params.size = data.length let firstChunk switch (_f) { case 'notification': firstChunk = _format.notification(method, params) break case 'request': firstChunk = _format.request(id, method, params) break case 'response': firstChunk = _format.response(id, params) break case 'error': firstChunk = _format.error(id, error) break default: throw new Error('Unknown or unhandled jsonrpc message format') } let output = firstChunk data.forEach(element => { output = output.concat('\n') output = output.concat(JSON.stringify(element)) }) return output } const notification = (method, params, data = []) => { return _do({ _f: 'notification', method, params, data }) } const request = (id, method, params, data) => { return _do({ _f: 'request', id, method, params, data }) } const response = (id, params, data = []) => { return _do({ _f: 'response', id, params, data }) } const error = (id, error) => { return _do({ _f: 'error', id, error }) } /* * returns { jsonrpcMessage, data} * * where `jsonrpcMessage` is a json-rpc message object, and `data` an array * * `jsonrpcMessage` can be a json-rpc error * `data` can be undefined * * If `data` is defined, `jsonrpc.size` will give its number of elements */ export const parse = response => { response = response.split('\n') let firstChunk try { firstChunk = _parse(response.shift()) } catch (error) { if (error instanceof InvalidJson) { throw new NdJsonRpcError('First chunk is not a well-formed json-rpc response', error.code) } throw error } const { error } = firstChunk if (error !== undefined) { return { jsonrpcMessage: firstChunk } } if (firstChunk.result.size !== response.length) { throw new NdJsonRpcError('Data does not match its given size') } try { response = response.map(chunk => JSON.parse(chunk)) } catch (error) { if (error instanceof SyntaxError) { throw new NdJsonRpcError('Some data items are not well-formed JSON') } } return { jsonrpcMessage: firstChunk, data: response } } export const format = { error, notification, request, response } export { InvalidJson, InvalidParameters, InvalidRequest, JsonRpcError, MethodNotFound } from 'json-rpc-protocol'