Skip to content

Commit 0096316

Browse files
authored
Merge pull request #78 from klerick/nestjs-json-api-77
feat(nestjs-json-rpc): default transport for rpc
2 parents fdc6e6b + c852bff commit 0096316

File tree

125 files changed

+4600
-66
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+4600
-66
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ jobs:
2828
key: ${{ runner.os }}-nx-${{ steps.branch-names.outputs.current_branch }}
2929
- run: git branch --track main origin/master
3030
- name: Test and build
31-
run: npx nx affected -t test build --parallel=3 --exclude='json-api-front,json-api-server,json-api-server-e2e,json-shared-type,database,@nestjs-json-api/source'
31+
env:
32+
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
33+
run: npx nx affected -t test build --parallel=3 --exclude='json-api-front,json-api-server,json-api-server-e2e,json-shared-type,database,@nestjs-json-api/source,type-for-rpc'
3234
- name: Save cached .nx
3335
id: cache-dependencies-save
3436
uses: actions/cache/save@v4

.verdaccio/config.yml

Lines changed: 0 additions & 28 deletions
This file was deleted.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
- *[json-api-nestjs](https://github.com/klerick/nestjs-json-api/tree/master/libs/json-api/json-api-nestjs)* - plugin for create CRUD overs JSON API
1111
- *[json-api-nestjs-sdk](https://github.com/klerick/nestjs-json-api/tree/master/libs/json-api/json-api-nestjs-sdk)* - tool for client, call api over *json-api-nestjs*
12+
- *[nestjs-json-rpc](https://github.com/klerick/nestjs-json-api/tree/master/libs/json-rpc/nestjs-json-rpc)* - plugin for create RPC server using [JSON-RPC](https://www.jsonrpc.org/)
13+
- *[nestjs-json-rpc-sdk](https://github.com/klerick/nestjs-json-api/tree/master/libs/json-rpc/nestjs-json-rpc-sdk)* - tool for client, call RPC server *nestjs-json-rpc*
1214
- *json-api-nestjs-acl* - tool for acl over *json-api-nestjs*(coming soon...)
1315
## Installation
1416

apps/json-api-front/proxy.conf.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,10 @@
22
"/api": {
33
"target": "http://localhost:3000",
44
"secure": false
5+
},
6+
"/rpc": {
7+
"target": "http://localhost:3000",
8+
"secure": false,
9+
"ws": true
510
}
611
}

apps/json-api-front/src/app/app.component.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,19 @@ import { Component, inject, OnInit } from '@angular/core';
22
import { NxWelcomeComponent } from './nx-welcome.component';
33
import { JsonApiSdkService } from 'json-api-nestjs-sdk';
44
import { AtomicFactory } from 'json-api-nestjs-sdk/json-api-nestjs-sdk.module';
5+
import {
6+
JSON_RPC,
7+
RPC_BATCH,
8+
Rpc,
9+
} from '@klerick/nestjs-json-rpc-sdk/json-rpc-sdk.module';
10+
11+
import { RpcService as IRpcService } from '@nestjs-json-api/type-for-rpc';
512
import { switchMap } from 'rxjs';
613

14+
type RpcMap = {
15+
RpcService: IRpcService;
16+
};
17+
718
@Component({
819
standalone: true,
920
imports: [NxWelcomeComponent],
@@ -14,14 +25,25 @@ import { switchMap } from 'rxjs';
1425
export class AppComponent implements OnInit {
1526
private JsonApiSdkService = inject(JsonApiSdkService);
1627
private atomicFactory = inject(AtomicFactory);
28+
private rpc = inject<Rpc<RpcMap>>(JSON_RPC);
29+
private rpcBatch = inject(RPC_BATCH);
1730

1831
ngOnInit(): void {
19-
// this.JsonApiSdkService.getAll(class Users {}, {
20-
// page: {
21-
// size: 2,
22-
// number: 1,
23-
// },
24-
// }).subscribe((r) => console.log(r));
32+
const rpc1 = this.rpc.RpcService.someMethode(1);
33+
34+
const rpc2 = this.rpc.RpcService.methodeWithObjectParams({
35+
a: 1,
36+
b: 1,
37+
});
38+
39+
this.rpcBatch(rpc2, rpc1).subscribe(([r2, r1]) => console.log(r1, r2));
40+
41+
this.JsonApiSdkService.getAll(class Users {}, {
42+
page: {
43+
size: 2,
44+
number: 1,
45+
},
46+
}).subscribe((r) => console.log(r));
2547

2648
class Addresses {
2749
id = 1;
@@ -54,9 +76,9 @@ export class AppComponent implements OnInit {
5476

5577
const tmpUsers = new Users();
5678
tmpUsers.id = 1;
57-
// this.JsonApiSdkService.getRelationships(tmpUsers, 'addresses').subscribe(
58-
// (r) => console.log(r)
59-
// );
79+
this.JsonApiSdkService.getRelationships(tmpUsers, 'addresses').subscribe(
80+
(r) => console.log(r)
81+
);
6082

6183
const roles = new Roles();
6284
roles.id = 10000;

apps/json-api-front/src/app/app.config.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,60 @@
1-
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
1+
import {
2+
ApplicationConfig,
3+
importProvidersFrom,
4+
InjectionToken,
5+
} from '@angular/core';
26
import { JsonApiAngular } from 'json-api-nestjs-sdk/json-api-nestjs-sdk.module';
7+
import {
8+
JsonRpcAngular,
9+
JsonRpcAngularConfig,
10+
TransportType,
11+
} from '@klerick/nestjs-json-rpc-sdk/json-rpc-sdk.module';
12+
import { Subject } from 'rxjs';
13+
import { webSocket } from 'rxjs/webSocket';
14+
import { io } from 'socket.io-client';
15+
16+
const destroySubject = new Subject<boolean>();
17+
setTimeout(() => {
18+
console.log('Disconnect');
19+
destroySubject.next(true);
20+
destroySubject.complete();
21+
}, 5000);
22+
const destroySubjectToken = new InjectionToken('destroySubjectToken', {
23+
factory: () => destroySubject,
24+
});
25+
destroySubject.subscribe((r) => console.log(r));
26+
const tokenSocketInst = new InjectionToken('tokenSocketInst', {
27+
factory: () => webSocket('ws://localhost:4200/rpc'),
28+
});
29+
30+
const tokenIoSocketInst = new InjectionToken('tokenIoSocketInst', {
31+
factory: () => io('http://localhost:3000', { path: '/rpc' }),
32+
});
33+
34+
const httpConfig: JsonRpcAngularConfig = {
35+
transport: TransportType.HTTP,
36+
rpcPath: '/api/rpc',
37+
rpcHost: 'http://localhost:4200',
38+
};
39+
const wsConfig: JsonRpcAngularConfig = {
40+
transport: TransportType.WS,
41+
useWsNativeSocket: true,
42+
rpcPath: 'rpc',
43+
rpcHost: 'ws://localhost:4200',
44+
destroySubjectToken,
45+
};
46+
const wsConfigWithToken: JsonRpcAngularConfig = {
47+
transport: TransportType.WS,
48+
useWsNativeSocket: true,
49+
tokenSocketInst,
50+
destroySubjectToken,
51+
};
52+
const ioConfig: JsonRpcAngularConfig = {
53+
transport: TransportType.WS,
54+
useWsNativeSocket: false,
55+
destroySubjectToken,
56+
tokenSocketInst: tokenIoSocketInst,
57+
};
358

459
export const appConfig: ApplicationConfig = {
560
providers: [
@@ -11,5 +66,13 @@ export const appConfig: ApplicationConfig = {
1166
operationUrl: 'operation',
1267
})
1368
),
69+
importProvidersFrom(
70+
JsonRpcAngular.forRoot(
71+
// httpConfig
72+
// wsConfig
73+
// wsConfigWithToken,
74+
ioConfig
75+
)
76+
),
1477
],
1578
};

apps/json-api-server-e2e/src/json-api/json-api-sdk/atomic-sdk.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { FilterOperand, JsonSdkPromise } from 'json-api-nestjs-sdk';
33
import { Addresses, CommentKind, Comments, Roles, Users } from 'database';
44
import { faker } from '@faker-js/faker';
55
import { getUser } from '../utils/data-utils';
6-
import { run, creatSdk } from '../utils/run-ppplication';
6+
import { run, creatSdk } from '../utils/run-application';
77

88
let app: INestApplication;
99

apps/json-api-server-e2e/src/json-api/json-api-sdk/check-common-decorator.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { FilterOperand, JsonSdkPromise } from 'json-api-nestjs-sdk';
33
import { AxiosError } from 'axios';
44
import { Users } from 'database';
55

6-
import { run, creatSdk } from '../utils/run-ppplication';
6+
import { run, creatSdk } from '../utils/run-application';
77

88
let app: INestApplication;
99

apps/json-api-server-e2e/src/json-api/json-api-sdk/check-othe-call.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { BookList, Users } from 'database';
44
import { AxiosError } from 'axios';
55
import { faker } from '@faker-js/faker';
66
import { lastValueFrom } from 'rxjs';
7-
import { creatSdk, run, axiosAdapter } from '../utils/run-ppplication';
7+
import { creatSdk, run, axiosAdapter } from '../utils/run-application';
88

99
let app: INestApplication;
1010

apps/json-api-server-e2e/src/json-api/json-api-sdk/get-method.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { faker } from '@faker-js/faker';
44

55
import { FilterOperand, JsonSdkPromise } from 'json-api-nestjs-sdk';
66
import { getUser } from '../utils/data-utils';
7-
import { creatSdk, run } from '../utils/run-ppplication';
7+
import { creatSdk, run } from '../utils/run-application';
88

99
let app: INestApplication;
1010

apps/json-api-server-e2e/src/json-api/json-api-sdk/patch-methode.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Addresses, CommentKind, Comments, Users } from 'database';
33
import { faker } from '@faker-js/faker';
44
import { JsonSdkPromise } from 'json-api-nestjs-sdk';
55

6-
import { creatSdk, run } from '../utils/run-ppplication';
6+
import { creatSdk, run } from '../utils/run-application';
77

88
let app: INestApplication;
99

apps/json-api-server-e2e/src/json-api/json-api-sdk/post-method.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Addresses, BookList, CommentKind, Comments, Users } from 'database';
22
import { faker } from '@faker-js/faker';
33
import { JsonSdkPromise } from 'json-api-nestjs-sdk';
44

5-
import { creatSdk, run } from '../utils/run-ppplication';
5+
import { creatSdk, run } from '../utils/run-application';
66
import { INestApplication } from '@nestjs/common';
77
let app: INestApplication;
88

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { INestApplication } from '@nestjs/common';
2+
import {
3+
ResultRpcFactoryPromise,
4+
ErrorCodeType,
5+
RpcError,
6+
} from '@klerick/nestjs-json-rpc-sdk';
7+
8+
import { creatRpcSdk, MapperRpc, run } from '../utils/run-application';
9+
10+
let app: INestApplication;
11+
12+
beforeAll(async () => {
13+
app = await run();
14+
});
15+
16+
afterAll(async () => {
17+
await app.close();
18+
});
19+
20+
describe('Run json rpc:', () => {
21+
let rpc: ResultRpcFactoryPromise<MapperRpc>['rpc'];
22+
let rpcBatch: ResultRpcFactoryPromise<MapperRpc>['rpcBatch'];
23+
let rpcForBatch: ResultRpcFactoryPromise<MapperRpc>['rpcForBatch'];
24+
beforeEach(() => {
25+
({ rpc, rpcBatch, rpcForBatch } = creatRpcSdk());
26+
});
27+
28+
describe('Should be correct response', () => {
29+
it('Should be call one method', async () => {
30+
const input = 1;
31+
const result = await rpc.RpcService.someMethode(input);
32+
expect(result).toBe(input);
33+
});
34+
35+
it('Should be correct response batch', async () => {
36+
const input = 1;
37+
const input2 = {
38+
a: 1,
39+
b: 2,
40+
};
41+
const call1 = rpcForBatch.RpcService.someMethode(input);
42+
const call2 = rpcForBatch.RpcService.methodeWithObjectParams(input2);
43+
44+
const [result1, result2] = await rpcBatch(call1, call2);
45+
expect(result1).toBe(input);
46+
if ('error' in result2) {
47+
throw Error('Return error');
48+
}
49+
expect(result2.d).toEqual(`${input2.a}`);
50+
expect(result2.c).toEqual(`${input2.b}`);
51+
});
52+
});
53+
54+
describe('Check error', () => {
55+
it('Should throw an error ' + ErrorCodeType.MethodNotFound, async () => {
56+
const input = 1;
57+
expect.assertions(6);
58+
try {
59+
// @ts-ignore
60+
await rpc.IncorrectService.incorrectMethode(input);
61+
} catch (e) {
62+
expect(e).toBeInstanceOf(RpcError);
63+
expect((e as RpcError).code).toBe(-32601);
64+
expect((e as RpcError).message).toBe(ErrorCodeType.MethodNotFound);
65+
}
66+
try {
67+
// @ts-ignore
68+
await rpc.RpcService.incorrectMethode(input);
69+
} catch (e) {
70+
expect(e).toBeInstanceOf(RpcError);
71+
expect((e as RpcError).code).toBe(-32601);
72+
expect((e as RpcError).message).toBe(ErrorCodeType.MethodNotFound);
73+
}
74+
});
75+
76+
it('Should throw an error ' + ErrorCodeType.InvalidParams, async () => {
77+
const input = 'llll';
78+
expect.assertions(3);
79+
try {
80+
// @ts-ignore
81+
await rpc.RpcService.someMethode(input);
82+
} catch (e) {
83+
expect(e).toBeInstanceOf(RpcError);
84+
expect((e as RpcError).code).toBe(-32602);
85+
expect((e as RpcError).message).toBe(ErrorCodeType.InvalidParams);
86+
}
87+
});
88+
89+
it('Should throw an error ' + ErrorCodeType.ServerError, async () => {
90+
const input = 5;
91+
expect.assertions(4);
92+
try {
93+
await rpc.RpcService.someMethode(input);
94+
} catch (e) {
95+
expect(e).toBeInstanceOf(RpcError);
96+
expect((e as RpcError).code).toBe(-32099);
97+
expect((e as RpcError).message).toBe(ErrorCodeType.ServerError);
98+
expect((e as RpcError).data.title).toBe('Custom Error');
99+
}
100+
});
101+
});
102+
});

0 commit comments

Comments
 (0)