From d11c8c2bc041c2e8a25ebf7f1c68c901c18ee0ca Mon Sep 17 00:00:00 2001 From: Manuel Maute Date: Mon, 12 Jul 2021 01:08:46 +0200 Subject: [PATCH] fix: grpc-js support for nestjs (#307) * fix: grpc-js support for nestjs * fix: code style * fix: update snapshots * Re-codegen. * Remove js files. * Remove out. * Remove test.ts. * Update snapshot. Co-authored-by: Stephen Haberman --- integration/nestjs-metadata-grpc-js/hero.bin | Bin 0 -> 1049 bytes .../nestjs-metadata-grpc-js/hero.proto | 27 +++++++ integration/nestjs-metadata-grpc-js/hero.ts | 68 ++++++++++++++++++ .../nestjs-metadata-test.ts | 8 +++ .../nestjs-metadata-grpc-js/parameters.txt | 1 + .../nestjs-metadata-grpc-js/sample-service.ts | 25 +++++++ src/generate-nestjs.ts | 6 +- 7 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 integration/nestjs-metadata-grpc-js/hero.bin create mode 100644 integration/nestjs-metadata-grpc-js/hero.proto create mode 100644 integration/nestjs-metadata-grpc-js/hero.ts create mode 100644 integration/nestjs-metadata-grpc-js/nestjs-metadata-test.ts create mode 100644 integration/nestjs-metadata-grpc-js/parameters.txt create mode 100644 integration/nestjs-metadata-grpc-js/sample-service.ts diff --git a/integration/nestjs-metadata-grpc-js/hero.bin b/integration/nestjs-metadata-grpc-js/hero.bin new file mode 100644 index 0000000000000000000000000000000000000000..089060a585f5c9a15246efb6428f820c44b0ab62 GIT binary patch literal 1049 zcmb7^U279j5Qfj$GrKvRO|t21YBqslNpFJHQ2c^|-iSyQM5y3>G=T@H!xTt*GS{4Bk|X?n={yYf|B!t+~DBepA1(%%u0*C8W-{ z(A4Y2=K4QkGk@w|eNQPh#d6x$hyvs}?X`r)9A~RRmluOt z=Y{%i(CBole)F8j>vJkh2Y{|H9SDtu=|IpGrb~px9W*-KR${lFE>T@+IskN~=|E`I zSD@2@pev!%r4n@vX=o*n*pRp-t>rq0#yny}DeI+z&`3WHynG7i8pWd4;p>o4*%Sci pDw_g?#tJgkfuO5wil9@BZ3+NlW19k`HJbv2*jUQ; + + findOneVillain(request: VillainById, metadata?: Metadata): Observable; + + findManyVillain(request: Observable, metadata?: Metadata): Observable; +} + +export interface HeroServiceController { + findOneHero(request: HeroById, metadata?: Metadata): Promise | Observable | Hero; + + findOneVillain(request: VillainById, metadata?: Metadata): Promise | Observable | Villain; + + findManyVillain(request: Observable, metadata?: Metadata): Observable; +} + +export function HeroServiceControllerMethods() { + return function (constructor: Function) { + const grpcMethods: string[] = ['findOneHero', 'findOneVillain']; + for (const method of grpcMethods) { + const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method); + GrpcMethod('HeroService', method)(constructor.prototype[method], method, descriptor); + } + const grpcStreamMethods: string[] = ['findManyVillain']; + for (const method of grpcStreamMethods) { + const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method); + GrpcStreamMethod('HeroService', method)(constructor.prototype[method], method, descriptor); + } + }; +} + +export const HERO_SERVICE_NAME = 'HeroService'; + +// If you get a compile-error about 'Constructor and ... have no overlap', +// add '--ts_proto_opt=esModuleInterop=true' as a flag when calling 'protoc'. +if (util.Long !== Long) { + util.Long = Long as any; + configure(); +} diff --git a/integration/nestjs-metadata-grpc-js/nestjs-metadata-test.ts b/integration/nestjs-metadata-grpc-js/nestjs-metadata-test.ts new file mode 100644 index 000000000..ee81d9528 --- /dev/null +++ b/integration/nestjs-metadata-grpc-js/nestjs-metadata-test.ts @@ -0,0 +1,8 @@ +import { SampleService } from './sample-service'; + +describe('nestjs-metadata-test', () => { + it('compiles', () => { + const service = new SampleService(); + expect(service).not.toBeUndefined(); + }); +}); diff --git a/integration/nestjs-metadata-grpc-js/parameters.txt b/integration/nestjs-metadata-grpc-js/parameters.txt new file mode 100644 index 000000000..116886240 --- /dev/null +++ b/integration/nestjs-metadata-grpc-js/parameters.txt @@ -0,0 +1 @@ +nestJs=true,addGrpcMetadata=true,outputServices=grpc-js diff --git a/integration/nestjs-metadata-grpc-js/sample-service.ts b/integration/nestjs-metadata-grpc-js/sample-service.ts new file mode 100644 index 000000000..ff285546e --- /dev/null +++ b/integration/nestjs-metadata-grpc-js/sample-service.ts @@ -0,0 +1,25 @@ +import { HeroServiceController, HeroById, Hero, Villain, VillainById } from './hero'; +import { Metadata } from 'grpc'; +import { Observable, Subject } from 'rxjs'; + +export class SampleService implements HeroServiceController { + findOneHero(request: HeroById, metadata?: Metadata): Promise { + return Promise.resolve({ id: 1, name: 'test' }); + } + + findOneVillain(request: VillainById, metadata?: Metadata): Promise { + return Promise.resolve({ id: 1, name: 'test' }); + } + + findManyVillain(request: Observable): Observable { + const hero$ = new Subject(); + + const onNext = (villainById: VillainById) => { + hero$.next({ id: 1, name: 'test' }); + }; + const onComplete = () => hero$.complete(); + request.subscribe(onNext, null, onComplete); + + return hero$.asObservable(); + } +} diff --git a/src/generate-nestjs.ts b/src/generate-nestjs.ts index 08450b703..0856f2fc5 100644 --- a/src/generate-nestjs.ts +++ b/src/generate-nestjs.ts @@ -14,8 +14,6 @@ import { assertInstanceOf, FormattedMethodDescriptor, maybeAddComment, singular import { camelCase } from './case'; import { Context } from './context'; -const Metadata = imp('Metadata@grpc'); - export function generateNestjsServiceController( ctx: Context, fileDesc: FileDescriptorProto, @@ -25,6 +23,8 @@ export function generateNestjsServiceController( const { options } = ctx; const chunks: Code[] = []; + const Metadata = options.outputServices === 'grpc-js' ? imp('Metadata@@grpc/grpc-js') : imp('Metadata@grpc'); + maybeAddComment(sourceInfo, chunks, serviceDesc.options?.deprecated); const t = options.context ? `<${contextTypeVar}>` : ''; chunks.push(code` @@ -96,6 +96,8 @@ export function generateNestjsServiceClient( const { options } = ctx; const chunks: Code[] = []; + const Metadata = options.outputServices === 'grpc-js' ? imp('Metadata@@grpc/grpc-js') : imp('Metadata@grpc'); + maybeAddComment(sourceInfo, chunks); const t = options.context ? `<${contextTypeVar}>` : ``; chunks.push(code`