From adb725364a3d5ba3e44ccea2f89c9e2c1142f570 Mon Sep 17 00:00:00 2001 From: Alexander Fenster Date: Fri, 12 Aug 2022 13:41:59 -0700 Subject: [PATCH] fix: make browser and rest use case work (#1311) --- src/createApiCall.ts | 4 +++- src/fallback.ts | 28 +++++++++++++++++++++++++--- src/fallbackRest.ts | 15 ++------------- src/locationService.ts | 15 +++++---------- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/createApiCall.ts b/src/createApiCall.ts index 23080c1f0..51a40bd3b 100644 --- a/src/createApiCall.ts +++ b/src/createApiCall.ts @@ -55,7 +55,9 @@ import {StreamingApiCaller} from './streamingCalls/streamingApiCaller'; export function createApiCall( func: Promise | GRPCCall, settings: CallSettings, - descriptor?: Descriptor + descriptor?: Descriptor, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _fallback?: boolean | 'proto' | 'rest' // unused here, used in fallback.ts implementation ): GaxCall { // we want to be able to accept both promise resolving to a function and a // function. Currently client librares are only calling this method with a diff --git a/src/fallback.ts b/src/fallback.ts index e4ebcb6d1..da16f076d 100644 --- a/src/fallback.ts +++ b/src/fallback.ts @@ -46,7 +46,12 @@ import {google} from '../protos/http'; export {FallbackServiceError}; export {PathTemplate} from './pathTemplate'; export {routingHeader}; -export {CallSettings, constructSettings, RetryOptions} from './gax'; +export { + CallSettings, + constructSettings, + RetryOptions, + createDefaultBackoffSettings, +} from './gax'; export const version = require('../../package.json').version + '-fallback'; export { @@ -58,6 +63,10 @@ export { export {StreamType} from './streamingCalls/streaming'; +export {OperationsClient} from './operationsClient'; +export {IamClient} from './iamService'; +export {LocationsClient} from './locationService'; + export const defaultToObjectOptions = { keepCase: false, longs: String, @@ -365,16 +374,29 @@ export function lro(options: GrpcClientOptions) { export function createApiCall( func: Promise | GRPCCall, settings: gax.CallSettings, - descriptor?: Descriptor + descriptor?: Descriptor, + fallback?: boolean | 'proto' | 'rest' ): GaxCall { if ( + (!fallback || fallback === 'rest') && descriptor && 'streaming' in descriptor && (descriptor as StreamDescriptor).type !== StreamType.SERVER_STREAMING ) { return () => { throw new Error( - 'The gRPC-fallback client library (e.g. browser version of the library) currently does not support client-streaming or bidi-stream calls.' + 'The REST transport currently does not support client-streaming or bidi-stream calls.' + ); + }; + } + if ( + (fallback === 'proto' || fallback === true) && // for legacy reasons, fallback === true means 'proto' + descriptor && + 'streaming' in descriptor + ) { + return () => { + throw new Error( + 'The gRPC-fallback (proto over HTTP) transport currently does not support streaming calls.' ); }; } diff --git a/src/fallbackRest.ts b/src/fallbackRest.ts index baaa9cd74..9df2e02ca 100644 --- a/src/fallbackRest.ts +++ b/src/fallbackRest.ts @@ -19,23 +19,12 @@ import * as serializer from 'proto3-json-serializer'; import {defaultToObjectOptions} from './fallback'; import {FetchParameters} from './fallbackServiceStub'; -import {hasTextDecoder, hasTextEncoder, isNodeJS} from './featureDetection'; +import {hasTextDecoder, hasTextEncoder} from './featureDetection'; import {GoogleError} from './googleError'; import {transcode} from './transcoding'; if (!hasTextEncoder() || !hasTextDecoder()) { - if (isNodeJS()) { - // Node.js 10 does not have global TextDecoder - // TODO(@alexander-fenster): remove this logic after Node.js 10 is EOL. - // eslint-disable-next-line @typescript-eslint/no-var-requires - const util = require('util'); - Object.assign(global, { - TextDecoder: util.TextDecoder, - TextEncoder: util.TextEncoder, - }); - } else { - require('fast-text-encoding'); - } + require('fast-text-encoding'); } export function encodeRequest( diff --git a/src/locationService.ts b/src/locationService.ts index 367b0e38c..519c04e44 100644 --- a/src/locationService.ts +++ b/src/locationService.ts @@ -47,8 +47,6 @@ export class LocationsClient { private _terminated = false; private _opts: ClientOptions; private _providedCustomServicePath: boolean; - private _gaxGrpc: GrpcClient | FallbackGrpcClient; - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _protos: {}; private _defaults: {[method: string]: gax.CallSettings}; auth: GoogleAuth; @@ -124,14 +122,11 @@ export class LocationsClient { opts['scopes'] = staticMembers.scopes; } - // Create a `gaxGrpc` object, with any grpc-specific options sent to the client. - this._gaxGrpc = new GrpcClient(opts); - // Save options to use in initialize() method. this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = this._gaxGrpc.auth as GoogleAuth; + this.auth = gaxGrpc.auth as GoogleAuth; // Set the default scopes in auth client if needed. if (servicePath === staticMembers.servicePath) { @@ -146,15 +141,15 @@ export class LocationsClient { clientHeader.push(`gl-web/${version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); } else if (opts.fallback === 'rest') { - clientHeader.push(`rest/${this._gaxGrpc.grpcVersion}`); + clientHeader.push(`rest/${gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); } // Load the applicable protos. - this._protos = this._gaxGrpc.loadProtoJSON(jsonProtos); + this._protos = gaxGrpc.loadProtoJSON(jsonProtos); // Some of the methods on this service return "paged" results, // (e.g. 50 results at a time, with tokens to get subsequent @@ -168,7 +163,7 @@ export class LocationsClient { }; // Put together the default options sent with requests. - this._defaults = this._gaxGrpc.constructSettings( + this._defaults = gaxGrpc.constructSettings( 'google.cloud.location.Locations', gapicConfig as gax.ClientConfig, opts.clientConfig || {},