diff --git a/README.md b/README.md index ab255da..f156908 100644 --- a/README.md +++ b/README.md @@ -8,92 +8,55 @@ A strictly typed json-rpc(2.0) implementation, zero dependency, minimal abstract > Specification -```ts -const methodSet = { - upper: (str: string) => str.toUpperCase(), - lower: (str: string) => str.toLowerCase(), - plus: ([a, b]: [number, number]) => a + b, - minus: ([a, b]: [number, number]) => a - b, -} - -// initialize all methods with the constructor -const server = new JSONRPCServer(methodSet) - -// or add methods manually -const server = new JSONRPCServer() -server.setMethod('upper', methodSet.upper) -server.setMethod('lower', methodSet.lower) -server.setMethod('plus', methodSet.plus) -server.setMethod('minus', methodSet.minus) - -// (optional) provide a generic parameter to enable ts check -const client = new JSONRPCClient((json) => - server.process(json) -) - -// request, Notification and batch are always async -assertEquals(await client.request('upper', 'hello'), 'HELLO') - -assertEquals( - await client.batch( - client.createRequest('upper', 'nihao'), - // Notification does not have response, even when response errors - client.createNotification('upper'), - client.createRequest('upper', 'shijie'), - client.createRequest('plus', [1, 1]), - ), - [ - { - status: 'fulfilled', - value: 'NIHAO', - }, - { - status: 'fulfilled', - value: 'SHIJIE', - }, - { - status: 'fulfilled', - value: 2, - }, - ], -) -``` - Example to use the client ```ts -const client = new JSONRPCClient((json) => +const requestForResponse = (json: string) => fetch('http://localhost:6800/jsonrpc', { method: 'POST', body: json, }).then((res) => res.text()) -) -const aria2cMethods = await client.request('system.listMethods') +const client = new JSONRPCClient<{ + 'aria2.addUri': ( + urls: string[], + options?: object, + position?: number, + ) => string + 'aria2.remove': (gid: string) => string + 'system.listMethods': () => string[] +}>(requestForResponse) + +const resultGid: string = await client.request('aria2.addUri', [ + ['https://example.net/index.html'], + {}, + 0, +]) ``` Example to use the server ```ts -const server = new JSONRPCServer() +const server = new JSONRPCServer({ + upper: (str: string) => str.toUpperCase(), + lower: (str: string) => str.toLowerCase(), + plus: ([a, b]: [number, number]) => a + b, + minus: ([a, b]: [number, number]) => a - b, +}) +// or: server.setMethod('trim', (str: string) => str.trim()) server.setMethod('trimStart', (str: string) => str.trimStart()) server.setMethod('trimEnd', (str: string) => str.trimEnd()) const httpServer = Deno.serve( async (request) => { - const url = new URL(request.url) - if (url.pathname === '/jsonrpc') { - return new Response( - // server.process() accept string and returns Promise - await server.process(await request.text()), - { - headers: { 'content-type': 'application/json' }, - }, - ) - } - return new Response('404', { status: 404 }) + // server.handleRequest() accept string and returns Promise + const jsonString = await server.handleRequest(await request.text()) + + return new Response(jsonString, { + headers: { 'content-type': 'application/json' }, + }) }, ) ``` diff --git a/deno.json b/deno.json index 92aa364..3be69dc 100644 --- a/deno.json +++ b/deno.json @@ -5,7 +5,7 @@ "noImplicitOverride": true }, "imports": { - "std/": "https://deno.land/std@0.209.0/" + "std/": "https://deno.land/std@0.213.0/" }, "tasks": { "lint": "deno lint", diff --git a/deno.lock b/deno.lock index 7e52cfa..3d9fe23 100644 --- a/deno.lock +++ b/deno.lock @@ -32,6 +32,38 @@ "https://deno.land/std@0.209.0/assert/mod.ts": "37c49a26aae2b254bbe25723434dc28cd7532e444cf0b481a97c045d110ec085", "https://deno.land/std@0.209.0/assert/unimplemented.ts": "4e3e504792c87c485dbc5f4020489d8806ef697741403af2008dfa7b5a4711e8", "https://deno.land/std@0.209.0/assert/unreachable.ts": "1af8c99421cc5fb7332454b2b9eca074a4e394895a180bc837750dedcca75338", - "https://deno.land/std@0.209.0/fmt/colors.ts": "34b3f77432925eb72cf0bfb351616949746768620b8e5ead66da532f93d10ba2" + "https://deno.land/std@0.209.0/fmt/colors.ts": "34b3f77432925eb72cf0bfb351616949746768620b8e5ead66da532f93d10ba2", + "https://deno.land/std@0.213.0/assert/_constants.ts": "a271e8ef5a573f1df8e822a6eb9d09df064ad66a4390f21b3e31f820a38e0975", + "https://deno.land/std@0.213.0/assert/_diff.ts": "dcc63d94ca289aec80644030cf88ccbf7acaa6fbd7b0f22add93616b36593840", + "https://deno.land/std@0.213.0/assert/_format.ts": "0ba808961bf678437fb486b56405b6fefad2cf87b5809667c781ddee8c32aff4", + "https://deno.land/std@0.213.0/assert/assert.ts": "bec068b2fccdd434c138a555b19a2c2393b71dfaada02b7d568a01541e67cdc5", + "https://deno.land/std@0.213.0/assert/assert_almost_equals.ts": "8b96b7385cc117668b0720115eb6ee73d04c9bcb2f5d2344d674918c9113688f", + "https://deno.land/std@0.213.0/assert/assert_array_includes.ts": "1688d76317fd45b7e93ef9e2765f112fdf2b7c9821016cdfb380b9445374aed1", + "https://deno.land/std@0.213.0/assert/assert_equals.ts": "4497c56fe7d2993b0d447926702802fc0becb44e319079e8eca39b482ee01b4e", + "https://deno.land/std@0.213.0/assert/assert_exists.ts": "24a7bf965e634f909242cd09fbaf38bde6b791128ece08e33ab08586a7cc55c9", + "https://deno.land/std@0.213.0/assert/assert_false.ts": "6f382568e5128c0f855e5f7dbda8624c1ed9af4fcc33ef4a9afeeedcdce99769", + "https://deno.land/std@0.213.0/assert/assert_greater.ts": "4945cf5729f1a38874d7e589e0fe5cc5cd5abe5573ca2ddca9d3791aa891856c", + "https://deno.land/std@0.213.0/assert/assert_greater_or_equal.ts": "573ed8823283b8d94b7443eb69a849a3c369a8eb9666b2d1db50c33763a5d219", + "https://deno.land/std@0.213.0/assert/assert_instance_of.ts": "72dc1faff1e248692d873c89382fa1579dd7b53b56d52f37f9874a75b11ba444", + "https://deno.land/std@0.213.0/assert/assert_is_error.ts": "6596f2b5ba89ba2fe9b074f75e9318cda97a2381e59d476812e30077fbdb6ed2", + "https://deno.land/std@0.213.0/assert/assert_less.ts": "2b4b3fe7910f65f7be52212f19c3977ecb8ba5b2d6d0a296c83cde42920bb005", + "https://deno.land/std@0.213.0/assert/assert_less_or_equal.ts": "b93d212fe669fbde959e35b3437ac9a4468f2e6b77377e7b6ea2cfdd825d38a0", + "https://deno.land/std@0.213.0/assert/assert_match.ts": "ec2d9680ed3e7b9746ec57ec923a17eef6d476202f339ad91d22277d7f1d16e1", + "https://deno.land/std@0.213.0/assert/assert_not_equals.ts": "f3edda73043bc2c9fae6cbfaa957d5c69bbe76f5291a5b0466ed132c8789df4c", + "https://deno.land/std@0.213.0/assert/assert_not_instance_of.ts": "8f720d92d83775c40b2542a8d76c60c2d4aeddaf8713c8d11df8984af2604931", + "https://deno.land/std@0.213.0/assert/assert_not_match.ts": "b4b7c77f146963e2b673c1ce4846473703409eb93f5ab0eb60f6e6f8aeffe39f", + "https://deno.land/std@0.213.0/assert/assert_not_strict_equals.ts": "da0b8ab60a45d5a9371088378e5313f624799470c3b54c76e8b8abeec40a77be", + "https://deno.land/std@0.213.0/assert/assert_object_match.ts": "e85e5eef62a56ce364c3afdd27978ccab979288a3e772e6855c270a7b118fa49", + "https://deno.land/std@0.213.0/assert/assert_rejects.ts": "e9e0c8d9c3e164c7ac962c37b3be50577c5a2010db107ed272c4c1afb1269f54", + "https://deno.land/std@0.213.0/assert/assert_strict_equals.ts": "0425a98f70badccb151644c902384c12771a93e65f8ff610244b8147b03a2366", + "https://deno.land/std@0.213.0/assert/assert_string_includes.ts": "dfb072a890167146f8e5bdd6fde887ce4657098e9f71f12716ef37f35fb6f4a7", + "https://deno.land/std@0.213.0/assert/assert_throws.ts": "edddd86b39606c342164b49ad88dd39a26e72a26655e07545d172f164b617fa7", + "https://deno.land/std@0.213.0/assert/assertion_error.ts": "9f689a101ee586c4ce92f52fa7ddd362e86434ffdf1f848e45987dc7689976b8", + "https://deno.land/std@0.213.0/assert/equal.ts": "fae5e8a52a11d3ac694bbe1a53e13a7969e3f60791262312e91a3e741ae519e2", + "https://deno.land/std@0.213.0/assert/fail.ts": "f310e51992bac8e54f5fd8e44d098638434b2edb802383690e0d7a9be1979f1c", + "https://deno.land/std@0.213.0/assert/mod.ts": "325df8c0683ad83a873b9691aa66b812d6275fc9fec0b2d180ac68a2c5efed3b", + "https://deno.land/std@0.213.0/assert/unimplemented.ts": "47ca67d1c6dc53abd0bd729b71a31e0825fc452dbcd4fde4ca06789d5644e7fd", + "https://deno.land/std@0.213.0/assert/unreachable.ts": "38cfecb95d8b06906022d2f9474794fca4161a994f83354fd079cac9032b5145", + "https://deno.land/std@0.213.0/fmt/colors.ts": "aeaee795471b56fc62a3cb2e174ed33e91551b535f44677f6320336aabb54fbb" } } diff --git a/src/client.test.ts b/src/client.test.ts index a40158d..0282402 100644 --- a/src/client.test.ts +++ b/src/client.test.ts @@ -223,6 +223,47 @@ Deno.test('client/JSONRPCClientParseError', async () => { ).catch((e) => e), JSONRPCClientParseError, ) + + client = new JSONRPCClient(() => + JSON.stringify( + { + jsonrpc: '2.0', + id: null, + error: { + code: 0, + message: 'ERR_MSG', + }, + }, + ) + ) + + assertEquals( + await client.batch( + client.createRequest('foo1'), + client.createRequest('foo2'), + client.createRequest('foo3'), + ).catch((e) => e.message), + 'ERR_MSG', + ) + + client = new JSONRPCClient(() => + JSON.stringify( + { + jsonrpc: '2.0', + id: null, + result: 'wrong server', + }, + ) + ) + + assertInstanceOf( + await client.batch( + client.createRequest('foo1'), + client.createRequest('foo2'), + client.createRequest('foo3'), + ).catch((e) => e), + JSONRPCClientParseError, + ) }) Deno.test({ diff --git a/src/client.ts b/src/client.ts index df167ea..df64b85 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,4 +1,4 @@ -import type { JSONRPCMethodSet, JSONRPCSettledResult } from './types.ts' +import type { JSONRPCMethods, JSONRPCSettledResult } from './types.ts' import { JSONRPCNotification, JSONRPCRequest } from './dto/request.ts' import { JSONRPCErrorResponse, JSONRPCSuccessResponse } from './dto/response.ts' import { isJSONRPCResponse, JSONRPCResponse } from './dto/response.ts' @@ -9,72 +9,49 @@ import { selfAddIdGenerator, } from './id.ts' -type JSONRPCAnyRequest = - | JSONRPCNotification - | JSONRPCRequest - | Array - -/** - * The client cannot parse the server response - */ -export class JSONRPCClientParseError extends Error { - override name = 'JSONRPCClientParseError' - request: JSONRPCAnyRequest - constructor(message: string, request: JSONRPCAnyRequest) { - super(message) - this.request = request - } -} - -/** - * Just wrap the JSON.parse function, with potential `JSONRPCClientParseError` - */ -function parseJSON( - text: string, - associatedRequest: JSONRPCAnyRequest, -): unknown { - try { - return JSON.parse(text) - } catch { - throw new JSONRPCClientParseError( - `The server send an malformed json`, - associatedRequest, - ) - } -} - /** - * Provide a external `processor` function to the constructor, - * it should accept a string (json encoded from one or more json rpc request) - * and your customized code should send this string to a json rpc server - * for any response represented as **string** + * Provide a external `requestForResponse` function to the constructor, + * it should accept a `string` (json encoded from one or more json rpc request) + * and your customized function should send this string to a json rpc server + * for any response represented as `string` * * The constructor optionally accept a customized id generator, otherwise it use a * self added number + * + * To customize the request or response, you can extend `JSONRPCClient`. + * + * To customize request, overwrite `createRequest` and `createNotification` methods. + * + * To customize response, overwrite `request` `notify` and `batch` methods. */ export class JSONRPCClient< - MethodSet extends JSONRPCMethodSet = JSONRPCMethodSet, + Methods extends JSONRPCMethods = JSONRPCMethods, > { /** * MUST be an infinite iterator */ - private idGenerator: IDGenerator + protected idGenerator: IDGenerator /** - * The extern function to request the server for response + * The external function to send the json string to any rpc server, + * and fetch for response as string */ - private processor: (input: string) => string | Promise + protected requestForResponse: (input: string) => string | Promise - constructor( - processor: (input: string) => string | Promise, + /** + * @param requestForResponse An external function to send the json string to any rpc server, + * and fetch for response as string + */ + public constructor( + requestForResponse: (input: string) => string | Promise, idGenerator?: IDGenerator, ) { - this.processor = processor + this.requestForResponse = requestForResponse this.idGenerator = idGenerator || selfAddIdGenerator() } - public createRequest( + public createRequest( method: T extends string ? T : never, - params?: Parameters[0], + params?: Parameters[0], ): JSONRPCRequest { const id = getIDFromGenerator(this.idGenerator) const request = new JSONRPCRequest({ @@ -85,9 +62,9 @@ export class JSONRPCClient< return request } - public createNotification( + public createNotification( method: T extends string ? T : never, - params?: Parameters[0], + params?: Parameters[0], ): JSONRPCNotification { const notification = new JSONRPCNotification({ method, @@ -99,13 +76,15 @@ export class JSONRPCClient< /** * Send `JSONRPCRequest` to server, returns `JSONRPCValue` or throw `JSONRPCErrorInterface` (or `JSONRPCClientParseError`) */ - async request( + public async request( method: T extends string ? T : never, - params?: Parameters[0], - ): Promise> { + params?: Parameters[0], + ): Promise> { const request = this.createRequest(method, params) // responded json string - const jsonString = await this.processor(JSON.stringify(request)) + const jsonString = await this.requestForResponse( + JSON.stringify(request), + ) const jsonValue = parseJSON(jsonString, request) // parsed response @@ -130,7 +109,7 @@ export class JSONRPCClient< } // response.result is now JSONRPCValue - return response.result as ReturnType + return response.result as ReturnType } } @@ -138,12 +117,12 @@ export class JSONRPCClient< * Send `JSONRPCNotification` to server, no returns, * only throws if your provided `processor` function throws */ - async notify( + public async notify( method: T extends string ? T : never, - params?: Parameters[0], + params?: Parameters[0], ): Promise { const notification = this.createNotification(method, params) - await this.processor(JSON.stringify(notification)) + await this.requestForResponse(JSON.stringify(notification)) } /** @@ -170,11 +149,13 @@ export class JSONRPCClient< * @throws `JSONRPCError` - when server return single JSONRPCErrorResponse * @throws `JSONRPCClientParseError` - when server response cannot be parsed */ - async batch( + public async batch( ...requests: Array ): Promise { // responded json string - const jsonString = await this.processor(JSON.stringify(requests)) + const jsonString = await this.requestForResponse( + JSON.stringify(requests), + ) const requestCount = requests.filter((r) => 'id' in r).length if (requestCount === 0) { // all the requests are notification @@ -256,3 +237,37 @@ export class JSONRPCClient< return responses } } + +type JSONRPCAnyRequest = + | JSONRPCNotification + | JSONRPCRequest + | Array + +/** + * The client cannot parse the server response + */ +export class JSONRPCClientParseError extends Error { + override name = 'JSONRPCClientParseError' + request: JSONRPCAnyRequest + constructor(message: string, request: JSONRPCAnyRequest) { + super(message) + this.request = request + } +} + +/** + * Just wrap the JSON.parse function, with potential `JSONRPCClientParseError` + */ +function parseJSON( + text: string, + associatedRequest: JSONRPCAnyRequest, +): unknown { + try { + return JSON.parse(text) + } catch { + throw new JSONRPCClientParseError( + `The server send an malformed json`, + associatedRequest, + ) + } +} diff --git a/src/index.test.ts b/src/index.test.ts index 112d029..08aaafb 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -2,17 +2,17 @@ import { assertEquals, assertObjectMatch } from 'std/assert/mod.ts' import { JSONRPCClient, JSONRPCServer } from './index.ts' Deno.test('JSONRPCClient/JSONRPCServer', async () => { - const methodSet = { + const methods = { upper: (str: string) => str.toUpperCase(), lower: (str: string) => str.toLowerCase(), plus: ([a, b]: [number, number]) => a + b, minus: ([a, b]: [number, number]) => a - b, } - const server = new JSONRPCServer(methodSet) + const server = new JSONRPCServer(methods) - const client = new JSONRPCClient((json) => - server.process(json) + const client = new JSONRPCClient((json) => + server.handleRequest(json) ) assertEquals(await client.request('upper', 'hello'), 'HELLO') @@ -83,7 +83,7 @@ Deno.test({ const url = new URL(request.url) if (url.pathname === '/jsonrpc') { return new Response( - await server.process(await request.text()), + await server.handleRequest(await request.text()), { headers: { 'content-type': 'application/json' }, }, diff --git a/src/server.test.ts b/src/server.test.ts index c9b48a4..84094d9 100644 --- a/src/server.test.ts +++ b/src/server.test.ts @@ -25,7 +25,7 @@ Deno.test( assertEquals( isJSONRPCError( JSON.parse( - await server.process(JSON.stringify({ + await server.handleRequest(JSON.stringify({ id: 1, params: ' trim ', })), @@ -36,14 +36,14 @@ Deno.test( assertEquals( isJSONRPCError( - JSON.parse(await server.process('malformed json')).error, + JSON.parse(await server.handleRequest('malformed json')).error, ), true, ) assertObjectMatch( JSON.parse( - await server.process('[]'), + await server.handleRequest('[]'), ), { id: null, @@ -52,7 +52,7 @@ Deno.test( ) assertEquals( - await server.process(JSON.stringify([{ + await server.handleRequest(JSON.stringify([{ jsonrpc: '2.0', method: 'trim', }])), @@ -61,7 +61,7 @@ Deno.test( assertObjectMatch( JSON.parse( - await server.process(JSON.stringify([{ + await server.handleRequest(JSON.stringify([{ jsonrpc: '2.0', id: 1, params: ' trim ', @@ -78,7 +78,7 @@ Deno.test( assertObjectMatch( JSON.parse( - await server.process(JSON.stringify([{ + await server.handleRequest(JSON.stringify([{ id: null, params: ' trim ', }])), @@ -91,7 +91,7 @@ Deno.test( assertObjectMatch( JSON.parse( - await server.process(JSON.stringify([{ + await server.handleRequest(JSON.stringify([{ jsonrpc: '2.0', id: 1, method: 'trim', @@ -100,6 +100,10 @@ Deno.test( id: 2, method: 'trim', params: ' trim ', + }, { + id: ['invalid id'], + method: 'trim', + params: ' trim ', }])), ), { @@ -109,7 +113,21 @@ Deno.test( id: 2, error: { code: -32600, message: 'Invalid Request' }, }, + 2: { + jsonrpc: '2.0', + id: null, + error: { code: -32600, message: 'Invalid Request' }, + }, }, ) + + assertEquals( + await server.handleRequest(JSON.stringify([{ + jsonrpc: '2.0', + method: 'trim', + params: 'only notification', + }])), + '', + ) }, ) diff --git a/src/server.ts b/src/server.ts index 29a44a3..1d223d2 100644 --- a/src/server.ts +++ b/src/server.ts @@ -16,49 +16,54 @@ import { JSONRPCSuccessResponse, } from './dto/response.ts' import { isJSONRPCID } from './id.ts' -import type { JSONRPCMethodSet, JSONRPCValue } from './types.ts' +import type { JSONRPCMethods, JSONRPCValue } from './types.ts' /** * Provide a method set object to the constructor, it should contains * a record with it's key is a string and value is a function * that handle the rpc calls. * - * See `JSONRPCMethodSet` for how method in method set should be. + * See `JSONRPCMethods` for how method in method set should be. * * Note: avoid using `this` in method! + * + * To customize how your server handle request, extend `JSONRPCServer` and + * overwrite `getMethod` method, using this method, you can forward request + * params to an existing method in `methods` */ export class JSONRPCServer< - MethodSet extends JSONRPCMethodSet = JSONRPCMethodSet, + Methods extends JSONRPCMethods = JSONRPCMethods, > { - private methodSet: MethodSet + protected methods: Methods constructor() - constructor(methodSet: MethodSet) - constructor(methodSet?: MethodSet) { - this.methodSet = methodSet || ({} as MethodSet) + constructor(methods: Methods) + constructor(methods?: Methods) { + this.methods = methods || ({} as Methods) } /** * Override this function, to customize the behavior - * when method is not in methodSet. + * when method is not in `methods`. * * You can also use this method to handle dynamic * method name if you like, but make sure you manually * throw `JSONRPCMethodNotFoundError` when required */ - public methodNotFound(): JSONRPCValue { + // deno-lint-ignore no-unused-vars no-explicit-any + public methodNotFound(params: any): JSONRPCValue { throw new JSONRPCMethodNotFoundError() } /** - * Use this to get method in methodSet by method name + * Use this to get method in `methods` by method name */ - public getMethod( + public getMethod( method: T, - ): MethodSet[T] | undefined { - const prop = this.methodSet[method] + ): Methods[T] | undefined { + const prop = this.methods[method] if (typeof prop === 'function') { - return prop.bind(this.methodSet) as MethodSet[T] + return prop.bind(this.methods) as Methods[T] } return undefined @@ -67,11 +72,11 @@ export class JSONRPCServer< /** * Use this to replace or add more methods */ - public setMethod( + public setMethod( method: T, - fn: MethodSet[T], + fn: Methods[T], ) { - Reflect.set(this.methodSet, method, fn) + Reflect.set(this.methods, method, fn) return this } @@ -79,8 +84,8 @@ export class JSONRPCServer< * Given any string as input, return response as json string * @noexcept */ - public async process(input: string): Promise { - const resp = await this.processAnyRequest(input) + public async handleRequest(input: string): Promise { + const resp = await this.processAnyJsonString(input) if (!resp) { return '' } @@ -92,10 +97,10 @@ export class JSONRPCServer< /** * Process request or batch request, return corresponding value - * @returns corresponding response object or array or some other thing + * @returns Corresponding response object or array or some other thing * @noexcept */ - private async processAnyRequest( + private async processAnyJsonString( jsonString: string, ): Promise { let jsonValue: unknown @@ -124,14 +129,16 @@ export class JSONRPCServer< // just run each method in the event loop // and immediately return nothing Promise.allSettled( - jsonValue.map((r) => this.processOneRequest(r)), + jsonValue.map((r) => this.processSingleRequest(r)), ) + // If there are no Response objects contained within the Response array as it is to be sent to the client, + // the server MUST NOT return an empty Array and should return nothing at all. return } const batchReturnValue: JSONRPCResponse[] = [] for (const singleJsonValue of jsonValue) { - const returnValue = await this.processOneJsonValue( + const returnValue = await this.processSingleJsonValue( singleJsonValue, ) if (returnValue) { @@ -139,15 +146,14 @@ export class JSONRPCServer< } // there SHOULD NOT be any Response objects for notifications } - if (batchReturnValue.length === 0) { - // If there are no Response objects contained within the Response array as it is to be sent to the client, - // the server MUST NOT return an empty Array and should return nothing at all. - return - } + //? `batchReturnValue.length` MUST greater that 0 + // if (batchReturnValue.length === 0) { + // return + // } return batchReturnValue } // single request - return this.processOneJsonValue(jsonValue) + return this.processSingleJsonValue(jsonValue) } /** @@ -155,12 +161,12 @@ export class JSONRPCServer< * @returns `JSONRPCResponse` if is request, or `undefined` if is Notification * @noexcept */ - private async processOneJsonValue( + private async processSingleJsonValue( jsonValue: unknown, ): Promise { if (isJSONRPCRequest(jsonValue)) { // request or notification - return await this.processOneRequest(jsonValue) + return await this.processSingleRequest(jsonValue) } // jsonValue is not a valid Request object @@ -185,15 +191,15 @@ export class JSONRPCServer< } /** - * WARN: this process JSONRPCNotification or JSONRPCRequest + * WARN: this process `JSONRPCNotification` or `JSONRPCRequest` * @noexcept */ - private async processOneRequest( + private async processSingleRequest( request: JSONRPCNotification | JSONRPCRequest, ): Promise { const { method, params } = request - // load method from methodSet or use the methodNotFound() function as fallback + // load method from `methods` or use the `methodNotFound()` function as fallback const methodFn = this.getMethod(method) || this.methodNotFound.bind(this) diff --git a/src/types.ts b/src/types.ts index 05ffe1f..47d332e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,7 +21,7 @@ export type ArrayValue = Array * * Note that client is allowed to send no params, meaning that params can also be `undefined` */ -export interface JSONRPCMethodSet { +export interface JSONRPCMethods { [method: string]: JSONRPCMethod }