Skip to content

Commit

Permalink
Add new RpcRequest, RpcResponse types and their transformer types
Browse files Browse the repository at this point in the history
  • Loading branch information
lorisleiva committed Aug 23, 2024
1 parent 39ddfd0 commit e236173
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
41 changes: 41 additions & 0 deletions packages/rpc-spec/src/__tests__/rpc-shared-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import '@solana/test-matchers/toBeFrozenObject';

import { createJsonRpcResponseTransformer, RpcRequest, RpcResponse } from '../rpc-shared';

describe('createJsonRpcResponseTransformer', () => {
it('can alter the value of the json Promise', async () => {
expect.assertions(2);

// Given a request and a response that returns a number.
const request = { methodName: 'someMethod', params: [123] };
const response = {
json: () => Promise.resolve(123),
text: () => Promise.resolve('123'),
};

// When we create a JSON transformer that doubles the number.
const transformer = createJsonRpcResponseTransformer((json: unknown) => (json as number) * 2);

// Then the transformed response should return the doubled number.
const transformedResponse = transformer(response, request);
transformedResponse satisfies RpcResponse<number>;
await expect(transformedResponse.json()).resolves.toBe(246);

// But the text should remain the same.
await expect(transformedResponse.text()).resolves.toBe('123');
});

it('returns a frozen object as the Reponse', () => {
// Given any response.
const response = {
json: () => Promise.resolve(123),
text: () => Promise.resolve('123'),
};

// When we pass it through a JSON transformer.
const transformedResponse = createJsonRpcResponseTransformer(x => x)(response, {} as RpcRequest);

// Then we expect the transformed response to be frozen.
expect(transformedResponse).toBeFrozenObject();
});
});
1 change: 1 addition & 0 deletions packages/rpc-spec/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './rpc';
export * from './rpc-api';
export * from './rpc-request';
export * from './rpc-shared';
export * from './rpc-transport';
35 changes: 35 additions & 0 deletions packages/rpc-spec/src/rpc-shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export type RpcRequest<TParams = unknown> = {
readonly methodName: string;
readonly params: TParams;
};

export type RpcResponse<TResponse = unknown> = {
readonly json: () => Promise<TResponse>;
readonly text: () => Promise<string>;
};

export type RpcRequestTransformer = {
<TParams>(request: RpcRequest<unknown>): RpcRequest<TParams>;
};

export type RpcResponseTransformer = {
<TResponse>(response: RpcResponse<unknown>, request: RpcRequest<unknown>): RpcResponse<TResponse>;
};

export type RpcResponseTransformerFor<TResponse> = {
(response: RpcResponse<unknown>, request: RpcRequest<unknown>): RpcResponse<TResponse>;
};

export function createJsonRpcResponseTransformer<TResponse>(
jsonTransformer: (json: unknown, request: RpcRequest) => TResponse,
): RpcResponseTransformerFor<TResponse> {
return function (response: RpcResponse, request: RpcRequest): RpcResponse<TResponse> {
return Object.freeze({
...response,
json: async () => {
const json = await response.json();
return jsonTransformer(json, request);
},
});
};
}

0 comments on commit e236173

Please sign in to comment.