Git Product home page Git Product logo

protoc-gen-ts's Introduction

Protoc Gen Typescript

conformance test npm npm npm

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.

Contributing

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.

See issues that needs help

See issues for newcomers

Become a maintainer? Send an email

Features

  • 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.

Usage

npm install -g protoc-gen-ts

Protoc

protoc -I=sourcedir --ts_out=dist myproto.proto

Buf

version: v1
plugins:
  - name: ts
    path: ./node_modules/.bin/protoc-gen-ts
    out: ./dist

Example

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())

Development

./infra/test.sh

Contributors

GitHub Contributors Image

Support

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

Contributors

aperron avatar custompro98 avatar davearata-snorack avatar dependabot[bot] avatar dreamershl avatar flolu avatar koblas avatar marcushultman avatar rahulv4667 avatar renkei avatar sandmule avatar thesayyn avatar zeidoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

protoc-gen-ts's Issues

`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]

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;
    }
}

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?

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().

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[]'.

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.

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.

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... 
}

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.

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.

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:

image

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"]
}

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

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 {}

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.

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.

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?

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.

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.

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!

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 outsiders
  • Issues: Windows
  • Issues: CamelCase
  • Issues: Namespaces
  • definition in Unimplemented Service Definitions - it feels wrong to a first read
  • Extra imports when not used
  • Escaping of reserved words (not gonna fix it.)
  • grpc-web client/support

Anything else?

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.

  1. <lang>_proto_library should prefer to use depson a proto_library vs referring to it as a src. 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.

  2. ts_library targets that wish to use the generated ts lang proto library should express dependency on the target using deps instead of src. It's considered generally a best practice to declare a label in srcs that is directly are directly consumed by the rule that output source files (citation). In this particular case, I believe the ts_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 in srcs of multiple targets, which this would cause.

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.

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.

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';
}

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.

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.

[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); }

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:
image
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.
image

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?

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.

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",
    ],
)

It's weird because the file is there in dist folder.
image

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.

Parse from JSON

I have a JSON file and I want my protobuf message to parse JSON. How to implement this? Thanks!

哥们额,多来点文档

详细介绍一下生成的范围和目前使用有没有什么问题呢?最好带一点*气的示例。
支持类似于这样的操作吗?

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)

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.

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.

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

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?

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

  1. Run yarn install && yarn build
  2. Run yarn start:server
  3. Run yarn start:client (error is in the client)

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.