diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 66a6fec7a..04717f3fb 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -126,7 +126,7 @@ function getImportLine(dependency: Protobuf.Type | Protobuf.Enum | Protobuf.Serv } else if (dependency instanceof Protobuf.Enum) { importedTypes = `${typeInterfaceName}`; } else if (dependency instanceof Protobuf.Service) { - importedTypes = `${typeInterfaceName}Client`; + importedTypes = `${typeInterfaceName}Client, ${typeInterfaceName}Definition`; } else { throw new Error('Invalid object passed to getImportLine'); } @@ -136,7 +136,7 @@ function getImportLine(dependency: Protobuf.Type | Protobuf.Enum | Protobuf.Serv } else if (dependency instanceof Protobuf.Enum) { importedTypes = `${dependency.name} as ${typeInterfaceName}`; } else if (dependency instanceof Protobuf.Service) { - importedTypes = `${dependency.name}Client as ${typeInterfaceName}Client`; + importedTypes = `${dependency.name}Client as ${typeInterfaceName}Client, ${dependency.name}Definition as ${typeInterfaceName}Definition`; } else { throw new Error('Invalid object passed to getImportLine'); } @@ -541,11 +541,25 @@ function generateServiceHandlerInterface(formatter: TextFormatter, serviceType: formatter.writeLine('}'); } +function generateServiceDefinitionInterface(formatter: TextFormatter, serviceType: Protobuf.Service) { + formatter.writeLine(`export interface ${serviceType.name}Definition {`); + formatter.indent(); + for (const methodName of Object.keys(serviceType.methods).sort()) { + const method = serviceType.methods[methodName]; + const requestType = getTypeInterfaceName(method.resolvedRequestType!); + const responseType = getTypeInterfaceName(method.resolvedResponseType!); + formatter.writeLine(`${methodName}: MethodDefinition<${requestType}, ${responseType}, ${requestType}__Output, ${responseType}__Output>`); + } + formatter.unindent(); + formatter.writeLine('}') +} + function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { formatter.writeLine(`// Original file: ${serviceType.filename}`); formatter.writeLine(''); const grpcImportPath = options.grpcLib.startsWith('.') ? getPathToRoot(serviceType) + options.grpcLib : options.grpcLib; formatter.writeLine(`import type * as grpc from '${grpcImportPath}'`); + formatter.writeLine(`import type { MethodDefinition } from '@grpc/proto-loader'`) const dependencies: Set = new Set(); for (const method of serviceType.methodsArray) { dependencies.add(method.resolvedRequestType!); @@ -560,6 +574,9 @@ function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protob formatter.writeLine(''); generateServiceHandlerInterface(formatter, serviceType, options); + formatter.writeLine(''); + + generateServiceDefinitionInterface(formatter, serviceType); } function generateServiceImports(formatter: TextFormatter, namespace: Protobuf.NamespaceBase, options: GeneratorOptions) { @@ -577,7 +594,8 @@ function generateSingleLoadedDefinitionType(formatter: TextFormatter, nested: Pr if (options.includeComments) { formatComment(formatter, nested.comment); } - formatter.writeLine(`${nested.name}: SubtypeConstructor & { service: ServiceDefinition }`) + const typeInterfaceName = getTypeInterfaceName(nested); + formatter.writeLine(`${nested.name}: SubtypeConstructor & { service: ${typeInterfaceName}Definition }`); } else if (nested instanceof Protobuf.Enum) { formatter.writeLine(`${nested.name}: EnumTypeDefinition`); } else if (nested instanceof Protobuf.Type) { diff --git a/packages/proto-loader/golden-generated/echo.ts b/packages/proto-loader/golden-generated/echo.ts index 02514f053..f257a40e4 100644 --- a/packages/proto-loader/golden-generated/echo.ts +++ b/packages/proto-loader/golden-generated/echo.ts @@ -1,8 +1,8 @@ import type * as grpc from '@grpc/grpc-js'; import type { ServiceDefinition, EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; -import type { OperationsClient as _google_longrunning_OperationsClient } from './google/longrunning/Operations'; -import type { EchoClient as _google_showcase_v1beta1_EchoClient } from './google/showcase/v1beta1/Echo'; +import type { OperationsClient as _google_longrunning_OperationsClient, OperationsDefinition as _google_longrunning_OperationsDefinition } from './google/longrunning/Operations'; +import type { EchoClient as _google_showcase_v1beta1_EchoClient, EchoDefinition as _google_showcase_v1beta1_EchoDefinition } from './google/showcase/v1beta1/Echo'; type SubtypeConstructor any, Subtype> = { new(...args: ConstructorParameters): Subtype; @@ -35,7 +35,7 @@ export interface ProtoGrpcType { * returns long-running operations should implement the `Operations` interface * so developers can have a consistent client experience. */ - Operations: SubtypeConstructor & { service: ServiceDefinition } + Operations: SubtypeConstructor & { service: _google_longrunning_OperationsDefinition } WaitOperationRequest: MessageTypeDefinition } protobuf: { @@ -78,7 +78,7 @@ export interface ProtoGrpcType { * paginated calls. Set the 'showcase-trailer' metadata key on any method * to have the values echoed in the response trailers. */ - Echo: SubtypeConstructor & { service: ServiceDefinition } + Echo: SubtypeConstructor & { service: _google_showcase_v1beta1_EchoDefinition } EchoRequest: MessageTypeDefinition EchoResponse: MessageTypeDefinition ExpandRequest: MessageTypeDefinition diff --git a/packages/proto-loader/golden-generated/google/longrunning/Operations.ts b/packages/proto-loader/golden-generated/google/longrunning/Operations.ts index 6aa477ada..8e5684ada 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/Operations.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/Operations.ts @@ -1,6 +1,7 @@ // Original file: deps/googleapis/google/longrunning/operations.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { CancelOperationRequest as _google_longrunning_CancelOperationRequest, CancelOperationRequest__Output as _google_longrunning_CancelOperationRequest__Output } from '../../google/longrunning/CancelOperationRequest'; import type { DeleteOperationRequest as _google_longrunning_DeleteOperationRequest, DeleteOperationRequest__Output as _google_longrunning_DeleteOperationRequest__Output } from '../../google/longrunning/DeleteOperationRequest'; import type { Empty as _google_protobuf_Empty, Empty__Output as _google_protobuf_Empty__Output } from '../../google/protobuf/Empty'; @@ -230,3 +231,11 @@ export interface OperationsHandlers extends grpc.UntypedServiceImplementation { WaitOperation: grpc.handleUnaryCall<_google_longrunning_WaitOperationRequest__Output, _google_longrunning_Operation>; } + +export interface OperationsDefinition { + CancelOperation: MethodDefinition<_google_longrunning_CancelOperationRequest, _google_protobuf_Empty, _google_longrunning_CancelOperationRequest__Output, _google_protobuf_Empty__Output> + DeleteOperation: MethodDefinition<_google_longrunning_DeleteOperationRequest, _google_protobuf_Empty, _google_longrunning_DeleteOperationRequest__Output, _google_protobuf_Empty__Output> + GetOperation: MethodDefinition<_google_longrunning_GetOperationRequest, _google_longrunning_Operation, _google_longrunning_GetOperationRequest__Output, _google_longrunning_Operation__Output> + ListOperations: MethodDefinition<_google_longrunning_ListOperationsRequest, _google_longrunning_ListOperationsResponse, _google_longrunning_ListOperationsRequest__Output, _google_longrunning_ListOperationsResponse__Output> + WaitOperation: MethodDefinition<_google_longrunning_WaitOperationRequest, _google_longrunning_Operation, _google_longrunning_WaitOperationRequest__Output, _google_longrunning_Operation__Output> +} diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts index 33fe373a8..acb911270 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts @@ -1,6 +1,7 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { BlockRequest as _google_showcase_v1beta1_BlockRequest, BlockRequest__Output as _google_showcase_v1beta1_BlockRequest__Output } from '../../../google/showcase/v1beta1/BlockRequest'; import type { BlockResponse as _google_showcase_v1beta1_BlockResponse, BlockResponse__Output as _google_showcase_v1beta1_BlockResponse__Output } from '../../../google/showcase/v1beta1/BlockResponse'; import type { EchoRequest as _google_showcase_v1beta1_EchoRequest, EchoRequest__Output as _google_showcase_v1beta1_EchoRequest__Output } from '../../../google/showcase/v1beta1/EchoRequest'; @@ -189,3 +190,13 @@ export interface EchoHandlers extends grpc.UntypedServiceImplementation { Wait: grpc.handleUnaryCall<_google_showcase_v1beta1_WaitRequest__Output, _google_longrunning_Operation>; } + +export interface EchoDefinition { + Block: MethodDefinition<_google_showcase_v1beta1_BlockRequest, _google_showcase_v1beta1_BlockResponse, _google_showcase_v1beta1_BlockRequest__Output, _google_showcase_v1beta1_BlockResponse__Output> + Chat: MethodDefinition<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> + Collect: MethodDefinition<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> + Echo: MethodDefinition<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> + Expand: MethodDefinition<_google_showcase_v1beta1_ExpandRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_ExpandRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> + PagedExpand: MethodDefinition<_google_showcase_v1beta1_PagedExpandRequest, _google_showcase_v1beta1_PagedExpandResponse, _google_showcase_v1beta1_PagedExpandRequest__Output, _google_showcase_v1beta1_PagedExpandResponse__Output> + Wait: MethodDefinition<_google_showcase_v1beta1_WaitRequest, _google_longrunning_Operation, _google_showcase_v1beta1_WaitRequest__Output, _google_longrunning_Operation__Output> +} diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index cfc767a9b..ee49abc40 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.0", + "version": "0.6.1", "author": "Google Inc.", "contributors": [ { diff --git a/packages/proto-loader/src/index.ts b/packages/proto-loader/src/index.ts index 6f76956a9..98ca97b51 100644 --- a/packages/proto-loader/src/index.ts +++ b/packages/proto-loader/src/index.ts @@ -115,14 +115,14 @@ export interface EnumTypeDefinition extends ProtobufTypeDefinition { format: 'Protocol Buffer 3 EnumDescriptorProto'; } -export interface MethodDefinition { +export interface MethodDefinition { path: string; requestStream: boolean; responseStream: boolean; requestSerialize: Serialize; responseSerialize: Serialize; - requestDeserialize: Deserialize; - responseDeserialize: Deserialize; + requestDeserialize: Deserialize; + responseDeserialize: Deserialize; originalName?: string; requestType: MessageTypeDefinition; responseType: MessageTypeDefinition;