Reputation: 43
Here is my npm run protoc
, the line below will run:
./node_modules/protoc/protoc/bin/protoc --proto_path=proto --js_out=import_style=commonjs,binary:src/bin --grpc_out=src/bin --plugin=protoc-gen-grpc=node_modules/grpc-tools/bin/grpc_node_plugin --ts_out=service=true:src/bin proto/authentication_service.proto
And it generates the following files:
authentication_service_grpc_pb.js
authentication_service_pb.d.ts
authentication_service_pb.js
authentication_service_pb_service.d.ts
authentication_service_pb_service.js
At one time I was able to get it to generate a authentication_service_grpc_pb.d.ts but with the config I saved above it does not. Can anyone help with what I am missing? Thanks!
Upvotes: 4
Views: 3408
Reputation: 1
I used https://www.npmjs.com/package/ts-protoc-gen to generate typescript definition.
In my case, I needed to pass in service=grpc-node
param to the --ts_out
. Then I got the correct file generated.
xxx_grpc_pb.d.ts
My full command is sth like
protoc --proto_path={{path to proto files}} \
--plugin=protoc-gen-ts={{path to ts-protoc-gen plugin}} \
--plugin=protoc-gen-grpc={{path to grpc-tools plugin}} \
--plugin={{path to official js plugin downloaded from https://github.com/protocolbuffers/protobuf-javascript release}} \
--js_out=import_style=commonjs,binary:{{generated file path}} \
--grpc_out=grpc_js:{{generated file path}} \
--ts_out=service=grpc-node,mode=grpc-js:{{generated file path}} \
Upvotes: 0
Reputation: 1613
All of that solutions are awful. Try that instead
Generation script
generate-dts.js
import { globSync } from "glob";
import { basename } from "path";
import { writeFileSync } from "fs";
import prettierSync from "@prettier/sync";
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
for (const protoPath of globSync("./proto/*.proto")) {
const output = [];
const namespaceName = basename(protoPath).replace(".proto", "");
const packageDefinition = protoLoader.loadSync(protoPath);
const proto = grpc.loadPackageDefinition(packageDefinition);
const services = Object.entries(proto)
.filter(([, value]) => value.service)
.map(([key, value]) => [key, Object.keys(value.service)]);
{
output.push("declare namespace GRPC {");
output.push(`namespace ${namespaceName} {`);
}
services.forEach(([className, methodList]) => {
output.push(`interface ${className} {`);
methodList.forEach((methodName) => {
output.push(`${methodName}(...args: any): any;`);
});
output.push("}");
});
{
output.push("}");
output.push("}");
}
const typedef = prettierSync.format(output.join("\n"), {
semi: true,
endOfLine: "auto",
trailingComma: "all",
singleQuote: false,
printWidth: 80,
tabWidth: 2,
parser: 'typescript',
});
writeFileSync(`./modules/remote-lib/types/${namespaceName}.d.ts`, typedef);
}
Output
service.d.ts
declare global {
export namespace GRPC {
export namespace service {
export interface ServiceA {
SendToServiceB(...args: any): any;
SendToServiceBCCC(...args: any): any;
}
export interface ServiceB {
ProcessRequest(...args: any): any;
}
}
}
}
service.proto
syntax = "proto3";
// Message for communication between services
message Request {
string message = 1;
}
message Response {
string message = 1;
}
// Service A definition
service ServiceA {
rpc SendToServiceB (Request) returns (Response);
rpc SendToServiceBCCC (Request) returns (Response);
}
// Service B definition
service ServiceB {
rpc ProcessRequest (Request) returns (Response);
}
Upvotes: 0
Reputation: 938
Take a look at the "How to use" section of the documentation and note that generating the d.ts codes is done with a different executable:
npm install grpc_tools_node_protoc_ts --save-dev
# generate js codes via grpc-tools
grpc_tools_node_protoc \
--js_out=import_style=commonjs,binary:./your_dest_dir \
--grpc_out=./your_dest_dir \
--plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` \
-I ./proto \
./your_proto_dir/*.proto
# generate d.ts codes
protoc \
--plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts \
--ts_out=./your_dest_dir \
-I ./proto \
./your_proto_dir/*.proto
After writing this, that's not even the root of the problem (at least for this one particular generator). The executable in bin/
is protoc-gen-ts
.
When you're trying out different stuff make sure to version-control your attempts and clean out the output directory to have a reproducible environment.
Given all of this my best guess is that the --ts-out
and --js-out
flags cancel each other out and you'll have to run the generator once for each output type. Verify by trying it out. As a bonus you could try finding out if there's a --verbose
flag to make your life easier :).
Upvotes: 2