Skip to content

Commit

Permalink
feat(nestjs-json-rpc): default transport for rpc
Browse files Browse the repository at this point in the history
- http transport
- validation
- explorer need service

Closes: #77
  • Loading branch information
klerick committed Mar 11, 2024
1 parent cd0d9d4 commit f89f7cf
Show file tree
Hide file tree
Showing 41 changed files with 1,526 additions and 28 deletions.
28 changes: 0 additions & 28 deletions .verdaccio/config.yml

This file was deleted.

2 changes: 2 additions & 0 deletions apps/json-api-server/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { LoggerModule } from 'nestjs-pino';

import { DatabaseModule } from 'database';
import { ResourcesModule } from './resources/resources.module';
import { RpcModule } from './rpc/rpc.module';
import * as process from 'process';

@Module({
imports: [
DatabaseModule,
ResourcesModule,
RpcModule,
LoggerModule.forRoot({
pinoHttp: {
level: process.env['NODE_ENV'] === 'test' ? 'silent' : 'debug',
Expand Down
13 changes: 13 additions & 0 deletions apps/json-api-server/src/app/rpc/rpc.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { NestjsJsonRpcModule, TransportType } from '@klerick/nestjs-json-rpc';

@Module({
imports: [
NestjsJsonRpcModule.forRootAsync({
path: 'rpc',
transport: TransportType.HTTP,
}),
],
// providers: [ContestRpc, ParseIntArrayPipe, LineUpSchemaPipe],
})
export class RpcModule {}
25 changes: 25 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"extends": ["../../../.eslintrc.base.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/dependency-checks": "error"
}
}
]
}
11 changes: 11 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# nestjs-json-rpc

This library was generated with [Nx](https://nx.dev).

## Building

Run `nx build nestjs-json-rpc` to build the library.

## Running unit tests

Run `nx test nestjs-json-rpc` to execute the unit tests via [Jest](https://jestjs.io).
11 changes: 11 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable */
export default {
displayName: 'nestjs-json-rpc',
preset: '../../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../../coverage/libs/json-rpc/nestjs-json-rpc',
};
10 changes: 10 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@klerick/nestjs-json-rpc",
"version": "0.0.1",
"dependencies": {
"tslib": "^2.3.0"
},
"type": "commonjs",
"main": "./src/index.js",
"typings": "./src/index.d.ts"
}
24 changes: 24 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "nestjs-json-rpc",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/json-rpc/nestjs-json-rpc/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/json-rpc/nestjs-json-rpc",
"tsConfig": "libs/json-rpc/nestjs-json-rpc/tsconfig.lib.json",
"packageJson": "libs/json-rpc/nestjs-json-rpc/package.json",
"main": "libs/json-rpc/nestjs-json-rpc/src/index.ts",
"assets": ["libs/json-rpc/nestjs-json-rpc/*.md"]
}
},
"publish": {
"command": "node tools/scripts/publish.mjs nestjs-json-rpc {args.ver} {args.tag}",
"dependsOn": ["build"]
}
},
"tags": []
}
7 changes: 7 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './lib/nestjs-json-rpc.module';
export { TransportType, CommonRpcConfig, ErrorCodeType } from './lib/types';
export {
fromRpcErrorToRpcErrorObject,
createError,
RpcError,
} from './lib/utils';
18 changes: 18 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/src/lib/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ErrorCodeType } from '../types';

export const JsonRpcMetadataKey = '__rpc-metadata__';
export const JsonRpcMetadataKeyParamPipe = '__rpc-metadata-param-pipe__';

export const MAP_HANDLER = Symbol('MAP_HANDLER');
export const RPC_CONTEXT = Symbol('RPC_CONTEXT');
export const ASYNC_ITERATOR_FACTORY = Symbol('ASYNC_ITERATOR_FACTORY');
export const ZOD_INPUT_DATA = Symbol('ZOD_INPUT_DATA');

export const ErrorCode: Record<ErrorCodeType, number> = {
[ErrorCodeType.ParseError]: -32700,
[ErrorCodeType.InvalidRequest]: -32600,
[ErrorCodeType.MethodNotFound]: -32601,
[ErrorCodeType.InvalidParams]: -32602,
[ErrorCodeType.InternalError]: -32603,
[ErrorCodeType.ServerError]: -32000,
} as const;
45 changes: 45 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/src/lib/decorators/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
applyDecorators,
Inject,
Injectable,
PipeTransform,
SetMetadata,
} from '@nestjs/common';
import { Type } from '@nestjs/common/interfaces';
import {
JsonRpcMetadataKey,
JsonRpcMetadataKeyParamPipe,
RPC_CONTEXT,
} from '../constants';

export const RpcHandler = () => {
return applyDecorators(SetMetadata(JsonRpcMetadataKey, true), Injectable());
};

// export function InjectContext(): PropertyDecorator {
// return (target, key) => {
// Inject(RPC_CONTEXT)(target, key);
// };
// }

export const RpcParamsPipe = (
pipe: Type<PipeTransform> | PipeTransform
): ParameterDecorator => {
return (target, key, index) => {
if (!key) {
throw Error('key is undefined');
}
const args: Record<string, Type<PipeTransform> | PipeTransform> =
Reflect.getMetadata(
JsonRpcMetadataKeyParamPipe,
target.constructor,
key
) || {};
Reflect.defineMetadata(
JsonRpcMetadataKeyParamPipe,
Object.assign(Object.assign({}, args), { [`params:${index}`]: pipe }),
target.constructor,
key
);
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Body, Controller, Inject, Post, UseFilters } from '@nestjs/common';
import { HandlerService } from '../../util/service';
import { InputDataPipe } from '../../util/pipe/input-data.pipe';
import { PayloadRpcData, RpcResult } from '../../../types';
import { RpcErrorObject } from '../../../types/error-payloade';
import { RpcErrorExceptionFilter } from '../filter/rpc-error-exception.filter';

@Controller('/')
export class JsonRpcController {
@Inject(HandlerService) private readonly handlerService!: HandlerService;

@Post('')
@UseFilters(new RpcErrorExceptionFilter())
async handler(
@Body(InputDataPipe) body: PayloadRpcData
): Promise<RpcResult | RpcErrorObject | Array<RpcResult | RpcErrorObject>> {
return this.handlerService.runRpc(body);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common';

import {
RpcError,
fromRpcErrorToRpcErrorObject,
createError,
} from '../../../utils';
import { RpcErrorObject, ErrorCodeType } from '../../../types';

@Catch()
export class RpcErrorExceptionFilter implements ExceptionFilter {
catch(exception: Error, host: ArgumentsHost): void {
let body: RpcErrorObject;
if (exception instanceof RpcError) {
body = fromRpcErrorToRpcErrorObject(exception);
} else {
body = fromRpcErrorToRpcErrorObject(
createError(ErrorCodeType.ServerError, exception.message)
);
}
host.switchToHttp().getResponse().send(body);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { DynamicModule, Provider } from '@nestjs/common';
import { Type } from '@nestjs/common/interfaces/type.interface';
import { ForwardReference } from '@nestjs/common/interfaces/modules/forward-reference.interface';

import { JsonRpcController } from './controllers/json-rpc.controller';

export class HttpTransportModule {
static forRoot(
providers: Provider[],
imports: Array<
Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference
> = []
): DynamicModule {
return {
module: HttpTransportModule,
providers,
controllers: [JsonRpcController],
// exports: [RPC_CONTEXT],
imports,
};
}
}
2 changes: 2 additions & 0 deletions libs/json-rpc/nestjs-json-rpc/src/lib/modules/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './http-transport/http-transport.module';
export * from './util/util.module';
Loading

0 comments on commit f89f7cf

Please sign in to comment.