From a9e975b41b760970da264a48cc3fb4ecc4b57a1d Mon Sep 17 00:00:00 2001 From: Luke Alvoeiro Date: Sat, 3 Feb 2024 06:00:51 -0800 Subject: [PATCH] fix: ensure default service streaming methods compile when middleware methods are enabled (#996) * mostly done, need to write tests * run bin2ts * tests passing * improvements --- .../before-after-request-streaming-test.ts | 74 ++ .../example.bin | Bin 0 -> 8011 bytes .../example.proto | 70 ++ .../before-after-request-streaming/example.ts | 1042 +++++++++++++++++ .../google/protobuf/wrappers.ts | 661 +++++++++++ .../parameters.txt | 1 + src/generate-services.ts | 44 +- src/utils.ts | 7 + 8 files changed, 1884 insertions(+), 15 deletions(-) create mode 100644 integration/before-after-request-streaming/before-after-request-streaming-test.ts create mode 100644 integration/before-after-request-streaming/example.bin create mode 100644 integration/before-after-request-streaming/example.proto create mode 100644 integration/before-after-request-streaming/example.ts create mode 100644 integration/before-after-request-streaming/google/protobuf/wrappers.ts create mode 100644 integration/before-after-request-streaming/parameters.txt diff --git a/integration/before-after-request-streaming/before-after-request-streaming-test.ts b/integration/before-after-request-streaming/before-after-request-streaming-test.ts new file mode 100644 index 000000000..8637829c1 --- /dev/null +++ b/integration/before-after-request-streaming/before-after-request-streaming-test.ts @@ -0,0 +1,74 @@ +import { Observable, map, of } from "rxjs"; +import { DashStateClientImpl, DashUserSettingsState, DashStateServiceName } from "./example"; + +interface Rpc { + request(service: string, method: string, data: Uint8Array): Promise; + clientStreamingRequest(service: string, method: string, data: Observable): Promise; + serverStreamingRequest(service: string, method: string, data: Uint8Array): Observable; + bidirectionalStreamingRequest(service: string, method: string, data: Observable): Observable; + beforeRequest?(service: string, method: string, request: T): void; + afterResponse?(service: string, method: string, response: T): void; + handleError?(service: string, method: string, error: Error): Error; +} + +describe("before-after-request-streaming", () => { + const reqData = { + email: "john.cena@gmail.com", + urls: undefined, + flashes: [{ msg: "dun dun dun dun", type: 0 }], + }; + const resData = { + email: "cena.john@gmail.com", + urls: undefined, + flashes: [{ msg: "dun dun dun dun", type: 0 }], + }; + let rpc: Rpc = { + request: jest.fn(() => Promise.resolve(new Uint8Array([21]))), + clientStreamingRequest: jest.fn(() => Promise.resolve(new Uint8Array([21]))), + serverStreamingRequest: jest.fn(() => of(new Uint8Array([21]))), + bidirectionalStreamingRequest: (service: string, method: string, data: Observable) => { + return data.pipe(map((data) => new Uint8Array([21]))); + }, + }; + let client = new DashStateClientImpl(rpc); + const beforeRequest = jest.fn(); + const afterResponse = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + jest.spyOn(DashUserSettingsState, "decode").mockReturnValue(resData); + }); + + it("compiles", () => { + const service = new DashStateClientImpl(rpc); + expect(service).not.toBeUndefined(); + }); + + it("performs function before request if specified", () => { + const req = DashUserSettingsState.create(reqData); + client = new DashStateClientImpl({ ...rpc, beforeRequest: beforeRequest }); + const reqObservable = of(req); + client.ChangeUserSettingsStream(reqObservable).subscribe(); + expect(beforeRequest).toHaveBeenCalledWith( + DashStateServiceName, + "ChangeUserSettingsStream", + DashUserSettingsState.encode(req).finish(), + ); + }); + + it("performs function after request if specified", async () => { + const req = DashUserSettingsState.create(reqData); + client = new DashStateClientImpl({ ...rpc, afterResponse: afterResponse }); + const reqObservable = of(req); + client.ChangeUserSettingsStream(reqObservable).subscribe(); + expect(afterResponse).toHaveBeenCalledWith(DashStateServiceName, "ChangeUserSettingsStream", resData); + }); + + it("doesn't perform function before or after request if they are not specified", async () => { + const req = DashUserSettingsState.create(reqData); + client = new DashStateClientImpl({ ...rpc }); + await client.ChangeUserSettingsStream(of(req)); + expect(beforeRequest).not.toHaveBeenCalled(); + expect(afterResponse).not.toHaveBeenCalled(); + }); +}); diff --git a/integration/before-after-request-streaming/example.bin b/integration/before-after-request-streaming/example.bin new file mode 100644 index 0000000000000000000000000000000000000000..5de3fbf9b8a5c28e33668e0b5fba21b19a3c9788 GIT binary patch literal 8011 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 literal 0 HcmV?d00001 diff --git a/integration/before-after-request-streaming/example.proto b/integration/before-after-request-streaming/example.proto new file mode 100644 index 000000000..02188397c --- /dev/null +++ b/integration/before-after-request-streaming/example.proto @@ -0,0 +1,70 @@ +syntax = "proto3"; +import "google/protobuf/wrappers.proto"; +package rpx; + +service DashState { + rpc UserSettings(Empty) returns (DashUserSettingsState); + rpc ActiveUserSettingsStream(Empty) returns (stream DashUserSettingsState); + // not supported in grpc-web, but should still compile + rpc ChangeUserSettingsStream (stream DashUserSettingsState) returns (stream DashUserSettingsState) {} +} + +message DashFlash { + string msg = 1; + Type type = 2; + + enum Type { + Undefined = 0; + Success = 1; + Warn = 2; + Error = 3; + } +} + +message DashUserSettingsState { + string email = 1; + URLs urls = 6; + repeated DashFlash flashes = 7; + + message URLs { + string connect_google = 1; + string connect_github = 2; + } +} + + +//---------------------- +// API Creds +//---------------------- +service DashAPICreds { + rpc Create(DashAPICredsCreateReq) returns (DashCred); + rpc Update(DashAPICredsUpdateReq) returns (DashCred); + rpc Delete(DashAPICredsDeleteReq) returns (DashCred); + rpc Uppercase(google.protobuf.StringValue) returns (google.protobuf.StringValue); +} + +message DashCred { + string description = 2; + string metadata = 3; + string token = 4; + string id = 7; +} + +message DashAPICredsCreateReq { + string description = 1; + string metadata = 2; +} + +message DashAPICredsUpdateReq { + string cred_sid = 1; + string description = 2; + string metadata = 3; + string id = 5; +} + +message DashAPICredsDeleteReq { + string cred_sid = 1; + string id = 3; +} + +message Empty {} diff --git a/integration/before-after-request-streaming/example.ts b/integration/before-after-request-streaming/example.ts new file mode 100644 index 000000000..97b9973b2 --- /dev/null +++ b/integration/before-after-request-streaming/example.ts @@ -0,0 +1,1042 @@ +/* eslint-disable */ +import * as _m0 from "protobufjs/minimal"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { StringValue } from "./google/protobuf/wrappers"; + +export const protobufPackage = "rpx"; + +export interface DashFlash { + msg: string; + type: DashFlash_Type; +} + +export enum DashFlash_Type { + Undefined = 0, + Success = 1, + Warn = 2, + Error = 3, + UNRECOGNIZED = -1, +} + +export function dashFlash_TypeFromJSON(object: any): DashFlash_Type { + switch (object) { + case 0: + case "Undefined": + return DashFlash_Type.Undefined; + case 1: + case "Success": + return DashFlash_Type.Success; + case 2: + case "Warn": + return DashFlash_Type.Warn; + case 3: + case "Error": + return DashFlash_Type.Error; + case -1: + case "UNRECOGNIZED": + default: + return DashFlash_Type.UNRECOGNIZED; + } +} + +export function dashFlash_TypeToJSON(object: DashFlash_Type): string { + switch (object) { + case DashFlash_Type.Undefined: + return "Undefined"; + case DashFlash_Type.Success: + return "Success"; + case DashFlash_Type.Warn: + return "Warn"; + case DashFlash_Type.Error: + return "Error"; + case DashFlash_Type.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + +export interface DashUserSettingsState { + email: string; + urls: DashUserSettingsState_URLs | undefined; + flashes: DashFlash[]; +} + +export interface DashUserSettingsState_URLs { + connectGoogle: string; + connectGithub: string; +} + +export interface DashCred { + description: string; + metadata: string; + token: string; + id: string; +} + +export interface DashAPICredsCreateReq { + description: string; + metadata: string; +} + +export interface DashAPICredsUpdateReq { + credSid: string; + description: string; + metadata: string; + id: string; +} + +export interface DashAPICredsDeleteReq { + credSid: string; + id: string; +} + +export interface Empty { +} + +function createBaseDashFlash(): DashFlash { + return { msg: "", type: 0 }; +} + +export const DashFlash = { + encode(message: DashFlash, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.msg !== "") { + writer.uint32(10).string(message.msg); + } + if (message.type !== 0) { + writer.uint32(16).int32(message.type); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DashFlash { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDashFlash(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.msg = reader.string(); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.type = reader.int32() as any; + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): DashFlash { + return { + msg: isSet(object.msg) ? globalThis.String(object.msg) : "", + type: isSet(object.type) ? dashFlash_TypeFromJSON(object.type) : 0, + }; + }, + + toJSON(message: DashFlash): unknown { + const obj: any = {}; + if (message.msg !== "") { + obj.msg = message.msg; + } + if (message.type !== 0) { + obj.type = dashFlash_TypeToJSON(message.type); + } + return obj; + }, + + create, I>>(base?: I): DashFlash { + return DashFlash.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): DashFlash { + const message = createBaseDashFlash(); + message.msg = object.msg ?? ""; + message.type = object.type ?? 0; + return message; + }, +}; + +function createBaseDashUserSettingsState(): DashUserSettingsState { + return { email: "", urls: undefined, flashes: [] }; +} + +export const DashUserSettingsState = { + encode(message: DashUserSettingsState, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.email !== "") { + writer.uint32(10).string(message.email); + } + if (message.urls !== undefined) { + DashUserSettingsState_URLs.encode(message.urls, writer.uint32(50).fork()).ldelim(); + } + for (const v of message.flashes) { + DashFlash.encode(v!, writer.uint32(58).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DashUserSettingsState { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDashUserSettingsState(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.email = reader.string(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.urls = DashUserSettingsState_URLs.decode(reader, reader.uint32()); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.flashes.push(DashFlash.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): DashUserSettingsState { + return { + email: isSet(object.email) ? globalThis.String(object.email) : "", + urls: isSet(object.urls) ? DashUserSettingsState_URLs.fromJSON(object.urls) : undefined, + flashes: globalThis.Array.isArray(object?.flashes) ? object.flashes.map((e: any) => DashFlash.fromJSON(e)) : [], + }; + }, + + toJSON(message: DashUserSettingsState): unknown { + const obj: any = {}; + if (message.email !== "") { + obj.email = message.email; + } + if (message.urls !== undefined) { + obj.urls = DashUserSettingsState_URLs.toJSON(message.urls); + } + if (message.flashes?.length) { + obj.flashes = message.flashes.map((e) => DashFlash.toJSON(e)); + } + return obj; + }, + + create, I>>(base?: I): DashUserSettingsState { + return DashUserSettingsState.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): DashUserSettingsState { + const message = createBaseDashUserSettingsState(); + message.email = object.email ?? ""; + message.urls = (object.urls !== undefined && object.urls !== null) + ? DashUserSettingsState_URLs.fromPartial(object.urls) + : undefined; + message.flashes = object.flashes?.map((e) => DashFlash.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseDashUserSettingsState_URLs(): DashUserSettingsState_URLs { + return { connectGoogle: "", connectGithub: "" }; +} + +export const DashUserSettingsState_URLs = { + encode(message: DashUserSettingsState_URLs, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.connectGoogle !== "") { + writer.uint32(10).string(message.connectGoogle); + } + if (message.connectGithub !== "") { + writer.uint32(18).string(message.connectGithub); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DashUserSettingsState_URLs { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDashUserSettingsState_URLs(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.connectGoogle = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.connectGithub = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): DashUserSettingsState_URLs { + return { + connectGoogle: isSet(object.connectGoogle) ? globalThis.String(object.connectGoogle) : "", + connectGithub: isSet(object.connectGithub) ? globalThis.String(object.connectGithub) : "", + }; + }, + + toJSON(message: DashUserSettingsState_URLs): unknown { + const obj: any = {}; + if (message.connectGoogle !== "") { + obj.connectGoogle = message.connectGoogle; + } + if (message.connectGithub !== "") { + obj.connectGithub = message.connectGithub; + } + return obj; + }, + + create, I>>(base?: I): DashUserSettingsState_URLs { + return DashUserSettingsState_URLs.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): DashUserSettingsState_URLs { + const message = createBaseDashUserSettingsState_URLs(); + message.connectGoogle = object.connectGoogle ?? ""; + message.connectGithub = object.connectGithub ?? ""; + return message; + }, +}; + +function createBaseDashCred(): DashCred { + return { description: "", metadata: "", token: "", id: "" }; +} + +export const DashCred = { + encode(message: DashCred, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.description !== "") { + writer.uint32(18).string(message.description); + } + if (message.metadata !== "") { + writer.uint32(26).string(message.metadata); + } + if (message.token !== "") { + writer.uint32(34).string(message.token); + } + if (message.id !== "") { + writer.uint32(58).string(message.id); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DashCred { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDashCred(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + if (tag !== 18) { + break; + } + + message.description = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.metadata = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.token = reader.string(); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.id = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): DashCred { + return { + description: isSet(object.description) ? globalThis.String(object.description) : "", + metadata: isSet(object.metadata) ? globalThis.String(object.metadata) : "", + token: isSet(object.token) ? globalThis.String(object.token) : "", + id: isSet(object.id) ? globalThis.String(object.id) : "", + }; + }, + + toJSON(message: DashCred): unknown { + const obj: any = {}; + if (message.description !== "") { + obj.description = message.description; + } + if (message.metadata !== "") { + obj.metadata = message.metadata; + } + if (message.token !== "") { + obj.token = message.token; + } + if (message.id !== "") { + obj.id = message.id; + } + return obj; + }, + + create, I>>(base?: I): DashCred { + return DashCred.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): DashCred { + const message = createBaseDashCred(); + message.description = object.description ?? ""; + message.metadata = object.metadata ?? ""; + message.token = object.token ?? ""; + message.id = object.id ?? ""; + return message; + }, +}; + +function createBaseDashAPICredsCreateReq(): DashAPICredsCreateReq { + return { description: "", metadata: "" }; +} + +export const DashAPICredsCreateReq = { + encode(message: DashAPICredsCreateReq, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.description !== "") { + writer.uint32(10).string(message.description); + } + if (message.metadata !== "") { + writer.uint32(18).string(message.metadata); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DashAPICredsCreateReq { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDashAPICredsCreateReq(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.description = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.metadata = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): DashAPICredsCreateReq { + return { + description: isSet(object.description) ? globalThis.String(object.description) : "", + metadata: isSet(object.metadata) ? globalThis.String(object.metadata) : "", + }; + }, + + toJSON(message: DashAPICredsCreateReq): unknown { + const obj: any = {}; + if (message.description !== "") { + obj.description = message.description; + } + if (message.metadata !== "") { + obj.metadata = message.metadata; + } + return obj; + }, + + create, I>>(base?: I): DashAPICredsCreateReq { + return DashAPICredsCreateReq.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): DashAPICredsCreateReq { + const message = createBaseDashAPICredsCreateReq(); + message.description = object.description ?? ""; + message.metadata = object.metadata ?? ""; + return message; + }, +}; + +function createBaseDashAPICredsUpdateReq(): DashAPICredsUpdateReq { + return { credSid: "", description: "", metadata: "", id: "" }; +} + +export const DashAPICredsUpdateReq = { + encode(message: DashAPICredsUpdateReq, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.credSid !== "") { + writer.uint32(10).string(message.credSid); + } + if (message.description !== "") { + writer.uint32(18).string(message.description); + } + if (message.metadata !== "") { + writer.uint32(26).string(message.metadata); + } + if (message.id !== "") { + writer.uint32(42).string(message.id); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DashAPICredsUpdateReq { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDashAPICredsUpdateReq(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.credSid = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.description = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.metadata = reader.string(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.id = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): DashAPICredsUpdateReq { + return { + credSid: isSet(object.credSid) ? globalThis.String(object.credSid) : "", + description: isSet(object.description) ? globalThis.String(object.description) : "", + metadata: isSet(object.metadata) ? globalThis.String(object.metadata) : "", + id: isSet(object.id) ? globalThis.String(object.id) : "", + }; + }, + + toJSON(message: DashAPICredsUpdateReq): unknown { + const obj: any = {}; + if (message.credSid !== "") { + obj.credSid = message.credSid; + } + if (message.description !== "") { + obj.description = message.description; + } + if (message.metadata !== "") { + obj.metadata = message.metadata; + } + if (message.id !== "") { + obj.id = message.id; + } + return obj; + }, + + create, I>>(base?: I): DashAPICredsUpdateReq { + return DashAPICredsUpdateReq.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): DashAPICredsUpdateReq { + const message = createBaseDashAPICredsUpdateReq(); + message.credSid = object.credSid ?? ""; + message.description = object.description ?? ""; + message.metadata = object.metadata ?? ""; + message.id = object.id ?? ""; + return message; + }, +}; + +function createBaseDashAPICredsDeleteReq(): DashAPICredsDeleteReq { + return { credSid: "", id: "" }; +} + +export const DashAPICredsDeleteReq = { + encode(message: DashAPICredsDeleteReq, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.credSid !== "") { + writer.uint32(10).string(message.credSid); + } + if (message.id !== "") { + writer.uint32(26).string(message.id); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DashAPICredsDeleteReq { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDashAPICredsDeleteReq(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.credSid = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.id = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): DashAPICredsDeleteReq { + return { + credSid: isSet(object.credSid) ? globalThis.String(object.credSid) : "", + id: isSet(object.id) ? globalThis.String(object.id) : "", + }; + }, + + toJSON(message: DashAPICredsDeleteReq): unknown { + const obj: any = {}; + if (message.credSid !== "") { + obj.credSid = message.credSid; + } + if (message.id !== "") { + obj.id = message.id; + } + return obj; + }, + + create, I>>(base?: I): DashAPICredsDeleteReq { + return DashAPICredsDeleteReq.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): DashAPICredsDeleteReq { + const message = createBaseDashAPICredsDeleteReq(); + message.credSid = object.credSid ?? ""; + message.id = object.id ?? ""; + return message; + }, +}; + +function createBaseEmpty(): Empty { + return {}; +} + +export const Empty = { + encode(_: Empty, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Empty { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseEmpty(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(_: any): Empty { + return {}; + }, + + toJSON(_: Empty): unknown { + const obj: any = {}; + return obj; + }, + + create, I>>(base?: I): Empty { + return Empty.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(_: I): Empty { + const message = createBaseEmpty(); + return message; + }, +}; + +export interface DashState { + UserSettings(request: Empty): Promise; + ActiveUserSettingsStream(request: Empty): Observable; + /** not supported in grpc-web, but should still compile */ + ChangeUserSettingsStream(request: Observable): Observable; +} + +export const DashStateServiceName = "rpx.DashState"; +export class DashStateClientImpl implements DashState { + private readonly rpc: Rpc; + private readonly service: string; + constructor(rpc: Rpc, opts?: { service?: string }) { + this.service = opts?.service || DashStateServiceName; + this.rpc = rpc; + this.UserSettings = this.UserSettings.bind(this); + this.ActiveUserSettingsStream = this.ActiveUserSettingsStream.bind(this); + this.ChangeUserSettingsStream = this.ChangeUserSettingsStream.bind(this); + } + UserSettings(request: Empty): Promise { + const data = Empty.encode(request).finish(); + if (this.rpc.beforeRequest) { + this.rpc.beforeRequest(this.service, "UserSettings", request); + } + const promise = this.rpc.request(this.service, "UserSettings", data); + return promise.then((data) => { + try { + const response = DashUserSettingsState.decode(_m0.Reader.create(data)); + if (this.rpc.afterResponse) { + this.rpc.afterResponse(this.service, "UserSettings", response); + } + return response; + } catch (error) { + return Promise.reject(error); + } + }).catch((error) => { + if (this.rpc.handleError) { + return Promise.reject(this.rpc.handleError(this.service, "UserSettings", error)); + } + return Promise.reject(error); + }); + } + + ActiveUserSettingsStream(request: Empty): Observable { + const data = Empty.encode(request).finish(); + if (this.rpc.beforeRequest) { + this.rpc.beforeRequest(this.service, "ActiveUserSettingsStream", request); + } + const result = this.rpc.serverStreamingRequest(this.service, "ActiveUserSettingsStream", data); + return result.pipe(map((data) => { + try { + const response = DashUserSettingsState.decode(_m0.Reader.create(data)); + if (this.rpc.afterResponse) { + this.rpc.afterResponse(this.service, "ActiveUserSettingsStream", response); + } + return response; + } catch (error) { + throw error; + } + })); + } + + ChangeUserSettingsStream(request: Observable): Observable { + const data = request.pipe(map((request) => { + const encodedRequest = DashUserSettingsState.encode(request).finish(); + if (this.rpc.beforeRequest) { + this.rpc.beforeRequest(this.service, "ChangeUserSettingsStream", encodedRequest); + } + return encodedRequest; + })); + const result = this.rpc.bidirectionalStreamingRequest(this.service, "ChangeUserSettingsStream", data); + return result.pipe(map((data) => { + try { + const response = DashUserSettingsState.decode(_m0.Reader.create(data)); + if (this.rpc.afterResponse) { + this.rpc.afterResponse(this.service, "ChangeUserSettingsStream", response); + } + return response; + } catch (error) { + throw error; + } + })); + } +} + +export type DashStateDefinition = typeof DashStateDefinition; +export const DashStateDefinition = { + name: "DashState", + fullName: "rpx.DashState", + methods: { + userSettings: { + name: "UserSettings", + requestType: Empty, + requestStream: false, + responseType: DashUserSettingsState, + responseStream: false, + options: {}, + }, + activeUserSettingsStream: { + name: "ActiveUserSettingsStream", + requestType: Empty, + requestStream: false, + responseType: DashUserSettingsState, + responseStream: true, + options: {}, + }, + /** not supported in grpc-web, but should still compile */ + changeUserSettingsStream: { + name: "ChangeUserSettingsStream", + requestType: DashUserSettingsState, + requestStream: true, + responseType: DashUserSettingsState, + responseStream: true, + options: {}, + }, + }, +} as const; + +/** + * ---------------------- + * API Creds + * ---------------------- + */ +export interface DashAPICreds { + Create(request: DashAPICredsCreateReq): Promise; + Update(request: DashAPICredsUpdateReq): Promise; + Delete(request: DashAPICredsDeleteReq): Promise; + Uppercase(request: StringValue): Promise; +} + +export const DashAPICredsServiceName = "rpx.DashAPICreds"; +export class DashAPICredsClientImpl implements DashAPICreds { + private readonly rpc: Rpc; + private readonly service: string; + constructor(rpc: Rpc, opts?: { service?: string }) { + this.service = opts?.service || DashAPICredsServiceName; + this.rpc = rpc; + this.Create = this.Create.bind(this); + this.Update = this.Update.bind(this); + this.Delete = this.Delete.bind(this); + this.Uppercase = this.Uppercase.bind(this); + } + Create(request: DashAPICredsCreateReq): Promise { + const data = DashAPICredsCreateReq.encode(request).finish(); + if (this.rpc.beforeRequest) { + this.rpc.beforeRequest(this.service, "Create", request); + } + const promise = this.rpc.request(this.service, "Create", data); + return promise.then((data) => { + try { + const response = DashCred.decode(_m0.Reader.create(data)); + if (this.rpc.afterResponse) { + this.rpc.afterResponse(this.service, "Create", response); + } + return response; + } catch (error) { + return Promise.reject(error); + } + }).catch((error) => { + if (this.rpc.handleError) { + return Promise.reject(this.rpc.handleError(this.service, "Create", error)); + } + return Promise.reject(error); + }); + } + + Update(request: DashAPICredsUpdateReq): Promise { + const data = DashAPICredsUpdateReq.encode(request).finish(); + if (this.rpc.beforeRequest) { + this.rpc.beforeRequest(this.service, "Update", request); + } + const promise = this.rpc.request(this.service, "Update", data); + return promise.then((data) => { + try { + const response = DashCred.decode(_m0.Reader.create(data)); + if (this.rpc.afterResponse) { + this.rpc.afterResponse(this.service, "Update", response); + } + return response; + } catch (error) { + return Promise.reject(error); + } + }).catch((error) => { + if (this.rpc.handleError) { + return Promise.reject(this.rpc.handleError(this.service, "Update", error)); + } + return Promise.reject(error); + }); + } + + Delete(request: DashAPICredsDeleteReq): Promise { + const data = DashAPICredsDeleteReq.encode(request).finish(); + if (this.rpc.beforeRequest) { + this.rpc.beforeRequest(this.service, "Delete", request); + } + const promise = this.rpc.request(this.service, "Delete", data); + return promise.then((data) => { + try { + const response = DashCred.decode(_m0.Reader.create(data)); + if (this.rpc.afterResponse) { + this.rpc.afterResponse(this.service, "Delete", response); + } + return response; + } catch (error) { + return Promise.reject(error); + } + }).catch((error) => { + if (this.rpc.handleError) { + return Promise.reject(this.rpc.handleError(this.service, "Delete", error)); + } + return Promise.reject(error); + }); + } + + Uppercase(request: StringValue): Promise { + const data = StringValue.encode(request).finish(); + if (this.rpc.beforeRequest) { + this.rpc.beforeRequest(this.service, "Uppercase", request); + } + const promise = this.rpc.request(this.service, "Uppercase", data); + return promise.then((data) => { + try { + const response = StringValue.decode(_m0.Reader.create(data)); + if (this.rpc.afterResponse) { + this.rpc.afterResponse(this.service, "Uppercase", response); + } + return response; + } catch (error) { + return Promise.reject(error); + } + }).catch((error) => { + if (this.rpc.handleError) { + return Promise.reject(this.rpc.handleError(this.service, "Uppercase", error)); + } + return Promise.reject(error); + }); + } +} + +/** + * ---------------------- + * API Creds + * ---------------------- + */ +export type DashAPICredsDefinition = typeof DashAPICredsDefinition; +export const DashAPICredsDefinition = { + name: "DashAPICreds", + fullName: "rpx.DashAPICreds", + methods: { + create: { + name: "Create", + requestType: DashAPICredsCreateReq, + requestStream: false, + responseType: DashCred, + responseStream: false, + options: {}, + }, + update: { + name: "Update", + requestType: DashAPICredsUpdateReq, + requestStream: false, + responseType: DashCred, + responseStream: false, + options: {}, + }, + delete: { + name: "Delete", + requestType: DashAPICredsDeleteReq, + requestStream: false, + responseType: DashCred, + responseStream: false, + options: {}, + }, + uppercase: { + name: "Uppercase", + requestType: StringValue, + requestStream: false, + responseType: StringValue, + responseStream: false, + options: {}, + }, + }, +} as const; + +interface Rpc { + request(service: string, method: string, data: Uint8Array): Promise; + clientStreamingRequest(service: string, method: string, data: Observable): Promise; + serverStreamingRequest(service: string, method: string, data: Uint8Array): Observable; + bidirectionalStreamingRequest(service: string, method: string, data: Observable): Observable; + beforeRequest?(service: string, method: string, request: T): void; + afterResponse?(service: string, method: string, response: T): void; + handleError?(service: string, method: string, error: Error): Error; +} + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} diff --git a/integration/before-after-request-streaming/google/protobuf/wrappers.ts b/integration/before-after-request-streaming/google/protobuf/wrappers.ts new file mode 100644 index 000000000..6aa1a51cc --- /dev/null +++ b/integration/before-after-request-streaming/google/protobuf/wrappers.ts @@ -0,0 +1,661 @@ +/* eslint-disable */ +import * as _m0 from "protobufjs/minimal"; +import Long = require("long"); + +export const protobufPackage = "google.protobuf"; + +/** + * Wrapper message for `double`. + * + * The JSON representation for `DoubleValue` is JSON number. + */ +export interface DoubleValue { + /** The double value. */ + value: number; +} + +/** + * Wrapper message for `float`. + * + * The JSON representation for `FloatValue` is JSON number. + */ +export interface FloatValue { + /** The float value. */ + value: number; +} + +/** + * Wrapper message for `int64`. + * + * The JSON representation for `Int64Value` is JSON string. + */ +export interface Int64Value { + /** The int64 value. */ + value: number; +} + +/** + * Wrapper message for `uint64`. + * + * The JSON representation for `UInt64Value` is JSON string. + */ +export interface UInt64Value { + /** The uint64 value. */ + value: number; +} + +/** + * Wrapper message for `int32`. + * + * The JSON representation for `Int32Value` is JSON number. + */ +export interface Int32Value { + /** The int32 value. */ + value: number; +} + +/** + * Wrapper message for `uint32`. + * + * The JSON representation for `UInt32Value` is JSON number. + */ +export interface UInt32Value { + /** The uint32 value. */ + value: number; +} + +/** + * Wrapper message for `bool`. + * + * The JSON representation for `BoolValue` is JSON `true` and `false`. + */ +export interface BoolValue { + /** The bool value. */ + value: boolean; +} + +/** + * Wrapper message for `string`. + * + * The JSON representation for `StringValue` is JSON string. + */ +export interface StringValue { + /** The string value. */ + value: string; +} + +/** + * Wrapper message for `bytes`. + * + * The JSON representation for `BytesValue` is JSON string. + */ +export interface BytesValue { + /** The bytes value. */ + value: Uint8Array; +} + +function createBaseDoubleValue(): DoubleValue { + return { value: 0 }; +} + +export const DoubleValue = { + encode(message: DoubleValue, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value !== 0) { + writer.uint32(9).double(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DoubleValue { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDoubleValue(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 9) { + break; + } + + message.value = reader.double(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): DoubleValue { + return { value: isSet(object.value) ? globalThis.Number(object.value) : 0 }; + }, + + toJSON(message: DoubleValue): unknown { + const obj: any = {}; + if (message.value !== 0) { + obj.value = message.value; + } + return obj; + }, + + create, I>>(base?: I): DoubleValue { + return DoubleValue.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): DoubleValue { + const message = createBaseDoubleValue(); + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseFloatValue(): FloatValue { + return { value: 0 }; +} + +export const FloatValue = { + encode(message: FloatValue, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value !== 0) { + writer.uint32(13).float(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): FloatValue { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFloatValue(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 13) { + break; + } + + message.value = reader.float(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): FloatValue { + return { value: isSet(object.value) ? globalThis.Number(object.value) : 0 }; + }, + + toJSON(message: FloatValue): unknown { + const obj: any = {}; + if (message.value !== 0) { + obj.value = message.value; + } + return obj; + }, + + create, I>>(base?: I): FloatValue { + return FloatValue.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): FloatValue { + const message = createBaseFloatValue(); + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseInt64Value(): Int64Value { + return { value: 0 }; +} + +export const Int64Value = { + encode(message: Int64Value, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value !== 0) { + writer.uint32(8).int64(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Int64Value { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseInt64Value(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.value = longToNumber(reader.int64() as Long); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Int64Value { + return { value: isSet(object.value) ? globalThis.Number(object.value) : 0 }; + }, + + toJSON(message: Int64Value): unknown { + const obj: any = {}; + if (message.value !== 0) { + obj.value = Math.round(message.value); + } + return obj; + }, + + create, I>>(base?: I): Int64Value { + return Int64Value.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Int64Value { + const message = createBaseInt64Value(); + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseUInt64Value(): UInt64Value { + return { value: 0 }; +} + +export const UInt64Value = { + encode(message: UInt64Value, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value !== 0) { + writer.uint32(8).uint64(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): UInt64Value { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseUInt64Value(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.value = longToNumber(reader.uint64() as Long); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): UInt64Value { + return { value: isSet(object.value) ? globalThis.Number(object.value) : 0 }; + }, + + toJSON(message: UInt64Value): unknown { + const obj: any = {}; + if (message.value !== 0) { + obj.value = Math.round(message.value); + } + return obj; + }, + + create, I>>(base?: I): UInt64Value { + return UInt64Value.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): UInt64Value { + const message = createBaseUInt64Value(); + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseInt32Value(): Int32Value { + return { value: 0 }; +} + +export const Int32Value = { + encode(message: Int32Value, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value !== 0) { + writer.uint32(8).int32(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Int32Value { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseInt32Value(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.value = reader.int32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Int32Value { + return { value: isSet(object.value) ? globalThis.Number(object.value) : 0 }; + }, + + toJSON(message: Int32Value): unknown { + const obj: any = {}; + if (message.value !== 0) { + obj.value = Math.round(message.value); + } + return obj; + }, + + create, I>>(base?: I): Int32Value { + return Int32Value.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Int32Value { + const message = createBaseInt32Value(); + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseUInt32Value(): UInt32Value { + return { value: 0 }; +} + +export const UInt32Value = { + encode(message: UInt32Value, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value !== 0) { + writer.uint32(8).uint32(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): UInt32Value { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseUInt32Value(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.value = reader.uint32(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): UInt32Value { + return { value: isSet(object.value) ? globalThis.Number(object.value) : 0 }; + }, + + toJSON(message: UInt32Value): unknown { + const obj: any = {}; + if (message.value !== 0) { + obj.value = Math.round(message.value); + } + return obj; + }, + + create, I>>(base?: I): UInt32Value { + return UInt32Value.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): UInt32Value { + const message = createBaseUInt32Value(); + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseBoolValue(): BoolValue { + return { value: false }; +} + +export const BoolValue = { + encode(message: BoolValue, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value === true) { + writer.uint32(8).bool(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): BoolValue { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBoolValue(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.value = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): BoolValue { + return { value: isSet(object.value) ? globalThis.Boolean(object.value) : false }; + }, + + toJSON(message: BoolValue): unknown { + const obj: any = {}; + if (message.value === true) { + obj.value = message.value; + } + return obj; + }, + + create, I>>(base?: I): BoolValue { + return BoolValue.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): BoolValue { + const message = createBaseBoolValue(); + message.value = object.value ?? false; + return message; + }, +}; + +function createBaseStringValue(): StringValue { + return { value: "" }; +} + +export const StringValue = { + encode(message: StringValue, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value !== "") { + writer.uint32(10).string(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): StringValue { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseStringValue(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.value = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): StringValue { + return { value: isSet(object.value) ? globalThis.String(object.value) : "" }; + }, + + toJSON(message: StringValue): unknown { + const obj: any = {}; + if (message.value !== "") { + obj.value = message.value; + } + return obj; + }, + + create, I>>(base?: I): StringValue { + return StringValue.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): StringValue { + const message = createBaseStringValue(); + message.value = object.value ?? ""; + return message; + }, +}; + +function createBaseBytesValue(): BytesValue { + return { value: new Uint8Array(0) }; +} + +export const BytesValue = { + encode(message: BytesValue, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.value.length !== 0) { + writer.uint32(10).bytes(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): BytesValue { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBytesValue(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.value = reader.bytes(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): BytesValue { + return { value: isSet(object.value) ? bytesFromBase64(object.value) : new Uint8Array(0) }; + }, + + toJSON(message: BytesValue): unknown { + const obj: any = {}; + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create, I>>(base?: I): BytesValue { + return BytesValue.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): BytesValue { + const message = createBaseBytesValue(); + message.value = object.value ?? new Uint8Array(0); + return message; + }, +}; + +function bytesFromBase64(b64: string): Uint8Array { + if (globalThis.Buffer) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); + } else { + const bin = globalThis.atob(b64); + const arr = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; ++i) { + arr[i] = bin.charCodeAt(i); + } + return arr; + } +} + +function base64FromBytes(arr: Uint8Array): string { + if (globalThis.Buffer) { + return globalThis.Buffer.from(arr).toString("base64"); + } else { + const bin: string[] = []; + arr.forEach((byte) => { + bin.push(globalThis.String.fromCharCode(byte)); + }); + return globalThis.btoa(bin.join("")); + } +} + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function longToNumber(long: Long): number { + if (long.gt(globalThis.Number.MAX_SAFE_INTEGER)) { + throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER"); + } + return long.toNumber(); +} + +if (_m0.util.Long !== Long) { + _m0.util.Long = Long as any; + _m0.configure(); +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} diff --git a/integration/before-after-request-streaming/parameters.txt b/integration/before-after-request-streaming/parameters.txt new file mode 100644 index 000000000..20e97a0b5 --- /dev/null +++ b/integration/before-after-request-streaming/parameters.txt @@ -0,0 +1 @@ +rpcBeforeRequest=true,rpcAfterResponse=true,rpcErrorHandler=true,outputServices=default,outputServices=generic-definitions diff --git a/src/generate-services.ts b/src/generate-services.ts index 0c59232d2..42fca4402 100644 --- a/src/generate-services.ts +++ b/src/generate-services.ts @@ -10,6 +10,7 @@ import { observableType, } from "./types"; import { + arrowFunction, assertInstanceOf, FormattedMethodDescriptor, impFile, @@ -132,11 +133,13 @@ function generateRegularRpcMethod(ctx: Context, methodDesc: MethodDescriptorProt let encode = code`${rawInputType}.encode(request).finish()`; let beforeRequest; - if (options.rpcBeforeRequest) { - beforeRequest = code` - if (this.rpc.beforeRequest) { - this.rpc.beforeRequest(this.service, "${methodDesc.name}", request); - }`; + if (options.rpcBeforeRequest && !methodDesc.clientStreaming) { + beforeRequest = generateBeforeRequest(methodDesc.name); + } else if (methodDesc.clientStreaming && options.rpcBeforeRequest) { + encode = code`{const encodedRequest = ${encode}; ${generateBeforeRequest( + methodDesc.name, + "encodedRequest", + )}; return encodedRequest}`; } let decode = code`${rawOutputType}.decode(${Reader}.create(data))`; if (options.rpcAfterResponse) { @@ -197,6 +200,13 @@ function generateRegularRpcMethod(ctx: Context, methodDesc: MethodDescriptorProt `; } +function generateBeforeRequest(methodName: string, requestVariableName: string = "request") { + return code` + if (this.rpc.beforeRequest) { + this.rpc.beforeRequest(this.service, "${methodName}", ${requestVariableName}); + }`; +} + function createDefaultServiceReturn( ctx: Context, methodDesc: MethodDescriptorProto, @@ -205,27 +215,31 @@ function createDefaultServiceReturn( ): Code { const { options } = ctx; const rawOutputType = responseType(ctx, methodDesc, { keepValueType: true }); + const returnStatement = arrowFunction("data", decode, !options.rpcAfterResponse); + if (options.returnObservable || methodDesc.serverStreaming) { if (options.useAsyncIterable) { return code`${rawOutputType}.decodeTransform(result)`; } else { - return code`result.pipe(${imp("map@rxjs/operators")}(data => ${decode}))`; + if (errorHandler) { + const tc = arrowFunction("data", tryCatchBlock(decode, code`throw error`), !options.rpcAfterResponse); + return code`result.pipe(${imp("map@rxjs/operators")}(${tc}))`; + } + return code`result.pipe(${imp("map@rxjs/operators")}(${returnStatement}))`; } } if (errorHandler) { - let tryBlock = decode; if (!options.rpcAfterResponse) { - tryBlock = code`return ${decode}`; + decode = code`return ${decode}`; } - return code`promise.then(data => { ${tryCatchBlock( - tryBlock, - code`return Promise.reject(error);`, - )}}).catch((error) => { ${errorHandler} })`; - } else if (options.rpcAfterResponse) { - return code`promise.then(data => { ${decode} } )`; + return code`promise.then(${arrowFunction( + "data", + tryCatchBlock(decode, code`return Promise.reject(error);`), + false, + )}).catch(${arrowFunction("error", errorHandler, false)})`; } - return code`promise.then(data => ${decode})`; + return code`promise.then(${returnStatement})`; } export function generateServiceClientImpl( diff --git a/src/utils.ts b/src/utils.ts index b36c89e86..9983c8f9e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -296,3 +296,10 @@ export function tryCatchBlock(tryBlock: Code | string, handleErrorBlock: Code | ${handleErrorBlock} }`; } + +export function arrowFunction(params: string, body: Code | string, isOneLine: boolean = true): Code { + if (isOneLine) { + return code`(${params}) => ${body}`; + } + return code`(${params}) => { ${body} }`; +}