From 360d352925b653d57fb90e2a60aa480194d2b05f Mon Sep 17 00:00:00 2001 From: Alexander Fenster Date: Wed, 6 Nov 2019 13:43:03 -0800 Subject: [PATCH] fix: compatibility with gapic-generator (#105) * fix: compatibility with gapic-generator * longrunning types and gts fix --- templates/typescript_gapic/_util.njk | 5 -- .../src/$version/$service_client.ts.njk | 39 ++++++++----- typescript/src/generator.ts | 7 ++- typescript/src/schema/proto.ts | 57 ++++++++++++++----- .../key_management_service_client.ts.baseline | 9 ++- .../src/v1beta1/echo_client.ts.baseline | 14 ++++- .../src/v1/text_to_speech_client.ts.baseline | 9 ++- .../translation_service_client.ts.baseline | 26 ++++++--- ...anslation_service_proto_list.json.baseline | 3 +- 9 files changed, 121 insertions(+), 48 deletions(-) diff --git a/templates/typescript_gapic/_util.njk b/templates/typescript_gapic/_util.njk index d37b1f4a0..fdd00538d 100644 --- a/templates/typescript_gapic/_util.njk +++ b/templates/typescript_gapic/_util.njk @@ -32,11 +32,6 @@ limitations under the License. {{ type.substring(0, index + 1) + 'I' + type.substring(index + 1) }} {%- endmacro -%} -{%- macro toLRInterface(type, inputType) -%} -{%- set index = inputType.lastIndexOf('.') -%} -{{ inputType.substring(0, index + 1) + 'I' + type }} -{%- endmacro -%} - {%- macro printCommentsForParams(method) -%} {%- set commentsMap = method.paramComment -%} {%- for oneComment in commentsMap -%} diff --git a/templates/typescript_gapic/src/$version/$service_client.ts.njk b/templates/typescript_gapic/src/$version/$service_client.ts.njk index 0ad663191..18b76fa46 100644 --- a/templates/typescript_gapic/src/$version/$service_client.ts.njk +++ b/templates/typescript_gapic/src/$version/$service_client.ts.njk @@ -144,12 +144,19 @@ export class {{ service.name }}Client { // Determine the client header string. const clientHeader = [ - `gl-node/${process.version}`, `grpc/${gaxGrpc.grpcVersion}`, `gax/${gaxModule.version}`, `gapic/${version}`, `gl-web/${gaxModule.version}` ]; + if (typeof process !== 'undefined' && 'versions' in process) { + clientHeader.push(`gl-node/${process.versions.node}`); + } else { + clientHeader.push(`gl-web/${gaxModule.version}`); + } + if (!opts.fallback) { + clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); } @@ -164,6 +171,10 @@ export class {{ service.name }}Client { nodejsProtoPath ); {%- if (service.pathTemplates.length > 0) %} + + // This API contains "path templates"; forward-slash-separated + // identifiers to uniquely identify resources within the API. + // Create useful helper objects for these. this._pathTemplates = { {%- for template in service.pathTemplates %} {{ template.name.toCamelCase() }}PathTemplate: new gaxModule.PathTemplate( @@ -200,8 +211,8 @@ export class {{ service.name }}Client { {%- endfor %} }; {%- endif %} - {%- if (service.longRunning.length > 0) %} + // This API contains "long-running operations", which return a // an Operation object that allows for tracking of the operation, // rather than holding a request open. @@ -216,9 +227,9 @@ export class {{ service.name }}Client { {%- for method in service.longRunning %} const {{ method.name.toCamelCase() }}Response = protoFilesRoot.lookup( - '{{ method.longRunning.responseType }}') as gax.protobuf.Type; + '{{ method.longRunningResponseType }}') as gax.protobuf.Type; const {{ method.name.toCamelCase() }}Metadata = protoFilesRoot.lookup( - '{{ method.longRunning.metadataType }}') as gax.protobuf.Type; + '{{ method.longRunningMetadataType }}') as gax.protobuf.Type; {%- endfor %} this._descriptors.longrunning = { @@ -457,27 +468,27 @@ export class {{ service.name }}Client { request: protosTypes{{ util.toInterface(method.inputInterface) }}, options?: gax.CallOptions): Promise<[ - Operation, + Operation, protosTypes{{ util.toInterface(method.outputInterface) }}|undefined, {}|undefined ]>; {{ method.name.toCamelCase() }}( request: protosTypes{{ util.toInterface(method.inputInterface) }}, options: gax.CallOptions, callback: Callback< - Operation, + Operation, protosTypes{{ util.toInterface(method.outputInterface) }}|undefined, {}|undefined>): void; {{ method.name.toCamelCase() }}( request: protosTypes{{ util.toInterface(method.inputInterface) }}, optionsOrCallback?: gax.CallOptions|Callback< - Operation, + Operation, protosTypes{{ util.toInterface(method.outputInterface) }}|undefined, {}|undefined>, callback?: Callback< - Operation, + Operation, protosTypes{{ util.toInterface(method.outputInterface) }}|undefined, {}|undefined>): Promise<[ - Operation, + Operation, protosTypes{{ util.toInterface(method.outputInterface) }}|undefined, {}|undefined ]>|void { request = request || {}; @@ -513,7 +524,7 @@ export class {{ service.name }}Client { request: protosTypes{{ util.toInterface(method.inputInterface) }}, options?: gax.CallOptions): Promise<[ - protosTypes{{ method.pagingResponseType }}[], + protosTypes{{ util.toInterface(method.pagingResponseType) }}[], protosTypes{{ util.toInterface(method.inputInterface) }}|null, protosTypes{{ util.toInterface(method.outputInterface) }} ]>; @@ -521,21 +532,21 @@ export class {{ service.name }}Client { request: protosTypes{{ util.toInterface(method.inputInterface) }}, options: gax.CallOptions, callback: Callback< - protosTypes{{ method.pagingResponseType }}[], + protosTypes{{ util.toInterface(method.pagingResponseType) }}[], protosTypes{{ util.toInterface(method.inputInterface) }}|null, protosTypes{{ util.toInterface(method.outputInterface) }}>): void; {{ method.name.toCamelCase() }}( request: protosTypes{{ util.toInterface(method.inputInterface) }}, optionsOrCallback?: gax.CallOptions|Callback< - protosTypes{{ method.pagingResponseType }}[], + protosTypes{{ util.toInterface(method.pagingResponseType) }}[], protosTypes{{ util.toInterface(method.inputInterface) }}|null, protosTypes{{ util.toInterface(method.outputInterface) }}>, callback?: Callback< - protosTypes{{ method.pagingResponseType }}[], + protosTypes{{ util.toInterface(method.pagingResponseType) }}[], protosTypes{{ util.toInterface(method.inputInterface) }}|null, protosTypes{{ util.toInterface(method.outputInterface) }}>): Promise<[ - protosTypes{{ method.pagingResponseType }}[], + protosTypes{{ util.toInterface(method.pagingResponseType) }}[], protosTypes{{ util.toInterface(method.inputInterface) }}|null, protosTypes{{ util.toInterface(method.outputInterface) }} ]>|void { diff --git a/typescript/src/generator.ts b/typescript/src/generator.ts index 34038df62..91479ea56 100644 --- a/typescript/src/generator.ts +++ b/typescript/src/generator.ts @@ -108,7 +108,12 @@ export class Generator { private buildAPIObject(): API { const protoFilesToGenerate = this.request.protoFile.filter( - pf => pf.name && this.request.fileToGenerate.includes(pf.name) + pf => + pf.name && + this.request.fileToGenerate.includes(pf.name) && + // ignoring some common package names + pf.package !== 'google.longrunning' && + pf.package !== 'google.cloud' ); const packageNamesToGenerate = protoFilesToGenerate.map( pf => pf.package || '' diff --git a/typescript/src/schema/proto.ts b/typescript/src/schema/proto.ts index 435233d8a..bd5bf5499 100644 --- a/typescript/src/schema/proto.ts +++ b/typescript/src/schema/proto.ts @@ -61,6 +61,7 @@ interface MethodDescriptorProto timeoutMillis?: number; headerRequestParams: string[]; } + export class RetryableCodeMap { codeEnumMapping: { [index: string]: string }; uniqueCodesNamesMap: { [uniqueName: string]: string }; @@ -212,20 +213,43 @@ function longrunning(method: MethodDescriptorProto) { return undefined; } -function longRunningResponseType(method: MethodDescriptorProto) { - if (method.options && method.options['.google.longrunning.operationInfo']) { - if (method.options['.google.longrunning.operationInfo'].responseType) { - return method.options['.google.longrunning.operationInfo'].responseType; - } +function toFullyQualifiedName(packageName: string, messageName: string) { + if (messageName.includes('.')) { + return messageName; + } + return `.${packageName}.${messageName}`; +} + +function longRunningResponseType( + packageName: string, + method: MethodDescriptorProto +) { + if ( + method.options && + method.options['.google.longrunning.operationInfo'] && + method.options['.google.longrunning.operationInfo'].responseType + ) { + return toFullyQualifiedName( + packageName, + method.options['.google.longrunning.operationInfo'].responseType + ); } return undefined; } -function longRunningMetadataType(method: MethodDescriptorProto) { - if (method.options && method.options['.google.longrunning.operationInfo']) { - if (method.options['.google.longrunning.operationInfo'].metadataType) { - return method.options['.google.longrunning.operationInfo'].metadataType; - } +function longRunningMetadataType( + packageName: string, + method: MethodDescriptorProto +) { + if ( + method.options && + method.options['.google.longrunning.operationInfo'] && + method.options['.google.longrunning.operationInfo'].metadataType + ) { + return toFullyQualifiedName( + packageName, + method.options['.google.longrunning.operationInfo'].metadataType + ); } return undefined; } @@ -289,8 +313,7 @@ function pagingResponseType( ) { const repeatedFields = pagingField(messages, method); if (repeatedFields && repeatedFields.typeName) { - const typeName = repeatedFields.typeName; //.google.showcase.v1beta1.EchoResponse - return typeName.replace(/\.([^.]+)$/, '.I$1'); + return repeatedFields.typeName; //.google.showcase.v1beta1.EchoResponse } return undefined; } @@ -339,8 +362,14 @@ function augmentMethod( method = Object.assign( { longRunning: longrunning(method), - longRunningResponseType: longRunningResponseType(method), - longRunningMetadataType: longRunningMetadataType(method), + longRunningResponseType: longRunningResponseType( + service.packageName, + method + ), + longRunningMetadataType: longRunningMetadataType( + service.packageName, + method + ), streaming: streaming(method), pagingFieldName: pagingFieldName(messages, method), pagingResponseType: pagingResponseType(messages, method), diff --git a/typescript/test/testdata/keymanager/src/v1/key_management_service_client.ts.baseline b/typescript/test/testdata/keymanager/src/v1/key_management_service_client.ts.baseline index c8396c2dc..fe853c4f2 100644 --- a/typescript/test/testdata/keymanager/src/v1/key_management_service_client.ts.baseline +++ b/typescript/test/testdata/keymanager/src/v1/key_management_service_client.ts.baseline @@ -144,12 +144,19 @@ export class KeyManagementServiceClient { // Determine the client header string. const clientHeader = [ - `gl-node/${process.version}`, `grpc/${gaxGrpc.grpcVersion}`, `gax/${gaxModule.version}`, `gapic/${version}`, `gl-web/${gaxModule.version}` ]; + if (typeof process !== 'undefined' && 'versions' in process) { + clientHeader.push(`gl-node/${process.versions.node}`); + } else { + clientHeader.push(`gl-web/${gaxModule.version}`); + } + if (!opts.fallback) { + clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); } diff --git a/typescript/test/testdata/showcase/src/v1beta1/echo_client.ts.baseline b/typescript/test/testdata/showcase/src/v1beta1/echo_client.ts.baseline index 12f4cf5cf..fa3c117d9 100644 --- a/typescript/test/testdata/showcase/src/v1beta1/echo_client.ts.baseline +++ b/typescript/test/testdata/showcase/src/v1beta1/echo_client.ts.baseline @@ -140,12 +140,19 @@ export class EchoClient { // Determine the client header string. const clientHeader = [ - `gl-node/${process.version}`, `grpc/${gaxGrpc.grpcVersion}`, `gax/${gaxModule.version}`, `gapic/${version}`, `gl-web/${gaxModule.version}` ]; + if (typeof process !== 'undefined' && 'versions' in process) { + clientHeader.push(`gl-node/${process.versions.node}`); + } else { + clientHeader.push(`gl-web/${gaxModule.version}`); + } + if (!opts.fallback) { + clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); } @@ -175,6 +182,7 @@ export class EchoClient { collect: new gaxModule.StreamDescriptor(gax.StreamType.CLIENT_STREAMING), chat: new gaxModule.StreamDescriptor(gax.StreamType.BIDI_STREAMING) }; + // This API contains "long-running operations", which return a // an Operation object that allows for tracking of the operation, // rather than holding a request open. @@ -187,9 +195,9 @@ export class EchoClient { grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined }).operationsClient(opts); const waitResponse = protoFilesRoot.lookup( - 'WaitResponse') as gax.protobuf.Type; + '.google.showcase.v1beta1.WaitResponse') as gax.protobuf.Type; const waitMetadata = protoFilesRoot.lookup( - 'WaitMetadata') as gax.protobuf.Type; + '.google.showcase.v1beta1.WaitMetadata') as gax.protobuf.Type; this._descriptors.longrunning = { wait: new gaxModule.LongrunningDescriptor( diff --git a/typescript/test/testdata/texttospeech/src/v1/text_to_speech_client.ts.baseline b/typescript/test/testdata/texttospeech/src/v1/text_to_speech_client.ts.baseline index 330c95444..b1e348041 100644 --- a/typescript/test/testdata/texttospeech/src/v1/text_to_speech_client.ts.baseline +++ b/typescript/test/testdata/texttospeech/src/v1/text_to_speech_client.ts.baseline @@ -121,12 +121,19 @@ export class TextToSpeechClient { // Determine the client header string. const clientHeader = [ - `gl-node/${process.version}`, `grpc/${gaxGrpc.grpcVersion}`, `gax/${gaxModule.version}`, `gapic/${version}`, `gl-web/${gaxModule.version}` ]; + if (typeof process !== 'undefined' && 'versions' in process) { + clientHeader.push(`gl-node/${process.versions.node}`); + } else { + clientHeader.push(`gl-web/${gaxModule.version}`); + } + if (!opts.fallback) { + clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); } diff --git a/typescript/test/testdata/translate/src/v3beta1/translation_service_client.ts.baseline b/typescript/test/testdata/translate/src/v3beta1/translation_service_client.ts.baseline index a60597e0b..bcf6e3b78 100644 --- a/typescript/test/testdata/translate/src/v3beta1/translation_service_client.ts.baseline +++ b/typescript/test/testdata/translate/src/v3beta1/translation_service_client.ts.baseline @@ -138,12 +138,19 @@ export class TranslationServiceClient { // Determine the client header string. const clientHeader = [ - `gl-node/${process.version}`, `grpc/${gaxGrpc.grpcVersion}`, `gax/${gaxModule.version}`, `gapic/${version}`, `gl-web/${gaxModule.version}` ]; + if (typeof process !== 'undefined' && 'versions' in process) { + clientHeader.push(`gl-node/${process.versions.node}`); + } else { + clientHeader.push(`gl-web/${gaxModule.version}`); + } + if (!opts.fallback) { + clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); } @@ -157,6 +164,10 @@ export class TranslationServiceClient { require("../../protos/protos.json") : nodejsProtoPath ); + + // This API contains "path templates"; forward-slash-separated + // identifiers to uniquely identify resources within the API. + // Create useful helper objects for these. this._pathTemplates = { locationPathTemplate: new gaxModule.PathTemplate( 'projects/{project}/locations/{location}' @@ -173,6 +184,7 @@ export class TranslationServiceClient { listGlossaries: new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'glossaries') }; + // This API contains "long-running operations", which return a // an Operation object that allows for tracking of the operation, // rather than holding a request open. @@ -185,17 +197,17 @@ export class TranslationServiceClient { grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined }).operationsClient(opts); const batchTranslateTextResponse = protoFilesRoot.lookup( - 'BatchTranslateResponse') as gax.protobuf.Type; + '.google.cloud.translation.v3beta1.BatchTranslateResponse') as gax.protobuf.Type; const batchTranslateTextMetadata = protoFilesRoot.lookup( - 'BatchTranslateMetadata') as gax.protobuf.Type; + '.google.cloud.translation.v3beta1.BatchTranslateMetadata') as gax.protobuf.Type; const createGlossaryResponse = protoFilesRoot.lookup( - 'Glossary') as gax.protobuf.Type; + '.google.cloud.translation.v3beta1.Glossary') as gax.protobuf.Type; const createGlossaryMetadata = protoFilesRoot.lookup( - 'CreateGlossaryMetadata') as gax.protobuf.Type; + '.google.cloud.translation.v3beta1.CreateGlossaryMetadata') as gax.protobuf.Type; const deleteGlossaryResponse = protoFilesRoot.lookup( - 'DeleteGlossaryResponse') as gax.protobuf.Type; + '.google.cloud.translation.v3beta1.DeleteGlossaryResponse') as gax.protobuf.Type; const deleteGlossaryMetadata = protoFilesRoot.lookup( - 'DeleteGlossaryMetadata') as gax.protobuf.Type; + '.google.cloud.translation.v3beta1.DeleteGlossaryMetadata') as gax.protobuf.Type; this._descriptors.longrunning = { batchTranslateText: new gaxModule.LongrunningDescriptor( diff --git a/typescript/test/testdata/translate/src/v3beta1/translation_service_proto_list.json.baseline b/typescript/test/testdata/translate/src/v3beta1/translation_service_proto_list.json.baseline index 47a656634..a50dcfc7d 100644 --- a/typescript/test/testdata/translate/src/v3beta1/translation_service_proto_list.json.baseline +++ b/typescript/test/testdata/translate/src/v3beta1/translation_service_proto_list.json.baseline @@ -1,4 +1,3 @@ [ - "../../protos/google/cloud/translate/v3beta1/translation_service.proto", - "../../protos/google/cloud/common_resources.proto" + "../../protos/google/cloud/translate/v3beta1/translation_service.proto" ]