From 83801360694c856109c37c02aad014aca951bf90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Fri, 13 Oct 2023 09:50:58 +0200 Subject: [PATCH] Wrapping / Unwrapping Value well-known type in request/response serializers Values of type google.protobuf.Value where not correctly wrapped/unwrapped when directly passed to a service (as a request or response). --- integration/grpc-js/grpc-js-test.ts | 15 +++++++++++++++ integration/grpc-js/simple.ts | 8 ++++---- src/encode.ts | 4 ++-- src/types.ts | 1 + 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/integration/grpc-js/grpc-js-test.ts b/integration/grpc-js/grpc-js-test.ts index 679a15058..15a7eaeb2 100644 --- a/integration/grpc-js/grpc-js-test.ts +++ b/integration/grpc-js/grpc-js-test.ts @@ -214,6 +214,21 @@ describe("grpc-js-test", () => { expect(response).toStrictEqual(timestamp); }); + client.value({ foo: "bar" }, (error: ServiceError | null, response: any) => { + expect(error).toBeNull(); + expect(response).toEqual({ foo: "bar" }); + }); + + client.value(12, (error: ServiceError | null, response: any) => { + expect(error).toBeNull(); + expect(response).toEqual(12); + }); + + client.struct({ foo: "bar" }, (error: ServiceError | null, response: any) => { + expect(error).toBeNull(); + expect(response).toEqual({ foo: "bar" }); + }); + const serverStreamingCall = client.serverStreaming({ timestamp }); serverStreamingCall.on("data", (response) => { expect(response.timestamp).toEqual(timestamp); diff --git a/integration/grpc-js/simple.ts b/integration/grpc-js/simple.ts index 32ae5d001..e2f422c36 100644 --- a/integration/grpc-js/simple.ts +++ b/integration/grpc-js/simple.ts @@ -227,10 +227,10 @@ export const TestService = { path: "/simple.Test/Value", requestStream: false, responseStream: false, - requestSerialize: (value: any | undefined) => Buffer.from(Value.encode(value).finish()), - requestDeserialize: (value: Buffer) => Value.decode(value), - responseSerialize: (value: any | undefined) => Buffer.from(Value.encode(value).finish()), - responseDeserialize: (value: Buffer) => Value.decode(value), + requestSerialize: (value: any | undefined) => Buffer.from(Value.encode(Value.wrap(value)).finish()), + requestDeserialize: (value: Buffer) => Value.unwrap(Value.decode(value)), + responseSerialize: (value: any | undefined) => Buffer.from(Value.encode(Value.wrap(value)).finish()), + responseDeserialize: (value: Buffer) => Value.unwrap(Value.decode(value)), }, listValue: { path: "/simple.Test/ListValue", diff --git a/src/encode.ts b/src/encode.ts index 19274f169..0399ff23b 100644 --- a/src/encode.ts +++ b/src/encode.ts @@ -20,7 +20,7 @@ export function generateEncoder(ctx: Context, typeName: string): Code { return code`${TimestampValue}.encode(${value}).finish()`; } - if (name == "Struct") { + if (name == "Struct" || name == "Value") { const StructType = impProto(ctx.options, "google/protobuf/struct", name); return code`${StructType}.encode(${StructType}.wrap(value)).finish()`; } @@ -75,7 +75,7 @@ export function generateDecoder(ctx: Context, typeName: string): Code { return decoder; } - if (name == "Struct" || name == "ListValue") { + if (name == "Struct" || name == "ListValue" || name == "Value") { TypeValue = impProto(ctx.options, "google/protobuf/struct", name); return code`${TypeValue}.unwrap(${TypeValue}.decode(value))`; } diff --git a/src/types.ts b/src/types.ts index 64213c358..5ab96c83c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -535,6 +535,7 @@ export function wrapperTypeName(typeName: string): string | undefined { case ".google.protobuf.ListValue": case ".google.protobuf.Timestamp": case ".google.protobuf.Struct": + case ".google.protobuf.Value": return typeName.split(".")[3]; default: return undefined;