Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate only gPRC client related code in nestJs=true #527

Open
mpx2m opened this issue Mar 3, 2022 · 2 comments
Open

generate only gPRC client related code in nestJs=true #527

mpx2m opened this issue Mar 3, 2022 · 2 comments
Labels
enhancement New feature or request help wanted Extra attention is needed nestjs

Comments

@mpx2m
Copy link

mpx2m commented Mar 3, 2022

If there is proto like this:

// demo.proto
syntax = "proto3";
package proto.v1;

service TestService {
    rpc Login (LoginRequest) returns (LoginResponse);
}

message LoginRequest {
    string name = 1;
    string password = 2;
}

message LoginResponse {
    string auth_code = 1;
}

after

"protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt=outputPartialMethods=true --ts_proto_opt=nestJs=true --ts_proto_opt=env=node --ts_proto_opt=addGrpcMetadata=true --ts_proto_opt=useOptionals=messages --ts_proto_opt=forceLong=string --ts_proto_opt=unrecognizedEnum=false --ts_proto_out=./ demo.proto"

produce

/* eslint-disable */
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
import { util, configure } from "protobufjs/minimal";
import * as Long from "long";
import { Observable } from "rxjs";
import { Metadata } from "@grpc/grpc-js";

export const protobufPackage = "proto.v1";

/** demo.proto */

export interface LoginRequest {
  name: string;
  password: string;
}

export interface LoginResponse {
  authCode: string;
}

export const PROTO_V1_PACKAGE_NAME = "proto.v1";

export interface TestServiceClient {
  login(request: LoginRequest, metadata?: Metadata): Observable<LoginResponse>;
}

export interface TestServiceController {
  login(
    request: LoginRequest,
    metadata?: Metadata
  ): Promise<LoginResponse> | Observable<LoginResponse> | LoginResponse;
}

export function TestServiceControllerMethods() {
  return function (constructor: Function) {
    const grpcMethods: string[] = ["login"];
    for (const method of grpcMethods) {
      const descriptor: any = Reflect.getOwnPropertyDescriptor(
        constructor.prototype,
        method
      );
      GrpcMethod("TestService", method)(
        constructor.prototype[method],
        method,
        descriptor
      );
    }
    const grpcStreamMethods: string[] = [];
    for (const method of grpcStreamMethods) {
      const descriptor: any = Reflect.getOwnPropertyDescriptor(
        constructor.prototype,
        method
      );
      GrpcStreamMethod("TestService", method)(
        constructor.prototype[method],
        method,
        descriptor
      );
    }
  };
}

export const TEST_SERVICE_NAME = "TestService";

// If you get a compile-error about 'Constructor<Long> 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();
}

In some NestJs project, only gRPC client is implemented and generated code with *Controller, *ControllerMethods related (TestServiceController, TestServiceControllerMethods above) are unwanted in this situation.

So a flag that can be set to only generate gPRC client related code would be nice.

After set the flag, the proto file above will produce code like:

/* eslint-disable */
import { util, configure } from "protobufjs/minimal";
import * as Long from "long";
import { Observable } from "rxjs";
import { Metadata } from "@grpc/grpc-js";

export const protobufPackage = "proto.v1";

/** demo.proto */

export interface LoginRequest {
  name: string;
  password: string;
}

export interface LoginResponse {
  authCode: string;
}

export const PROTO_V1_PACKAGE_NAME = "proto.v1";

export interface TestServiceClient {
  login(request: LoginRequest, metadata?: Metadata): Observable<LoginResponse>;
}

export const TEST_SERVICE_NAME = "TestService";

// If you get a compile-error about 'Constructor<Long> 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();
}
@stephenh
Copy link
Owner

stephenh commented Mar 6, 2022

@mpx2m hm, yeah, that makes sense. I think that nestJs=true is already kind of a meta-option that sets some other parameters; see around here:

https://github.com/stephenh/ts-proto/blob/main/src/options.ts#L113

If you'd like to submit a PR that adds nestJs=client & nestJs=server support, that'd be great.

If so, I'd suggest doing it like this PR:

#512

I.e. turn the internal Options.nestJs into an array of options.nestJs: Array<'client' | 'server'> and then update optionsFromParameter to watch for nestJs=true and turn that into nestJs: ['client', 'server'].

Thanks!

@stephenh stephenh added enhancement New feature or request help wanted Extra attention is needed nestjs labels Mar 6, 2022
@MaksymShuldiner
Copy link

+1 for that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed nestjs
Projects
None yet
Development

No branches or pull requests

3 participants