Compile .proto
files to plain TypeScript. Supports gRPC Node and gRPC Web.
Note
As of 2024, this project has adopted Rust as its primary programming language, replacing JavaScript. See the issue for the details.
I have limited availability to consistently maintain this project, as my time is primarily allocated to cutting new releases and implementing fixes on an ad hoc basis.
Become a maintainer? Send an email
- Passes all required conformance tests
- Supports well-known types
- Supports gRPC (
@grpc/grpc-js
) - Supports gRPC Web (
grpc-web
) - Supports json encoding (
toJson
,fromJson
) - Supports binary encoding (
toBinary
,fromBinary
) - Optimized for [de]serialization speed.
npm install -g protoc-gen-ts
protoc -I=sourcedir --ts_out=dist myproto.proto
version: v1
plugins:
- name: ts
path: ./node_modules/.bin/protoc-gen-ts
out: ./dist
syntax = "proto3";
enum Role {
ADMIN = 0;
MOD = 1;
}
message Author {
Role role = 2;
oneof id_or_name {
string id = 4;
string name = 5;
}
}
const author = Author.fromJson({
role: Kind.ADMIN,
name: "mary poppins",
});
// Serialize to binary
const bytes: Uint8Array = author.toBinary();
// Deserialize from binary
const received: Change = Change.fromBinary(bytes);
console.log(received.toJson())
./infra/test.sh
We need your constant support to keep protoc-gen-ts well maintained and add new features.
If your corporate has a OSS funding scheme, please consider supporting us monthly through open collective.
protoc-gen-ts's People
Forkers
zeidoo todd marcushultman snorack dreamershl aperron mantou132 rahulv4667 emma-app ddrowsy manabie-com renkei silversheep gecko655 badeadebayo jbpin koblas petermetz relief-melone echozhaoh parvineyvazov crystailx cprovatas dio plachta11b chris-kruining muddle216 iamricard yurzel michael-pomelo heycolin vitorelourenco ycllz mauritsr gcurtis psigen zacharyvoase td-krzysiek transmission-dynamics michaelcacciatore mygoalistokillbill santalov tranquocthien smallcharm long1eu tsawada mrmeku stefsietz psy-kai h-koura orby-ai-engineering pragone logunify curquhart martyphee johnnyasantoss danias aleksei2507 luffigo123 eliyya jcapote-lyft carpntr yutaura zulzi wdoconnell oolio-group yoshinariyamanaka thoradam anuraaga custompro98 binlogo p4p-83 jeevaprakashdr leonardobein peter-eid sanyatuning justinmakailaprotoc-gen-ts's Issues
Repeated field problem in protobuf v2
Based on the protobuf specification here
Proto file that not have syntax = "proto3";
on the first line will be treated as 'proto2' syntax. And so if it has first line syntax = "proto2";
its clean that its proto2 syntax.
In proto2 or proto3 the repeated field can be packed/not packed using special option:
repeated int32 samples = 4 [packed=true];
repeated ProtoEnum results = 5 [packed=false];
There is a different between v2 an v3 on dealing with integer repeated field. on v2 there's no optimization or by default is no packed integer
, its just an repeated field with same id.
I Found that this library ignoring that specification causing me to fail when rebuilt whatsapp protobuf that created using proto2 syntax.
I was try with specifyin [packed=false] but still no luck, so I need to manually patch the generated code because I have no time to make PR for this repo.
Note:
- If you compile proto using this library, and then decode and encode using same generated code, it will work and no error.
- Error happen when I decoding a binary message that came from other encoder (whatsapp server). It break on repeated field after I deeply investigate.
I know it error from generated ts code because I was using this before and no problems. Works fine using version before its breaking changes to simple getter/setter.
If you want, You can add a simple test (using nodejs assert is enough) to test against this files or make binary message from other tools with same proto spec.
Thanks this library is great and I like the improvement to use direct getter/setter on field instead using a lot of get-set function.
.proto3 input -> .ts3 output
This worked great out of the box! So much nicer than protoc's commonjs output! ❤️
I ran into one odd roadbump -- it kept generating a .ts3
file, which Snowpack didn't know to interpret as TypeScript. I finally figured out it's because I'd named my file something.proto3
and that 3 was carried over. I'm fine just renaming my input file to .proto
for now to work around this.
Cannot compile.
Hello, i'm trying to use you library and it fails at start, probably i miss something in configuration, can you give me advice?
>protoc -I=protos --ts_out=javascript/new-dist my.proto
internal/modules/cjs/loader.js:984
throw err;
^
Error: Cannot find module 'google-protobuf/google/protobuf/compiler/plugin_pb'
Require stack:
- C:\Users\...\AppData\Roaming\nvm\v12.16.0\node_modules\protoc-gen-ts\index.js
- C:\Users\...\AppData\Roaming\nvm\v12.16.0\node_modules\protoc-gen-ts\bin\protoc-gen-ts
?[90m at Function.Module._resolveFilename (internal/modules/cjs/loader.js:981:15)?[39m
?[90m at Function.Module._load (internal/modules/cjs/loader.js:863:27)?[39m
?[90m at Module.require (internal/modules/cjs/loader.js:1043:19)?[39m
?[90m at require (internal/modules/cjs/helpers.js:77:18)?[39m
at Object.<anonymous> (C:\Users\...\AppData\Roaming\nvm\v12.16.0\node_modules\?[4mprotoc-gen-ts?[24m\index.js:1:16)
?[90m at Module._compile (internal/modules/cjs/loader.js:1157:30)?[39m
?[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1177:10)?[39m
?[90m at Module.load (internal/modules/cjs/loader.js:1001:32)?[39m
?[90m at Function.Module._load (internal/modules/cjs/loader.js:900:14)?[39m
?[90m at Module.require (internal/modules/cjs/loader.js:1043:19)?[39m {
code: ?[32m'MODULE_NOT_FOUND'?[39m,
requireStack: [
?[32m'C:\\Users\\...\\AppData\\Roaming\\nvm\\v12.16.0\\node_modules\\protoc-gen-ts\\index.js'?[39m,
?[32m'C:\\Users\\...\\AppData\\Roaming\\nvm\\v12.16.0\\node_modules\\protoc-gen-ts\\bin\\protoc-gen-ts'?[39m
]
}
--ts_out: protoc-gen-ts: Plugin failed with status code 1.
Protoc version:
>protoc --version
libprotoc 3.11.4
Using Custom Types with Repeated Keyword Doesn't Work
Building this proto file
syntax = "proto3";
message Car {
string name = 1;
string color = 2;
}
// custom repeated type throws error
message Cars {
repeated Car cars = 1;
}
// primitve type works fine
message List {
repeated string list = 1;
}
throws
/node_modules/typescript/lib/typescript.js:11851
return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
^
TypeError: Cannot read property 'hasOwnProperty' of null
at Object.isNodeArray (/node_modules/typescript/lib/typescript.js:11851:22)
at createNodeArray (/node_modules/typescript/lib/typescript.js:20082:25)
at Object.createCallExpression (/node_modules/typescript/lib/typescript.js:21335:95)
at Object.createCall (/node_modules/typescript/lib/typescript.js:2814:29)
at createToObject (/node_modules/protoc-gen-ts/index.js:49:14)
at createMessage (/node_modules/protoc-gen-ts/index.js:1016:5)
at processMessageDescriptor (/node_modules/protoc-gen-ts/index.js:1545:5)
at processProtoDescriptor (/node_modules/protoc-gen-ts/index.js:1590:12)
at main (/node_modules/protoc-gen-ts/index.js:1680:24)
at Object.<anonymous> (/node_modules/protoc-gen-ts/index.js:1765:1)
I've created a repro here: https://github.com/flolu/protoc-gen-ts-repeated-repro
Basically it seems as if custom Types (in this case Car
) doesn't work with the repeated
keyword.
import error in generated ts files with namespace
When use the same package name in multiple .proto files, like
syntax = "proto3";
package Config;
In the generated ts file, there're import lines like
import * as dependency_1 from "./ConfigA";
import * as dependency_2 from "./ConfigB";
import * as pb_1 from "google-protobuf";
import * as grpc_1 from "@grpc/grpc-js";
export namespace Config {
...enums and classes
}
Then we got errors like this:
When using types and namespaces from dependency files, it should be dependency_x.Config.XXX
.
PS: All serializeBinary() function in classes has typscript error, because return type may be undefined.
Fields can be undefined but return type of getters can't
What is the idea behind the current implementation to generate code from proto files where the return type of the field getters is always cast to the data type of the field?
The cast in the generated typescript code is realized with an as
expression, which can be dangerous. The Typescript compiler is possibly happy with the cast while the data type has nothing to do with the real data type available at runtime in JavaScript.
This is exactly the case when a field of a proto message, here B
, is of type of another proto message, here A
:
message A
{
int32 id = 1;
}
message B
{
A item = 1;
}
If I use the generated typescript code to create an instance of B like:
const b = new B();
then the generated typescript code tells me that b.item
is always of type A
but in fact, b.item
is undefined
. This can be checked easily by printing b.item
to console
. So, the correct typings for b.item
would be A | undefined
. Or am I wrong? Do I miss something here?
proto3 fields unnecessarily serialized
I found that if I have a message like this:
syntax = "proto3";
message Test {
string foo = 1;
}
And I do:
// May be "" or non-empty:
let someString = someFieldValue()
new Test({foo:someString}).serialize()
... then a string of length 0 gets serialized with the bytes instead of nothing, which I believe should be the expected output for proto3.
Note that for scalar message fields, once a message is parsed there's no way of telling whether a field was explicitly set to the default value [...] or just not set at all
[...]
Also note that if a scalar message field is set to its default, the value will not be serialized on the wire.
from: proto3 docs
I can work around this with this pattern for now:
let test = new Test()
if (someString) test.foo = someString
But it would be nice to have that optimization built in.
Enums not working
The docs say that enums are supported, but they're not being generated in my use. I've created a minimal example here.
Steps to reproduce
package.json:
{
"dependencies": {
"google-protobuf": "^3.14.0",
"protoc-gen-ts": "^0.3.4",
"typescript": "^3"
},
"scripts": {
"proto": "protoc --plugin=./node_modules/.bin/protoc-gen-ts.cmd --ts_out=. --proto_path=. sample.proto"
}
}
sample.proto:
syntax = "proto3";
message Example {
Foo foo = 1;
}
enum Foo {
UNKNOWN = 0;
BAR = 1;
BAZ = 2;
}
Run:
npm install
npm run proto
Resulting output (does not contain an enum Foo
):
import * as pb_1 from "google-protobuf";
export class Example extends pb_1.Message {
constructor(data?: any[] | {
foo?: Foo;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) && data, 0, -1, [], null);
if (!Array.isArray(data) && typeof data == "object") {
this.foo = data.foo;
}
}
get foo(): Foo {
return pb_1.Message.getFieldWithDefault(this, 1, undefined) as Foo;
}
set foo(value: Foo) {
pb_1.Message.setField(this, 1, value);
}
toObject() {
return {
foo: this.foo
};
}
serialize(w?: pb_1.BinaryWriter): Uint8Array | undefined {
const writer = w || new pb_1.BinaryWriter();
if (this.foo !== undefined)
writer.writeEnum(1, this.foo);
if (!w)
return writer.getResultBuffer();
}
serializeBinary(): Uint8Array { throw new Error("Method not implemented."); }
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): Example {
const reader = bytes instanceof Uint8Array ? new pb_1.BinaryReader(bytes) : bytes, message = new Example();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
message.foo = reader.readEnum();
break;
default: reader.skipField();
}
}
return message;
}
}
`TypeError: Invalid data` in 0.3.6-rc1+
I was on my way to test #33, but first wanted to verify that my current proto would compile. Unfortunately, I wasn't able to compile my proto. It works in 0.3.5 but not 0.3.6-rc1 (tested up through rc4).
Interestingly, it seems to throw this error even if I slim the file down, even all the way down to a totally blank file (though it does give a warning in that case about no syntax specified). So it doesn't seem to be input related
Here is how I run my proto build:
PROTOC_GEN_TS_PATH="./node_modules/.bin/protoc-gen-ts"
TS_OUT_DIR="client-src/ProtoGenerated/"
protoc --plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" --js_out="import_style=commonjs,binary:${TS_OUT_DIR}" --ts_out="${TS_OUT_DIR}" --proto_path=../Bridge/ NetMessage.proto
It compiles fine with 0.3.5, but here is the error in the rc's:
net.js:714
throw new TypeError(
^
TypeError: Invalid data, chunk must be a string or buffer, not object
at Socket.write (net.js:714:11)
at Object.<anonymous> (/path/node_modules/protoc-gen-ts/src/index.js:2199:16)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/path/node_modules/protoc-gen-ts/bin/protoc-gen-ts:3:1)
--ts_out: protoc-gen-ts: Plugin failed with status code 1.
package.json contains these dependencies:
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.4.2",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.9.0",
"ts-loader": "^6.2.1",
"typescript": "^4.0.2",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
"@types/node": "^12.12.2",
"protoc-gen-ts": "^0.3.6-rc1"
},
"dependencies": {
"hotkeys-js": "^3.8.3",
"konva": "^7.2.5",
"google-protobuf": "^3.15.8",
"@microsoft/signalr": "^5.0.5"
}
Which results in these versions:
├─┬ @microsoft/[email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├── @types/[email protected]
├─┬ [email protected]
│ ├─┬ @types/[email protected]
│ │ ├── @types/[email protected]
│ │ ├── @types/[email protected]
│ │ ├── @types/[email protected]
│ │ ├─┬ @types/[email protected]
│ │ │ ├── @types/[email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ ├─┬ @types/[email protected]
│ │ └── @types/[email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── @types/[email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ └─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ └── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├─┬ @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ └─┬ @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ └── @xtuc/[email protected]
│ ├── @webassemblyjs/[email protected]
│ ├─┬ @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ └── @webassemblyjs/[email protected]
│ ├─┬ @webassemblyjs/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ ├─┬ @webassemblyjs/[email protected]
│ │ │ └── @xtuc/[email protected]
│ │ ├── @webassemblyjs/[email protected]
│ │ └── @webassemblyjs/[email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ ├── [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ │ └── [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ ├── [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├─┬ [email protected]
│ │ │ │ │ │ ├── [email protected]
│ │ │ │ │ │ └── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ └─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├── [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ ├── UNMET OPTIONAL DEPENDENCY fsevents@~2.3.1
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├── UNMET OPTIONAL DEPENDENCY fsevents@^1.2.7
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ └── [email protected]
└─┬ [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├── [email protected]
├─┬ [email protected]
│ └── [email protected]
├── [email protected]
└─┬ [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ └─┬ [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│ └── [email protected]
├── [email protected]
├── [email protected]
└─┬ [email protected]
└── [email protected]
Repeated fields are not implementing toObject()
Hi,
I've been trying to use this with repeated fields,
message Schema {
string name = 1;
repeated Field fields = 2;
}
The generated code fails to compile:
get fields(): Field[] {
return pb_1.Message.getRepeatedWrapperField(this, Field, 2) as Field[];
}
set fields(value: Field[]) {
pb_1.Message.setRepeatedWrapperField(this, 2, value);
}
toObject() {
return {
name: this.name,
fields: this.fields && this.fields.toObject() <-- the fields array doesn't implement toObject, the individual items themselves do.
};
}
The error when compiling is: Property 'toObject' does not exist on type 'Field[]'.
Make generated Typescript outputs compatible with Typescript strict mode
We have already talked about it. This just serves as a reminder.
Currently settings strict
to true
will cause errors in the generated Typescript files.
Repro: https://github.com/flolu/typescript-protobuf-bazel-rpc/tree/284c73f0d5d3d9af825fee49fec6b4dc8241d31a
Just change the tsconfig.json
like this
{
"compilerOptions": {
"strict": true,
}
}
Then running yarn start:server
will throw errors. It will work without errors with strict: false
.
Errors
bazel-out/k8-fastbuild/bin/example.ts:9:39 - error TS2345: Argument of type 'false | any[]' is not assignable to parameter of type 'MessageArray'.
Type 'boolean' is not assignable to type 'any[]'.
9 pb_1.Message.initialize(this, Array.isArray(data) && data, 0, -1, [], null);
~~~~~~~~~~~~~~~~~~~~~~~~~~~
bazel-out/k8-fastbuild/bin/example.ts:11:13 - error TS2322: Type 'number | undefined' is not assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.
11 this.a = data.a;
~~~~~~
bazel-out/k8-fastbuild/bin/example.ts:12:13 - error TS2322: Type 'number | undefined' is not assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.
12 this.b = data.b;
~~~~~~
bazel-out/k8-fastbuild/bin/example.ts:16:16 - error TS2352: Conversion of type 'undefined' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
16 return pb_1.Message.getFieldWithDefault(this, 1, undefined) as number;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bazel-out/k8-fastbuild/bin/example.ts:22:16 - error TS2352: Conversion of type 'undefined' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
22 return pb_1.Message.getFieldWithDefault(this, 2, undefined) as number;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bazel-out/k8-fastbuild/bin/example.ts:66:39 - error TS2345: Argument of type 'false | any[]' is not assignable to parameter of type 'MessageArray'.
Type 'boolean' is not assignable to type 'any[]'.
66 pb_1.Message.initialize(this, Array.isArray(data) && data, 0, -1, [], null);
~~~~~~~~~~~~~~~~~~~~~~~~~~~
bazel-out/k8-fastbuild/bin/example.ts:68:13 - error TS2322: Type 'number | undefined' is not assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.
68 this.result = data.result;
~~~~~~~~~~~
bazel-out/k8-fastbuild/bin/example.ts:72:16 - error TS2352: Conversion of type 'undefined' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
72 return pb_1.Message.getFieldWithDefault(this, 1, undefined) as number;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bazel-out/k8-fastbuild/bin/example.ts:112:61 - error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type 'Uint8Array | undefined' is not assignable to parameter of type 'string'.
Type 'undefined' is not assignable to type 'string'.
112 requestSerialize: (message: Request) => Buffer.from(message.serialize()),
~~~~~~~~~~~~~~~~~~~
external/npm/node_modules/@types/node/ts3.1/globals.d.ts:153:12
153 static from(str: string, encoding?: BufferEncoding): Buffer;
~~~~
The last overload is declared here.
bazel-out/k8-fastbuild/bin/example.ts:114:63 - error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type 'Uint8Array | undefined' is not assignable to parameter of type 'string'.
Type 'undefined' is not assignable to type 'string'.
114 responseSerialize: (message: Response) => Buffer.from(message.serialize()),
~~~~~~~~~~~~~~~~~~~
external/npm/node_modules/@types/node/ts3.1/globals.d.ts:153:12
153 static from(str: string, encoding?: BufferEncoding): Buffer;
~~~~
The last overload is declared here.
Interoperate with protoc-gen-validate
Discussed in #65
Originally posted by thesayyn June 30, 2021
Idea: Think about how could we interoperate with https://github.com/envoyproxy/protoc-gen-validate
[jstype = JS_STRING] type Compile error
int64 result_per_page = 3 [jstype = JS_STRING];
Still compiled to number
get result_per_page(): number | undefined { return pb_1.Message.getFieldWithDefault(this, 3, undefined) as number | undefined; }
set result_per_page(value: number) { pb_1.Message.setField(this, 3, value); }
RFC: Problems which we already solved by taking modern approaches and what should we do next
This issue is here to help people understand why I have created a new plugin that diversified the protocol buffer typescript community even more.
Q:
Why would you create a plugin from scratch when you can fix problems on the upstream compiler?
A:
Well it is not that simple because there is a lot of bureaucracy to make any of the design changes that I have done with this plugin. Even if we managed to pass that, there would be breaking changes that will not make design changes like this.
Q:
Why should I use this plugin when I can use https://github.com/improbable-eng/ts-protoc-gen?
A:
Keep in mind that "ts-protoc-gen" generates only d.ts
binding which basically a type declaration file for the javascript output that has been generated by the official protoc compiler. This comes with a trade-off of not being able to customize the d.ts
output as much as we like. If we did. it wouldn't match with the javascript file and you’d get a runtime error even though the typescript compiler wouldn’t complain about the javascript file being different than the d.ts
file. So ts-protoc-gen
has to match the javascript file which limits its ability to compile proto files to modern typescript syntax.
Q:
How does protoc-gen-ts
solve this problem?
A:
By throwing away the javascript compiler of the official protoc compiler. Instead, we generate a typescript file (".ts" not "d.ts") which includes the runtime code that will run on the underlying javascript engine when it is running. Hence we have the ability to generate the proto files the way we want them.
There are a number of things that we do differently than the official protoc compiler that complies to javascript such as "generating files as typescript getter setter" which in turn you get the exact names that you have defined in the proto message. For instance, when you have a field named user_messages
with the official compiler you'll get getUserMessages()
. however, if you use this plugin, you’ll just access the property as is like user_messages
.
Also, your enums
will be generated as a typescript enum
instead of an interface
or object
with predefined keys.
disable namespace
If the package name is a namespace name that ts does not support, then the generated ts cannot be used:
proto:
package xxx.xxx.xxx;
ts:
export namespace xxx.xxx.xxx {}
It fails on Windows
Hello!
Unfortunately I have some issues on Windows 11 and I can't get it to work.
ERROR: C:/users/xnerh/projects/blazity/gladiator-game/backend/questions-proto/BUILD.bazel:27:17: Generating Protocol Buffers for Typescript //backend/questions-proto:components_proto failed: (Exit 1): protoc.exe failed: error executing command
cd C:/users/xnerh/_bazel_xnerh/kiuaadle/execroot/init
SET GRPC_PACKAGE_NAME=@grpc/grpc-js
bazel-out/x64_windows-opt-exec-2B5CBBC6/bin/external/com_google_protobuf/protoc.exe --plugin=protoc-gen-ts=bazel-out/x64_windows-opt-exec-2B5CBBC6/bin/external/npm/protoc-gen-ts/bin/protoc-gen-ts.bat --ts_out=bazel-out/x64_windows-fastbuild/bin --descriptor_set_in=bazel-out/x64_windows-fastbuild/bin/external/com_google_protobuf/empty_proto-descriptor-set.proto.bin:bazel-out/x64_windows-fastbuild/bin/backend/questions-proto/proto-descriptor-set.proto.bin backend/questions-proto/user.proto
Execution platform: @local_config_platform//:host
bazel-out/x64_windows-fastbuild/bin/external/com_google_protobuf/empty_proto-descriptor-set.proto.bin:bazel-out/x64_windows-fastbuild/bin/backend/questions-proto/proto-descriptor-set.proto.bin: No such file or directory
Target //backend/questions-proto:components_proto failed to build
INFO: Elapsed time: 50.090s, Critical Path: 0.70s
INFO: 188 processes: 172 remote cache hit, 16 internal.
FAILED: Build did NOT complete successfully
Here is my BUILD:
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@npm//protoc-gen-ts:index.bzl", "ts_proto_library")
proto_library(
name = "proto",
srcs = ["user.proto"],
deps = ["@com_google_protobuf//:empty_proto"],
)
ts_proto_library(
name = "components_proto",
deps = [
":proto",
],
)
Solve issues that won’t be solved by the js version soon
This is a general issue for the issues we could solve here;
Message with repeated custom type generating incorrect key name in AsObject/toObject()
I'm pretty new to Protobuf but have come across something odd in a current project. Given this proto file:
syntax = "proto3";
package technician.api.v1;
message Technician {
// The id for the contractor.
optional int32 id = 1;
// The technician_ref for the contractor.
optional string technician_ref = 2;
// The oem_ref for the contractor.
optional string oem_ref = 3;
}
service TechnicianAPI {
// Return a list of 0 or more technicians for the given request.
rpc ListTechnicians(ListTechniciansRequest) returns (ListTechniciansResponse);
}
// A response containing a list of technicians.
message ListTechniciansResponse {
repeated Technician technicians = 1;
}
// A request to list technicians.
message ListTechniciansRequest {
// The technician_ref to start listing from. If not provided, start from the beginning.
string start_technician_ref = 1;
// The maximum number of results to return, default to 100
uint32 count = 2;
}
When the typescript is generated the ListTechnicianResponse
looks like this.
export namespace ListTechniciansResponse {
export type AsObject = {
techniciansList: Array<technician_api_v1_technician_pb.Technician.AsObject>,
}
}
The key technicians
is now suffixed with List
which doesn't match the protobuf and as such doesn't result in the correct output when returned. Again I'm new to protobuf so if this is expected behaviour please let me know but this doesn't seem correct to me and I don't see anything about it in any documentation.
Generated code for nested enum failed
Proto:
package test;
message Code {
enum Language {
UNKNOWN = 0;
C = 1;
CPP = 2;
}
Language language = 1;
int32 lines = 2;
}
Generated:
import * as pb_1 from "google-protobuf";
export namespace test {
export class Code extends pb_1.Message {
constructor(data?: any[] | {
language?: Code.Language;
lines?: number;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) && data, 0, -1, [], null);
if (!Array.isArray(data) && typeof data == "object") {
this.language = data.language;
this.lines = data.lines;
}
}
get language(): Code.Language | undefined {
return pb_1.Message.getFieldWithDefault(this, 1, undefined) as Code.Language | undefined;
}
set language(value: Code.Language) {
pb_1.Message.setField(this, 1, value);
}
get lines(): number | undefined {
return pb_1.Message.getFieldWithDefault(this, 2, undefined) as number | undefined;
}
set lines(value: number) {
pb_1.Message.setField(this, 2, value);
}
toObject() {
return {
language: this.language,
lines: this.lines
};
}
serialize(w?: pb_1.BinaryWriter): Uint8Array | undefined {
const writer = w || new pb_1.BinaryWriter();
if (this.language !== undefined)
writer.writeEnum(1, this.language);
if (this.lines !== undefined)
writer.writeInt32(2, this.lines);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): Code {
const reader = bytes instanceof Uint8Array ? new pb_1.BinaryReader(bytes) : bytes, message = new Code();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
message.language = reader.readEnum();
break;
case 2:
message.lines = reader.readInt32();
break;
default: reader.skipField();
}
}
return message;
}
}
}
Error:
src/protos_gen/test.ts:5:24 - error TS2702: 'Code' only refers to a type, but is being used as a namespace here.
5 language?: Code.Language;
Essentially, the enum is not generated at all. Causing this error. One suggestion is generate the enum as <CLASS_NAME>_<ENUM_NAME> to avoid colliding.
Parse from JSON
I have a JSON file and I want my protobuf message to parse JSON. How to implement this? Thanks!
Is there a tutorial on how to use it
I want to trying,but no tutorials found in readme。
thanks
Finish oneof support
Thanks so much for working on this project! Hope this bug will help :). I looked at your code for a bit to see if I could write you a pull request, but wasn't sure where to start.
To complete oneof support, there should be helper functions to determine what case is set.
https://developers.google.com/protocol-buffers/docs/reference/javascript-generated#oneof
So taking the example from above:
package account;
message Profile {
oneof avatar {
string image_url = 1;
bytes image_data = 2;
}
}
There should be a generated enum representing the cases, so for the above example:
proto.account.Profile.AvatarCase = {
AVATAR_NOT_SET: 0,
IMAGE_URL: 1,
IMAGE_DATA: 2
};
And a getter that returns the enum value that is currently set, getAvatarCase().
How to run on windows?
Hello, I am having trouble trying to compile on windows10.
.\protoc.exe -I=proto_src --ts_out=dist message.proto
throws 'protoc-gen-ts' is not recognized as an internal or external command, operable program or batch file. --ts_out: protoc-gen-ts: Plugin failed with status code 1.
error.
And when I use .\protoc.exe --plugin=protoc-gen-ts=<absolute_path_to_project>/node_modules/protoc-gen-ts/bin/protoc-gen-ts -I=proto_src --ts_out=dist message.proto
, it throws --ts_out: protoc-gen-ts: %1 is not a valid Win32 application.
And it only takes absolute path. Doesn't work with relative path.
I have observed that in other typescript generators, there was cmd script given in bin folder of package. But in my npm download, there is only javascript code without any extension to the file but with first line saying '#!/usr/bin/env node'. This made me think if this is made only for shells in unix systems and not windows.
I neither have bazel on my system and nor am I familiar with it. So, I would like to know how to generate files on windows(if it is possible), preferably without bazel.
Maps support
Hi,
atm, I have an issue with working with map types in the typescript generated messages.
In my Proto files, I use map<key, value> type.
In the .AsObject also it appears as Array<[key, value]>. And in the main jspb.Message type, there is only a getter and a clear method for it.
Any way to work around it?
deserialize uses dubious test for reader vs bytes
There are cases where (bytes instanceof Uint8Array) fails.
More robust to reverse the test, and look for definite BinaryReader.
from:
const reader = bytes instanceof Uint8Array ? new pb_1.BinaryReader(bytes) : bytes, message = new XXX();
to:
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new XXX();
My auto-patching tricked me into thinking this was fixed back in -rc3
Support for oneof Fields
Support for handling oneof
fields is a must-have.
I know that this is already a TODO in the code, but I just wanted to create a reminder.
Consider aligning API w/ Bazel proto idioms
Hey there, I was reviewing this example and I notice your example could be more idiomatic with existing Bazel proto rules.
-
<lang>_proto_library
should prefer to usedeps
on aproto_library
vs referring to it as asrc
. Example can be found here: https://docs.bazel.build/versions/master/be/java.html#java_proto_library. The rationale being this is generating source code from a collection of dependencies and is usually expressed that way. -
ts_library
targets that wish to use the generated ts lang proto library should express dependency on the target usingdeps
instead ofsrc
. It's considered generally a best practice to declare a label insrcs
that is directly are directly consumed by the rule that output source files (citation). In this particular case, I believe thets_library
is depending on a previously generated target and wouldn't be expected to list it as a src of the library itself. Additionally, its considered a best practice to not have the same file listed insrcs
of multiple targets, which this would cause.
Experimental Promises Do Not Work (Cannot read property 'interceptors' of undefined)
After enabling experimental_features
, I get the following error:
TypeError: Cannot read property 'interceptors' of undefined
at ExampleClient.makeUnaryRequest (app/client_image.binary.runfiles/npm/node_modules/@grpc/grpc-js/src/client.ts:295:52)
at ExampleClient.add (app/client_image.binary.runfiles/npm/node_modules/@grpc/grpc-js/src/make-client.ts:174:15)
at example.ts:123:61
at new Promise (<anonymous>)
at ExampleClient.add (example.ts:123:16)
at client.ts:17:33
at Generator.next (<anonymous>)
at /app/client_image.binary.runfiles/repro/client.js:7:71
at new Promise (<anonymous>)
at __awaiter (/app/client_image.binary.runfiles/repro/client.js:3:12)
You can try it yourself by cloning this commit:
https://github.com/flolu/typescript-protobuf-bazel-rpc/tree/8f1c47cb9944064384e9f87db2c30f0a98a2b6a2
- Run
yarn install && yarn build
- Run
yarn start:server
- Run
yarn start:client
(error is in the client)
Help users understand tradeoffs with alternatives
It would be nice if the readme helped me understand whether to use this package or the alternative
https://github.com/improbable-eng/ts-protoc-gen
with its Bazel rules
https://github.com/Dig-Doug/rules_typescript_proto
Do you already know what tradeoffs make this package better or that one for some use cases?
Support for `optional` in proto3
Calling protoc with --experimental_allow_proto3_optional
returns
filename.proto is a proto3 file that contains optional fields, but code generator protoc-gen-ts hasn't been updated to support optional fields in proto3. Please ask the owner of this code generator to support proto3 optional.
For more information on implementation, see: https://github.com/protocolbuffers/protobuf/blob/master/docs/implementing_proto3_presence.md
Add license information
There should be a LICENSE file in the project with license information so people know if they can use it in their own projects.
Generated TS is invalid if proto has a message type `Map` and other messages that use the built in `map` type
Hi there,
Thanks for the library! I'd love to use it but I'm running into an issue that would be a stopper for our team. We have a proto file like this:
message Map {
string key = 1;
string value = 2;
}
message Foo {
map<string, string> fields = 1;
}
When this library generates a TS file from it, the generated code fails TS compilation. The code the library spits out doesn't distinguish between its usage of the user-defined Map
and the Map
generic built into TypeScript.
I have an example repo that shows the issue.
I don't know the TS compiler API at all, but I'm curious if you think fixing this would be an easy or small task? I might be able to fix it with some guidance 😄
Again, thanks for the library and for your time!
Compiler fails to build typescript proto definitions
I am trying to compile the TS definitions according to the documentation, but I have encountered some issues when running the following command:
protoc \
--ts_out=grpc_js:../autogen \
-I ./proto \
./proto/*.proto
The script fails and exists with the following message:
--ts_out: protoc-gen-ts: Plugin failed with status code 1.
As you can see on the following screenshot:
My dependencies are the following:
"dependencies": {
"@grpc/grpc-js": "^1.1.7",
"@grpc/proto-loader": "^0.5.5",
"@types/google-protobuf": "^3.7.3",
"@types/node": "^14.11.8",
"google-protobuf": "^3.13.0",
"ts-node-dev": "^1.0.0-pre.63",
"typescript": "^4.0.3"
},
"devDependencies": {
"grpc-tools": "^1.9.1",
"grpc_tools_node_protoc_ts": "^5.0.0",
"protoc-gen-ts": "^0.3.4"
}
My tsconfig file definition is the following:
{
"compilerOptions": {
"moduleResolution": "node",
"module": "commonjs",
"target": "ES6",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
},
"exclude": ["node_modules", "**/*.spec.ts"]
}
哥们额,多来点文档
详细介绍一下生成的范围和目前使用有没有什么问题呢?最好带一点*气的示例。
支持类似于这样的操作吗?
class ProtoCoder {
decode<T extends Message>(bytes: Unit8Arrays, clz: new(): T): T
}
than:
const m1: Person = decode(bytes, Person)
const m2: People = decode(bytes, People)
Support of google.rpc.status
Google's Status proto allows customizing errors thrown by the server and received by a client.
Here is one of the implementations I found out there, adopting this behavior into GRPC server/client:
https://github.com/quangtm210395/grpc-node-status-proto
Would it be possible to have the ability to customize errors as this?
fromObject is not in v0.5.0
First I do want to thank you for creating this compiler. It is definitely very helpful and good features. I was especially excited on seeing the fromObject
support but it seems to be that it's not in the current release. I can see the version that I installed is 0.5.0 but even in it's source I cannot find the changes related to fromObject.
Support of string-based enums
I know this kind of a limitation of proto
protocol, but would be good to have the ability to have string-based enums in TS.
enum EmploymentStatus {
unemployed = 0;
employed = 1;
student = 2;
retired = 3;
}
it intended to be in the TS:
enum EmploymentStatus = {
unemployed = 'unemployed';
employed = 'employed';
student = 'student';
retired = 'retired';
}
Getting to 1.0
This is putting in a handful of notes. I would like to help push this package to a formal 1.0 release so that it can get better adoption. I'm selfish in that way which is I want to make sure I've got stable programs that I'm building against that have more maintainers...
There are a handful of things that I perceive that might help:
Moving the codebase to TypeScript-- just makes it look better to outsidersIssues: WindowsIssues: CamelCaseIssues: Namespacesdefinition
in Unimplemented Service Definitions - it feels wrong to a first readExtra imports when not used- Escaping of reserved words (not gonna fix it.)
grpc-web client/support
Anything else?
Request: Show How to Properly Do Client-Server Communication in Example
with grpc-node
How do I bundle outputs for use in other typescript projects?
Imagine a directory structure like:
protos \
service1
blah.proto
...
service2
fubar.proto
assuming I generate working ts using this plugin, how can I export the output (while preserving directory strcuture) for the purpose of importing and using client stubs in other repositories?
reimplement serialize as serializeBinary & serializeBinaryToWriter
serialize
does not exist onMessage
but is implemented similarly to how the staticserializeBinaryToWriter
should be implemented. Removing is a breaking change.serializeBinary
is not implemented/generated but a properabstract
method onMessage
(adding throwing stub in #12)
Add option to not use namespaces
The generated code uses namespaces to organize the generated members; however, create-react-app
's built-in Babel config does not support namespaces. The error message:
SyntaxError: Namespace not marked type-only declare. Non-declarative namespaces are only supported experimentally in Babel. To enable and review caveats see: https://babeljs.io/docs/en/babel-plugin-transform-typescript
Enabling namespaces is not possible with create-react-app
. Is it possible to add an option to the generator to not use namespaces?
Dots in Filenames Cause Errors
It seems as if dots in filenames cuase errors:
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@npm//protoc-gen-ts:index.bzl", "ts_proto_library")
package(default_visibility = ["//visibility:public"])
# works fine
proto_library(
name = "message_proto",
srcs = ["message.proto"],
)
ts_proto_library(
name = "message",
deps = [
":message_proto",
],
)
# doesn't work
proto_library(
name = "other_message_proto",
srcs = ["other.message.proto"],
)
ts_proto_library(
name = "other_message",
deps = [
":other_message_proto",
],
)
The second one throws:
ERROR: /home/flolu/Desktop/protoc-gen-ts-filename-repro/BUILD.bazel:23:17: output 'other.message.ts' was not created
ERROR: /home/flolu/Desktop/protoc-gen-ts-filename-repro/BUILD.bazel:23:17: not all outputs were created or valid
I've made a small repro here: https://github.com/flolu/protoc-gen-ts-filename-repro
fix: import public causes AssertionError
This works fine:
import "models/health_check_response_pb.proto";
This one crashes protoc:
import public "models/health_check_response_pb.proto";
Logs:
> Executing task: yarn run proto:protoc-gen-ts <
yarn run v1.19.0
$ yarn run grpc_tools_node_protoc --plugin=protoc-gen-ts=../../node_modules/.bin/protoc-gen-ts --ts_out=grpc_js:./src/main/typescript/generated/proto/protoc-gen-ts/ --proto_path ./src/main/proto/generated/openapi/ --proto_path ./src/main/proto/generated/openapi/models/ --proto_path ./src/main/proto/generated/openapi/services/ ./src/main/proto/generated/openapi/models/*.proto ./src/main/proto/generated/openapi/services/*.proto
$ /******/node_modules/.bin/grpc_tools_node_protoc --plugin=protoc-gen-ts=../../node_modules/.bin/protoc-gen-ts --ts_out=grpc_js:./src/main/typescript/generated/proto/protoc-gen-ts/ --proto_path ./src/main/proto/generated/openapi/ --proto_path ./src/main/proto/generated/openapi/models/ --proto_path ./src/main/proto/generated/openapi/services/ ./src/main/proto/generated/openapi/models/health_check_response_pb.proto ./src/main/proto/generated/openapi/models/memory_usage_pb.proto ./src/main/proto/generated/openapi/services/default_service.proto
/******/node_modules/google-protobuf/google-protobuf.js:81
jspb.BinaryConstants.TWO_TO_32=4294967296;jspb.BinaryConstants.TWO_TO_52=4503599627370496;jspb.BinaryConstants.TWO_TO_63=0x7fffffffffffffff;jspb.BinaryConstants.TWO_TO_64=1.8446744073709552E19;jspb.BinaryConstants.ZERO_HASH="\x00\x00\x00\x00\x00\x00\x00\x00";goog.dom={};goog.dom.NodeType={ELEMENT:1,ATTRIBUTE:2,TEXT:3,CDATA_SECTION:4,ENTITY_REFERENCE:5,ENTITY:6,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,NOTATION:12};goog.debug={};goog.debug.Error=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,goog.debug.Error);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a));this.reportErrorToServer=!0};goog.inherits(goog.debug.Error,Error);goog.debug.Error.prototype.name="CustomError";goog.asserts={};goog.asserts.ENABLE_ASSERTS=goog.DEBUG;goog.asserts.AssertionError=function(a,b){goog.debug.Error.call(this,goog.asserts.subs_(a,b));this.messagePattern=a};goog.inherits(goog.asserts.AssertionError,goog.debug.Error);goog.asserts.AssertionError.prototype.name="AssertionError";goog.asserts.DEFAULT_ERROR_HANDLER=function(a){throw a;};goog.asserts.errorHandler_=goog.asserts.DEFAULT_ERROR_HANDLER;
Error [AssertionError]: Assertion failed
at new goog.asserts.AssertionError (/******/node_modules/google-protobuf/google-protobuf.js:81:876)
at Object.goog.asserts.doAssertFailure_ (/******/node_modules/google-protobuf/google-protobuf.js:82:257)
at Object.goog.asserts.assert (/******/node_modules/google-protobuf/google-protobuf.js:83:83)
at jspb.BinaryReader.readPackedField_ (/******/node_modules/google-protobuf/google-protobuf.js:398:249)
at jspb.BinaryReader.readPackedInt32 (/******/node_modules/google-protobuf/google-protobuf.js:399:68)
at Function.deserialize (/******/node_modules/protoc-gen-ts/src/compiler/descriptor.js:233:56)
at /******/node_modules/protoc-gen-ts/src/compiler/plugin.js:193:151
at jspb.BinaryReader.readMessage (/******/node_modules/google-protobuf/google-protobuf.js:385:329)
at Function.deserialize (/******/node_modules/protoc-gen-ts/src/compiler/plugin.js:193:28)
at Object.<anonymous> (/******/node_modules/protoc-gen-ts/src/index.js:22:45) {
reportErrorToServer: true,
messagePattern: 'Assertion failed'
}
--ts_out: protoc-gen-ts: Plugin failed with status code 1.
/******/node_modules/grpc-tools/bin/protoc.js:41
throw error;
^
Error: Command failed: /******/node_modules/grpc-tools/bin/protoc --plugin=protoc-gen-grpc=/******/node_modules/grpc-tools/bin/grpc_node_plugin --plugin=protoc-gen-ts=../../node_modules/.bin/protoc-gen-ts --ts_out=grpc_js:./src/main/typescript/generated/proto/protoc-gen-ts/ --proto_path ./src/main/proto/generated/openapi/ --proto_path ./src/main/proto/generated/openapi/models/ --proto_path ./src/main/proto/generated/openapi/services/ ./src/main/proto/generated/openapi/models/health_check_response_pb.proto ./src/main/proto/generated/openapi/models/memory_usage_pb.proto ./src/main/proto/generated/openapi/services/default_service.proto
/******/node_modules/google-protobuf/google-protobuf.js:81
jspb.BinaryConstants.TWO_TO_32=4294967296;jspb.BinaryConstants.TWO_TO_52=4503599627370496;jspb.BinaryConstants.TWO_TO_63=0x7fffffffffffffff;jspb.BinaryConstants.TWO_TO_64=1.8446744073709552E19;jspb.BinaryConstants.ZERO_HASH="\x00\x00\x00\x00\x00\x00\x00\x00";goog.dom={};goog.dom.NodeType={ELEMENT:1,ATTRIBUTE:2,TEXT:3,CDATA_SECTION:4,ENTITY_REFERENCE:5,ENTITY:6,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,NOTATION:12};goog.debug={};goog.debug.Error=function(a){if(Error.captureStackTrace)Error.captureStackTrace(this,goog.debug.Error);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a));this.reportErrorToServer=!0};goog.inherits(goog.debug.Error,Error);goog.debug.Error.prototype.name="CustomError";goog.asserts={};goog.asserts.ENABLE_ASSERTS=goog.DEBUG;goog.asserts.AssertionError=function(a,b){goog.debug.Error.call(this,goog.asserts.subs_(a,b));this.messagePattern=a};goog.inherits(goog.asserts.AssertionError,goog.debug.Error);goog.asserts.AssertionError.prototype.name="AssertionError";goog.asserts.DEFAULT_ERROR_HANDLER=function(a){throw a;};goog.asserts.errorHandler_=goog.asserts.DEFAULT_ERROR_HANDLER;
Error [AssertionError]: Assertion failed
at new goog.asserts.AssertionError (/******/node_modules/google-protobuf/google-protobuf.js:81:876)
at Object.goog.asserts.doAssertFailure_ (/******/node_modules/google-protobuf/google-protobuf.js:82:257)
at Object.goog.asserts.assert (/******/node_modules/google-protobuf/google-protobuf.js:83:83)
at jspb.BinaryReader.readPackedField_ (/******/node_modules/google-protobuf/google-protobuf.js:398:249)
at jspb.BinaryReader.readPackedInt32 (/******/node_modules/google-protobuf/google-protobuf.js:399:68)
at Function.deserialize (/******/node_modules/protoc-gen-ts/src/compiler/descriptor.js:233:56)
at /******/node_modules/protoc-gen-ts/src/compiler/plugin.js:193:151
at jspb.BinaryReader.readMessage (/******/node_modules/google-protobuf/google-protobuf.js:385:329)
at Function.deserialize (/******/node_modules/protoc-gen-ts/src/compiler/plugin.js:193:28)
at Object.<anonymous> (/******/node_modules/protoc-gen-ts/src/index.js:22:45) {
reportErrorToServer: true,
messagePattern: 'Assertion failed'
}
--ts_out: protoc-gen-ts: Plugin failed with status code 1.
at ChildProcess.exithandler (node:child_process:326:12)
at ChildProcess.emit (node:events:365:28)
at maybeClose (node:internal/child_process:1067:16)
at Socket.<anonymous> (node:internal/child_process:453:11)
at Socket.emit (node:events:365:28)
at Pipe.<anonymous> (node:net:661:12) {
killed: false,
code: 1,
signal: null,
cmd: '/******/node_modules/grpc-tools/bin/protoc --plugin=protoc-gen-grpc=/******/node_modules/grpc-tools/bin/grpc_node_plugin --plugin=protoc-gen-ts=../../node_modules/.bin/protoc-gen-ts --ts_out=grpc_js:./src/main/typescript/generated/proto/protoc-gen-ts/ --proto_path ./src/main/proto/generated/openapi/ --proto_path ./src/main/proto/generated/openapi/models/ --proto_path ./src/main/proto/generated/openapi/services/ ./src/main/proto/generated/openapi/models/health_check_response_pb.proto ./src/main/proto/generated/openapi/models/memory_usage_pb.proto ./src/main/proto/generated/openapi/services/default_service.proto'
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
The terminal process "bash '-c', 'yarn run proto:protoc-gen-ts'" terminated with exit code: 1.
Terminal will be reused by tasks, press any key to close it.
"deserializeBinary" do not exist in "typeof Map"
my proto:
message QueryTagGroupResponse
{
uint32 result = 1;
string reason = 2;
map<string, string> tag_path = 3;
}
...
rpc QueryTagsPath(stream QueryTagGroupRequest) returns (stream QueryTagGroupResponse){}
Maybe it's a problem of @types/google-protobuf?
TypeError: Cannot read property 'hasOwnProperty' of null
Attempting to use this plugin with grpc-tools
from grpc-node
package:
protoc \
--proto_path=proto/schemas \
--plugin=protoc-gen-grpc="$(which grpc_node_plugin)" \
--js_out=import_style=commonjs,binary:proto/js \
--ts_out="proto/js" \
--grpc_out=grpc_js:proto/js \
./proto/schemas/*.proto
Results in:
/home/cmcdragonkai/Projects/js-polykey/node_modules/typescript/lib/typescript.js:12449
return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
^
TypeError: Cannot read property 'hasOwnProperty' of null
at Object.isNodeArray (/home/cmcdragonkai/Projects/js-polykey/node_modules/typescript/lib/typescript.js:12449:22)
at createNodeArray (/home/cmcdragonkai/Projects/js-polykey/node_modules/typescript/lib/typescript.js:20812:25)
at Object.createCallExpression (/home/cmcdragonkai/Projects/js-polykey/node_modules/typescript/lib/typescript.js:22099:95)
at Object.createCall (/home/cmcdragonkai/Projects/js-polykey/node_modules/typescript/lib/typescript.js:3022:29)
at createToObject (/home/cmcdragonkai/Projects/js-polykey/node_modules/protoc-gen-ts/index.js:49:14)
at createMessage (/home/cmcdragonkai/Projects/js-polykey/node_modules/protoc-gen-ts/index.js:1016:5)
at processMessageDescriptor (/home/cmcdragonkai/Projects/js-polykey/node_modules/protoc-gen-ts/index.js:1545:5)
at processProtoDescriptor (/home/cmcdragonkai/Projects/js-polykey/node_modules/protoc-gen-ts/index.js:1590:12)
at main (/home/cmcdragonkai/Projects/js-polykey/node_modules/protoc-gen-ts/index.js:1680:24)
at Object.<anonymous> (/home/cmcdragonkai/Projects/js-polykey/node_modules/protoc-gen-ts/index.js:1765:1)
--ts_out: protoc-gen-ts: Plugin failed with status code 1.
0.3.6-rc3 regression: missing '?' in message constructor (for repeated and map fields)
Fields marked with 'repeated' or 'map' are missing the optional indicator; '?' in the Message constructor signature.
TypeError: Cannot read property 'hasOwnProperty' of null
D:\IdeaProjects\ml\ml-shared>npm install -g protoc-gen-ts
C:\Users\yzf\AppData\Roaming\npm\protoc-gen-ts -> C:\Users\yzf\AppData\Roaming\npm\node_modules\protoc-gen-ts\bin\protoc-gen-ts
npm WARN [email protected] requires a peer of typescript@^4.0.2 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of google-protobuf@^3.13.0 but none is installed. You must install peer dependencies yourself.
- [email protected]
added 1 package in 0.267s
D:\IdeaProjects\ml\ml-shared>protoc-3.9.0-windows-x86_64.exe --ts_out=dist ./proto/game.proto
C:\Users\yzf\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:12449
return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
^
TypeError: Cannot read property 'hasOwnProperty' of null
at Object.isNodeArray (C:\Users\yzf\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:12449:22)
at createNodeArray (C:\Users\yzf\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:20812:25)
at Object.createCallExpression (C:\Users\yzf\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:22099:95)
at Object.createCall (C:\Users\yzf\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:3022:29)
at createToObject (C:\Users\yzf\AppData\Roaming\npm\node_modules\protoc-gen-ts\index.js:49:14)
at createMessage (C:\Users\yzf\AppData\Roaming\npm\node_modules\protoc-gen-ts\index.js:1016:5)
at processMessageDescriptor (C:\Users\yzf\AppData\Roaming\npm\node_modules\protoc-gen-ts\index.js:1545:5)
at processProtoDescriptor (C:\Users\yzf\AppData\Roaming\npm\node_modules\protoc-gen-ts\index.js:1590:12)
at main (C:\Users\yzf\AppData\Roaming\npm\node_modules\protoc-gen-ts\index.js:1680:24)
at Object. (C:\Users\yzf\AppData\Roaming\npm\node_modules\protoc-gen-ts\index.js:1765:1)
--ts_out: protoc-gen-ts: Plugin failed with status code 1.
Migrate away from grpc to @grpc/grpc-js
We have already talked about it. This just serves as a reminder.
The grpc package is more or less deprecated. Thus we should migrate to using @grpc/grpc-js instead.
But it might not be enough to just interchange them. Since it seems as if there are small incompatibilities.
Camel case support
Now plugin outputs class getters and setters with the same name as in proto files.
It will be nice to have option to generate camelCase fields.
For instance for proto:
syntax = "proto3";
message Change {
string long_name = 1;
}
have generated class:
export class Change {
// omitted lines...
get longName() {
// omitted lines...
}
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.