Skip to content

Commit

Permalink
Merge branch 'master' into windows-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
thesayyn committed Oct 13, 2021
2 parents 3a9e655 + ce7dd99 commit d045f57
Show file tree
Hide file tree
Showing 9 changed files with 1,368 additions and 1,126 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: 14.x
- shell: bash
run: yarn test
- shell: bash
- shell: powershell
run: cd examples/pure && yarn --frozen-lockfile && yarn test
test:
runs-on: ${{ matrix.os }}
Expand Down
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
proseWrap: always
singleQuote: false
trailingComma: all
31 changes: 14 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
![npm](https://img.shields.io/npm/v/protoc-gen-ts)
![npm](https://img.shields.io/npm/dm/protoc-gen-ts)

Generates appropriate Protocol Buffer sources from Proto files directly through _TypeScript Compiler API_.

This plugin generates plain **Typescript** files that can be used AMD, UMD, CommonJS module systems.
Aim of this protoc plugin is to make usage of protocol buffers easy in Javascript/Typescript by taking modern approaches. This plugin generates plain **Typescript** files that can be used AMD, UMD, CommonJS module systems.

Aim of this protoc plugin is to make usage of protocol buffers easy in Javascript/Typescript by taking modern approaches.

## Example

Expand Down Expand Up @@ -72,7 +69,7 @@ To overcome this problem, every generated message class has a static method call
which can handle the mapping bidirectionally for you, even with the deeply structured messages. since it is
aware of the field graph, it does not rely on any runtime type information thus we get the chance to keep it fast.

given the change example above, one can write code as;
One can write code as;

```typescript
const change = Change.fromObject({
Expand All @@ -85,13 +82,15 @@ const change = Change.fromObject({
role: "maintainer"
}
});

console.log(change.author instanceof Author) // true
```


## Usage with `@grpc/grpc-js` or `grpc`

There is a seperate documentation for the usage of protoc-gen-ts along with either `@grpc/grpc-js` or `grpc`.
There is a seperate documentation for the usage of protoc-gen-ts along with either `@grpc/grpc-js` or `grpc`. By default
this generated gRPC interfaces will use `@grpc/grpc-js`.

Checkout [rpcs](docs/rpc.md).

Expand Down Expand Up @@ -140,20 +139,12 @@ ts_proto_library(
# Checkout the examples/bazel directory for an example.
```

## Environment variables

```sh
# This controls experimental features such as 'Promise' based rpcs.
export EXPERIMENTAL_FEATURES=true;
## Supported Options

* With `--ts_opt=unary_rpc_promise=true`, the service definition will contain a promise based rpc with a calling pattern of `const result = await client.METHOD(message)`. Note: all othe `metadata` and `options` parameters are still available to you.

# This controls the "import statement" for the outputs.
# this is here for legacy purposes.
export GRPC_PACKAGE_NAME="@grpc/grpc-js";
# or
export GRPC_PACKAGE_NAME="@grpc/grpc";
* With `--ts_opt=grpc_package=xxxx`, you can specify a different package to import rather than `@grpc/grpc-js`.

```
## Roadmap

- <s>Support for repeated non-integer fields</s>
Expand All @@ -178,10 +169,16 @@ export GRPC_PACKAGE_NAME="@grpc/grpc";

## Development

Generates appropriate Protocol Buffer sources from Proto files directly through _TypeScript Compiler API_.

```sh
# to run test invoke
yarn test
# additionally if you want to see error details
yarn test --test_output=errors

```

## Contributors

![GitHub Contributors Image](https://contrib.rocks/image?repo=thesayyn/protoc-gen-ts)
3 changes: 1 addition & 2 deletions examples/pure/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "example",
"scripts": {
"preinstall": "cd ../.. && yarn bazel build :package",
"postinstall": "./scripts/download_protoc.sh",
"test": "protoc -I=src --ts_out=src test.proto && tsc && node ./dist/index"
},
Expand All @@ -10,7 +9,7 @@
"google-protobuf": "^3.15.8"
},
"devDependencies": {
"protoc-gen-ts": "file:../../bazel-bin/package",
"protoc-gen-ts": "file:../../",
"typescript": "^4.2.4"
}
}
251 changes: 140 additions & 111 deletions index.bzl
Original file line number Diff line number Diff line change
@@ -1,111 +1,140 @@
load("@rules_proto//proto:defs.bzl", "ProtoInfo")

def _proto_path(proto):
"""
The proto path is not really a file path
It's the path to the proto that was seen when the descriptor file was generated.
"""
path = proto.path
root = proto.root.path
ws = proto.owner.workspace_root
if path.startswith(root):
path = path[len(root):]
if path.startswith("/"):
path = path[1:]
if path.startswith(ws):
path = path[len(ws):]
if path.startswith("/"):
path = path[1:]
return path

def _ts_proto_library(ctx):

transitive_descriptors = []
direct_sources = []

for target in ctx.attr.deps:
if ProtoInfo not in target:
fail("All targets in the deps attribute should be proto_library target.")
else:
info = target[ProtoInfo]
transitive_descriptors.extend(info.transitive_descriptor_sets.to_list())
direct_sources.extend(info.direct_sources)

ts_outputs = []


for proto in direct_sources:
normalizedProtoName = proto.path.replace(ctx.label.package, "").lstrip("/")[:-len(proto.extension) - 1]
ts_outputs.append(ctx.actions.declare_file("%s.ts" % (normalizedProtoName)))

protoc_args = ctx.actions.args()

protoc_args.add("--plugin=protoc-gen-ts=%s" % (ctx.executable.protoc_gen_ts_bin.path))

protoc_args.add("--ts_out=%s" % (ctx.bin_dir.path))

protoc_args.add("--descriptor_set_in=%s" % (":".join([desc.path for desc in transitive_descriptors])))

protoc_args.add_all(direct_sources)

print(args)

env = dict()

env["GRPC_PACKAGE_NAME"] = ctx.attr.grpc_package_name

if ctx.attr.experimental_features:
env['EXPERIMENTAL_FEATURES'] = "true"

ctx.actions.run(
inputs = direct_sources + transitive_descriptors,
tools = ctx.files.protoc_gen_ts_bin,
executable = ctx.executable._protoc,
outputs = ts_outputs,
arguments = [protoc_args],
env = env,
progress_message = "Generating Protocol Buffers for Typescript %s" % ctx.label,
)

return [
DefaultInfo(files = depset(ts_outputs))
]





ts_proto_library = rule(
implementation = _ts_proto_library,
attrs = {
"deps": attr.label_list(
doc = "List of proto_library targets.",
providers = [ProtoInfo],
mandatory = True
),
"experimental_features": attr.bool(
doc = "Enable experimental features.",
default = False
),
"grpc_package_name": attr.string(
doc = "Configures name of the grpc package to use. '@grpc/grpc-js' or 'grpc'",
default = "@grpc/grpc-js"
),
"protoc_gen_ts_bin": attr.label(
executable = True,
cfg = "host",
default = (
"//protoc-gen-ts/bin:protoc-gen-ts"
),
),
"_protoc": attr.label(
cfg = "host",
executable = True,
allow_single_file = True,
default = (
"@com_google_protobuf//:protoc"
),
),

}
)
load("@rules_proto//proto:defs.bzl", "ProtoInfo")

def _proto_path(proto):
"""
The proto path is not really a file path
It's the path to the proto that was seen when the descriptor file was generated.
"""
path = proto.path
root = proto.root.path
ws = proto.owner.workspace_root
if path.startswith(root):
path = path[len(root):]
if path.startswith("/"):
path = path[1:]
if path.startswith(ws):
path = path[len(ws):]
if path.startswith("/"):
path = path[1:]
return path

def _ts_proto_library(ctx):

transitive_descriptors = []
direct_sources = []

for target in ctx.attr.deps:
if ProtoInfo not in target:
fail("All targets in the deps attribute should be proto_library target.")
else:
info = target[ProtoInfo]
transitive_descriptors.extend(info.transitive_descriptor_sets.to_list())
direct_sources.extend(info.direct_sources)

ts_outputs = []


for proto in direct_sources:
normalizedProtoName = proto.path.replace(ctx.label.package, "").lstrip("/")[:-len(proto.extension) - 1]
ts_outputs.append(ctx.actions.declare_file("%s.ts" % (normalizedProtoName)))

args = ctx.actions.args()

args.add("--plugin=protoc-gen-ts=%s" % (ctx.executable.protoc_gen_ts_bin.path))

args.add("--ts_out=%s" % (ctx.bin_dir.path))

args.add("--descriptor_set_in=%s" % (":".join([desc.path for desc in transitive_descriptors])))

args.add_all(direct_sources)

args.add("--ts_opt=grpc_package=%s" % ctx.attr.grpc_package_name)

if ctx.attr.experimental_features:
args.add("--ts_opt=unary_rpc_promise")

args.add_all(direct_sources)


executable = ""

is_windows_host = ctx.configuration.host_path_separator == ";"


if is_windows_host:
executable = ctx.actions.declare_file("_protoc.cmd")
ctx.actions.write(
executable,
content =
"""@echo off
CALL "{protoc}" %*
""".format(
protoc = ctx.executable._protoc.path,
),
is_executable = True,
)
else:
executable = ctx.actions.declare_file("_protoc.sh")
ctx.actions.write(
executable,
content =
"""#!/usr/bin/env bash
set -e
{protoc} $@
""".format(
protoc = ctx.executable._protoc.path,
),
is_executable = True,
)

ctx.actions.run(
inputs = direct_sources + transitive_descriptors,
tools = [ctx.executable.protoc_gen_ts_bin, ctx.executable._protoc],
executable = executable,
outputs = ts_outputs,
arguments = [args],
progress_message = "Generating Protocol Buffers for Typescript %s" % ctx.label,
)

return [
DefaultInfo(files = depset(ts_outputs))
]





ts_proto_library = rule(
implementation = _ts_proto_library,
attrs = {
"deps": attr.label_list(
doc = "List of proto_library targets.",
providers = [ProtoInfo],
mandatory = True
),
"experimental_features": attr.bool(
doc = "Enable experimental features.",
default = False
),
"grpc_package_name": attr.string(
doc = "Configures name of the grpc package to use. '@grpc/grpc-js' or 'grpc'",
default = "@grpc/grpc-js"
),
"protoc_gen_ts_bin": attr.label(
executable = True,
cfg = "host",
default = (
"//protoc-gen-ts/bin:protoc-gen-ts"
),
),
"_protoc": attr.label(
cfg = "host",
executable = True,
allow_single_file = True,
default = (
"@com_google_protobuf//:protoc"
),
),

}
)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "protoc-gen-ts",
"description": "Compile protocol buffers descriptors to Typescript.",
"version": "0.5.0",
"version": "0.6.0",
"license": "MIT",
"author": {
"email": "[email protected]",
Expand Down
Loading

0 comments on commit d045f57

Please sign in to comment.