diff --git a/.github/renovate.json5 b/.github/renovate.json5 index dedaca07..e20126d6 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -123,6 +123,16 @@ ], depNameTemplate: "google.golang.org/grpc", datasourceTemplate: "go", + }, + { + fileMatch: [ + "variables.sh$" + ], + matchStrings: [ + "TS_PROTO_VERSION=\\$\\{TS_PROTO_VERSION:-(?.*?)\\}\\n" + ], + depNameTemplate: "ts-proto", + datasourceTemplate: "npm", } ], packageRules: [ diff --git a/Dockerfile b/Dockerfile index 4269a3b5..65a9da26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,7 @@ ARG node_version ARG node_grpc_tools_node_protoc_ts_version ARG node_grpc_tools_version ARG node_protoc_gen_grpc_web_version +ARG ts_proto_version ARG go_envoyproxy_pgv_version ARG go_mwitkow_gpv_version @@ -133,6 +134,7 @@ ARG node_version ARG node_grpc_tools_node_protoc_ts_version ARG node_grpc_tools_version ARG node_protoc_gen_grpc_web_version +ARG ts_proto_version ARG go_envoyproxy_pgv_version ARG go_mwitkow_gpv_version @@ -153,10 +155,13 @@ RUN set -ex && apt-get update && apt-get install -y --no-install-recommends \ RUN curl -fsSL "https://deb.nodesource.com/setup_${node_version}.x" | bash - RUN apt-get install -y nodejs -# Add TypeScript support +# Add Node TypeScript support RUN npm config set unsafe-perm true RUN npm i -g grpc_tools_node_protoc_ts@$node_grpc_tools_node_protoc_ts_version grpc-tools@$node_grpc_tools_version protoc-gen-grpc-web@$node_protoc_gen_grpc_web_version +# Add TypeScript support +RUN npm i -g ts-proto@$ts_proto_version + COPY --from=build /tmp/googleapis/google/ /opt/include/google COPY --from=build /tmp/api-common-protos/google/ /opt/include/google diff --git a/all/entrypoint.sh b/all/entrypoint.sh index 2c40d5d2..1dca6bd4 100755 --- a/all/entrypoint.sh +++ b/all/entrypoint.sh @@ -39,6 +39,7 @@ printUsage() { echo " --js-out This option overrides the 'js_out=' argument in the grpc-node and grpc-web code generation. Defaults to 'import_style=commonjs'." echo " --grpc-out This option allows overriding the left-half of the 'grpc_out=' argument (before the colon) with grpc-node and grpc-web code generation. Options are: generate_package_definition, grpc_js or grpc(depricated from April 2021). Defaults to grpc_js." echo " --grpc-web-out This option overrides the 'grpc-web_out=' argument in the grpc-web code generation. Defaults to 'import_style=typescript'." + echo " --ts_opt The options to pass to protoc to customize the typescript code generation. See https://github.com/stephenh/ts-proto#supported-options. --ts_opt useOptionals=messages will evaluate to --ts_proto_opt=useOptionals=messages" } GEN_GATEWAY=false @@ -50,7 +51,7 @@ GEN_RBI=false GEN_TYPESCRIPT=false LINT=false LINT_CHECKS="" -SUPPORTED_LANGUAGES=("go" "ruby" "csharp" "java" "python" "objc" "gogo" "php" "node" "web" "cpp" "descriptor_set" "scala") +SUPPORTED_LANGUAGES=("go" "ruby" "csharp" "java" "python" "objc" "gogo" "php" "node" "typescript" "web" "cpp" "descriptor_set" "scala") EXTRA_INCLUDES="" OUT_DIR="" GO_SOURCE_RELATIVE="" @@ -69,6 +70,7 @@ GENERATE_UNBOUND_METHODS=false JS_OUT="import_style=commonjs" WEB_OUT="import_style=typescript" GRPC_OUT="grpc_js" +TYPESCRIPT_OPT="" while test $# -gt 0; do case "$1" in -h|--help) @@ -141,11 +143,11 @@ while test $# -gt 0; do LINT=true if [ "$#" -gt 1 ] && [[ $2 != -* ]]; then LINT_CHECKS=$2 - shift + shift fi shift ;; - --validator-source-relative) + --validator-source-relative) VALIDATOR_SOURCE_RELATIVE=",paths=source_relative" shift ;; @@ -153,7 +155,7 @@ while test $# -gt 0; do GO_SOURCE_RELATIVE="paths=source_relative," shift ;; - --go-module-prefix) + --go-module-prefix) shift GO_MODULE_PREFIX="module=$1," shift @@ -161,7 +163,7 @@ while test $# -gt 0; do --go-package-map) if [ "$#" -gt 1 ] && [[ $2 != -* ]]; then GO_PACKAGE_MAP=$2, - shift + shift fi shift ;; @@ -228,6 +230,11 @@ while test $# -gt 0; do GRPC_OUT=$1 shift ;; + --ts_opt) + shift + TYPESCRIPT_OPT=$1 + shift + ;; *) break ;; @@ -339,7 +346,7 @@ plugins=grpc+embedded\ :$OUT_DIR" ;; "java") - GEN_STRING="--grpc_out=$OUT_DIR --${GEN_LANG}_out=$OUT_DIR --plugin=protoc-gen-grpc=`which grpc_java_plugin`" + GEN_STRING="--grpc_out=$OUT_DIR --${GEN_LANG}_out=$OUT_DIR --plugin=protoc-gen-grpc=$(which grpc_java_plugin)" ;; "scala") SCALA_OUT=$OUT_DIR @@ -348,16 +355,16 @@ plugins=grpc+embedded\ SCALA_OUT="$SCALA_OPT:$OUT_DIR" fi - GEN_STRING="--scala_out=$SCALA_OUT --plugin=`which protoc-gen-scala`" + GEN_STRING="--scala_out=$SCALA_OUT --plugin=$(which protoc-gen-scala)" ;; "node") # add plugin - GEN_STRING="--plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin`" + GEN_STRING="--plugin=protoc-gen-grpc=$(which grpc_tools_node_protoc_plugin)" GEN_STRING="$GEN_STRING --js_out=$JS_OUT,binary:$OUT_DIR --grpc_out=$GRPC_OUT:$OUT_DIR" ;; "web") # add plugins - GEN_STRING=" --plugin=protoc-gen-grpc-web=`which protoc-gen-grpc-web`" + GEN_STRING=" --plugin=protoc-gen-grpc-web=$(which protoc-gen-grpc-web)" GEN_STRING="$GEN_STRING --js_out=$JS_OUT,binary:$OUT_DIR --grpc-web_out=$WEB_OUT,mode=grpcwebtext:$OUT_DIR" ;; "descriptor_set") @@ -370,13 +377,21 @@ plugins=grpc+embedded\ fi ;; "csharp") - GEN_STRING="--grpc_out=$OUT_DIR --csharp_out=$OUT_DIR --plugin=protoc-gen-grpc=`which grpc_csharp_plugin`" + GEN_STRING="--grpc_out=$OUT_DIR --csharp_out=$OUT_DIR --plugin=protoc-gen-grpc=$(which grpc_csharp_plugin)" if [[ ! -z $CSHARP_OPT ]]; then GEN_STRING="$GEN_STRING --csharp_opt=$CSHARP_OPT" fi ;; + "typescript") + # add plugin + GEN_STRING="--plugin=$(which protoc-gen-ts_proto)" + GEN_STRING="$GEN_STRING --ts_proto_out=$OUT_DIR" + if [[ ! -z $TYPESCRIPT_OPT ]]; then + GEN_STRING="$GEN_STRING --ts_proto_opt=$TYPESCRIPT_OPT" + fi + ;; *) - GEN_STRING="--grpc_out=$OUT_DIR --${GEN_LANG}_out=$OUT_DIR --plugin=protoc-gen-grpc=`which grpc_${PLUGIN_LANG}_plugin`" + GEN_STRING="--grpc_out=$OUT_DIR --${GEN_LANG}_out=$OUT_DIR --plugin=protoc-gen-grpc=$(which grpc_${PLUGIN_LANG}_plugin)" ;; esac @@ -410,7 +425,7 @@ if [[ $GEN_RBI == true ]]; then fi if [[ $GEN_TYPESCRIPT == true ]]; then - GEN_STRING="$GEN_STRING --plugin=protoc-gen-ts=`which protoc-gen-ts` --ts_out=$GRPC_OUT:$OUT_DIR" + GEN_STRING="$GEN_STRING --plugin=protoc-gen-ts=$(which protoc-gen-ts) --ts_out=$GRPC_OUT:$OUT_DIR" fi LINT_STRING='' diff --git a/all/test/all_test.go b/all/test/all_test.go index 6eb5d529..032bb289 100644 --- a/all/test/all_test.go +++ b/all/test/all_test.go @@ -552,6 +552,40 @@ func (s *TestSuite) TestAllCases() { }, extraArgs: []string{"--with-validator"}, }, + "typescript": { + lang: "typescript", + protofileName: "all/test/test.proto", + expectedOutputDir: "gen/pb-typescript", + fileExpectations: []FileExpectation{ + {fileName: "all/test/test.ts"}, + }, + }, + "typescript with alternative output dir": { + lang: "typescript", + protofileName: "all/test/test.proto", + expectedOutputDir: "gen/foo/bar", + fileExpectations: []FileExpectation{ + {fileName: "all/test/test.ts", assert: func(filePath, expectedValue string) { + fileText := s.readFile(filePath) + s.Assert().True(strings.Contains(fileText, expectedValue), "does not contain \"%s\"", expectedValue) + // without useOptionals=messages uses `string[] | undefined` syntax. by default. + }, expectedValue: "updateMask: string[] | undefined;"}, + }, + extraArgs: []string{"-o", "gen/foo/bar"}, + }, + "typescript with arguments": { + lang: "typescript", + protofileName: "all/test/test.proto", + expectedOutputDir: "gen/pb-typescript", + fileExpectations: []FileExpectation{ + {fileName: "all/test/test.ts", assert: func(filePath, expectedValue string) { + fileText := s.readFile(filePath) + s.Assert().True(strings.Contains(fileText, expectedValue), "does not contain \"%s\"", expectedValue) + // useOptionals=messages changes `updateMask: string[] | undefined` to `updateMask?: string[]` + }, expectedValue: "updateMask?: string[];"}, + }, + extraArgs: []string{"--ts_opt", "useOptionals=messages"}, + }, } container := os.Getenv("CONTAINER") s.Require().NotEmpty(container, "CONTAINER env var must be set") diff --git a/build.sh b/build.sh index b868e3cf..a4870a43 100755 --- a/build.sh +++ b/build.sh @@ -7,20 +7,21 @@ for build in ${BUILDS[@]}; do echo "building ${build} container with tag ${tag}" docker build -t ${tag} \ -f Dockerfile \ - --build-arg grpc_version=${GRPC_VERSION} \ - --build-arg grpc_java_version=${GRPC_JAVA_VERSION} \ - --build-arg grpc_web_version=${GRPC_WEB_VERSION} \ - --build-arg grpc_gateway_version=${GRPC_GATEWAY_VERSION} \ - --build-arg go_version=${GO_VERSION} \ - --build-arg uber_prototool_version=${UBER_PROTOTOOL_VERSION} \ - --build-arg scala_pb_version=${SCALA_PB_VERSION} \ - --build-arg node_version=${NODE_VERSION} \ - --build-arg node_grpc_tools_node_protoc_ts_version=${NODE_GRPC_TOOLS_NODE_PROTOC_TS_VERSION} \ - --build-arg node_grpc_tools_version=${NODE_GRPC_TOOLS_VERSION} \ - --build-arg node_protoc_gen_grpc_web_version=${NODE_PROTOC_GEN_GRPC_WEB_VERSION} \ - --build-arg go_envoyproxy_pgv_version=${GO_ENVOYPROXY_PGV_VERSION} \ - --build-arg go_mwitkow_gpv_version=${GO_MWITKOW_GPV_VERSION} \ - --target ${build} \ + --build-arg grpc_version="${GRPC_VERSION}" \ + --build-arg grpc_java_version="${GRPC_JAVA_VERSION}" \ + --build-arg grpc_web_version="${GRPC_WEB_VERSION}" \ + --build-arg grpc_gateway_version="${GRPC_GATEWAY_VERSION}" \ + --build-arg go_version="${GO_VERSION}" \ + --build-arg uber_prototool_version="${UBER_PROTOTOOL_VERSION}" \ + --build-arg scala_pb_version="${SCALA_PB_VERSION}" \ + --build-arg node_version="${NODE_VERSION}" \ + --build-arg node_grpc_tools_node_protoc_ts_version="${NODE_GRPC_TOOLS_NODE_PROTOC_TS_VERSION}" \ + --build-arg node_grpc_tools_version="${NODE_GRPC_TOOLS_VERSION}" \ + --build-arg node_protoc_gen_grpc_web_version="${NODE_PROTOC_GEN_GRPC_WEB_VERSION}" \ + --build-arg go_envoyproxy_pgv_version="${GO_ENVOYPROXY_PGV_VERSION}" \ + --build-arg go_mwitkow_gpv_version="${GO_MWITKOW_GPV_VERSION}" \ + --build-arg ts_proto_version="${TS_PROTO_VERSION}" \ + --target "${build}" \ . if [ "${LATEST}" = true ]; then diff --git a/variables.sh b/variables.sh index 20e41785..ec906df5 100755 --- a/variables.sh +++ b/variables.sh @@ -17,6 +17,7 @@ NODE_VERSION=${NODE_VERSION:-14} NODE_GRPC_TOOLS_NODE_PROTOC_TS_VERSION=${NODE_GRPC_TOOLS_NODE_PROTOC_TS_VERSION:-5.3.2} NODE_GRPC_TOOLS_VERSION=${NODE_GRPC_TOOLS_VERSION:-1.11.2} NODE_PROTOC_GEN_GRPC_WEB_VERSION=${NODE_PROTOC_GEN_GRPC_WEB_VERSION:-1.4.0} +TS_PROTO_VERSION=${TS_PROTO_VERSION:1.117.0} GO_ENVOYPROXY_PGV_VERSION=${GO_ENVOYPROXY_PGV_VERSION:-0.6.7} GO_MWITKOW_GPV_VERSION=${GO_MWITKOW_GPV_VERSION:-0.3.2} BUILD_VERSION="${BUILD_VERSION:-local}"