Merge pull request #2573 from murgatroid99/proto-loader_no_grpc_library

proto-loader: Allow the `grpcLib` option to be omitted in the type generator
This commit is contained in:
Michael Lumish 2023-09-18 15:06:29 -07:00 committed by GitHub
commit ddb8de2992
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 18 deletions

View File

@ -87,7 +87,8 @@ Options:
-I, --includeDirs Directories to search for included files [array] -I, --includeDirs Directories to search for included files [array]
-O, --outDir Directory in which to output files [string] [required] -O, --outDir Directory in which to output files [string] [required]
--grpcLib The gRPC implementation library that these types will --grpcLib The gRPC implementation library that these types will
be used with [string] [required] be used with. If not provided, some types will not be
generated [string]
--inputTemplate Template for mapping input or "permissive" type names --inputTemplate Template for mapping input or "permissive" type names
[string] [default: "%s"] [string] [default: "%s"]
--outputTemplate Template for mapping output or "restricted" type names --outputTemplate Template for mapping output or "restricted" type names

View File

@ -39,7 +39,7 @@ const useNameFmter = ({outputTemplate, inputTemplate}: GeneratorOptions) => {
type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & {
includeDirs?: string[]; includeDirs?: string[];
grpcLib: string; grpcLib?: string;
outDir: string; outDir: string;
verbose?: boolean; verbose?: boolean;
includeComments?: boolean; includeComments?: boolean;
@ -522,12 +522,12 @@ function generateEnumInterface(formatter: TextFormatter, enumType: Protobuf.Enum
* We always generate two service client methods per service method: one camel * We always generate two service client methods per service method: one camel
* cased, and one with the original casing. So we will still generate one * cased, and one with the original casing. So we will still generate one
* service client method for any conflicting name. * service client method for any conflicting name.
* *
* Technically, at runtime conflicting name in the service client method * Technically, at runtime conflicting name in the service client method
* actually shadows the original method, but TypeScript does not have a good * actually shadows the original method, but TypeScript does not have a good
* way to represent that. So this change is not 100% accurate, but it gets the * way to represent that. So this change is not 100% accurate, but it gets the
* generated code to compile. * generated code to compile.
* *
* This is just a list of the methods in the Client class definitions in * This is just a list of the methods in the Client class definitions in
* grpc@1.24.11 and @grpc/grpc-js@1.4.0. * grpc@1.24.11 and @grpc/grpc-js@1.4.0.
*/ */
@ -640,7 +640,11 @@ function generateServiceHandlerInterface(formatter: TextFormatter, serviceType:
function generateServiceDefinitionInterface(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { function generateServiceDefinitionInterface(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) {
const {inputName, outputName} = useNameFmter(options); const {inputName, outputName} = useNameFmter(options);
formatter.writeLine(`export interface ${serviceType.name}Definition extends grpc.ServiceDefinition {`); if (options.grpcLib) {
formatter.writeLine(`export interface ${serviceType.name}Definition extends grpc.ServiceDefinition {`);
} else {
formatter.writeLine(`export interface ${serviceType.name}Definition {`);
}
formatter.indent(); formatter.indent();
for (const methodName of Object.keys(serviceType.methods).sort()) { for (const methodName of Object.keys(serviceType.methods).sort()) {
const method = serviceType.methods[methodName]; const method = serviceType.methods[methodName];
@ -655,8 +659,10 @@ function generateServiceDefinitionInterface(formatter: TextFormatter, serviceTyp
function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) {
formatter.writeLine(`// Original file: ${(serviceType.filename ?? 'null')?.replace(/\\/g, '/')}`); formatter.writeLine(`// Original file: ${(serviceType.filename ?? 'null')?.replace(/\\/g, '/')}`);
formatter.writeLine(''); formatter.writeLine('');
const grpcImportPath = options.grpcLib.startsWith('.') ? getPathToRoot(serviceType) + options.grpcLib : options.grpcLib; if (options.grpcLib) {
formatter.writeLine(`import type * as grpc from '${grpcImportPath}'`); 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'`) formatter.writeLine(`import type { MethodDefinition } from '@grpc/proto-loader'`)
const dependencies: Set<Protobuf.Type> = new Set<Protobuf.Type>(); const dependencies: Set<Protobuf.Type> = new Set<Protobuf.Type>();
for (const method of serviceType.methodsArray) { for (const method of serviceType.methodsArray) {
@ -668,11 +674,13 @@ function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protob
} }
formatter.writeLine(''); formatter.writeLine('');
generateServiceClientInterface(formatter, serviceType, options); if (options.grpcLib) {
formatter.writeLine(''); generateServiceClientInterface(formatter, serviceType, options);
formatter.writeLine('');
generateServiceHandlerInterface(formatter, serviceType, options); generateServiceHandlerInterface(formatter, serviceType, options);
formatter.writeLine(''); formatter.writeLine('');
}
generateServiceDefinitionInterface(formatter, serviceType, options); generateServiceDefinitionInterface(formatter, serviceType, options);
} }
@ -742,6 +750,9 @@ function generateLoadedDefinitionTypes(formatter: TextFormatter, namespace: Prot
} }
function generateRootFile(formatter: TextFormatter, root: Protobuf.Root, options: GeneratorOptions) { function generateRootFile(formatter: TextFormatter, root: Protobuf.Root, options: GeneratorOptions) {
if (!options.grpcLib) {
return;
}
formatter.writeLine(`import type * as grpc from '${options.grpcLib}';`); formatter.writeLine(`import type * as grpc from '${options.grpcLib}';`);
generateDefinitionImports(formatter, root, options); generateDefinitionImports(formatter, root, options);
formatter.writeLine(''); formatter.writeLine('');
@ -802,11 +813,13 @@ function writeFilesForRoot(root: Protobuf.Root, masterFileName: string, options:
const filePromises: Promise<void>[] = []; const filePromises: Promise<void>[] = [];
const masterFileFormatter = new TextFormatter(); const masterFileFormatter = new TextFormatter();
generateRootFile(masterFileFormatter, root, options); if (options.grpcLib) {
if (options.verbose) { generateRootFile(masterFileFormatter, root, options);
console.log(`Writing ${options.outDir}/${masterFileName}`); if (options.verbose) {
console.log(`Writing ${options.outDir}/${masterFileName}`);
}
filePromises.push(writeFile(`${options.outDir}/${masterFileName}`, masterFileFormatter.getFullText()));
} }
filePromises.push(writeFile(`${options.outDir}/${masterFileName}`, masterFileFormatter.getFullText()));
filePromises.push(...generateFilesForNamespace(root, options)); filePromises.push(...generateFilesForNamespace(root, options));
@ -898,12 +911,12 @@ async function runScript() {
includeComments: 'Generate doc comments from comments in the original files', includeComments: 'Generate doc comments from comments in the original files',
includeDirs: 'Directories to search for included files', includeDirs: 'Directories to search for included files',
outDir: 'Directory in which to output files', outDir: 'Directory in which to output files',
grpcLib: 'The gRPC implementation library that these types will be used with', grpcLib: 'The gRPC implementation library that these types will be used with. If not provided, some types will not be generated',
inputTemplate: 'Template for mapping input or "permissive" type names', inputTemplate: 'Template for mapping input or "permissive" type names',
outputTemplate: 'Template for mapping output or "restricted" type names', outputTemplate: 'Template for mapping output or "restricted" type names',
inputBranded: 'Output property for branded type for "permissive" types with fullName of the Message as its value', inputBranded: 'Output property for branded type for "permissive" types with fullName of the Message as its value',
outputBranded: 'Output property for branded type for "restricted" types with fullName of the Message as its value', outputBranded: 'Output property for branded type for "restricted" types with fullName of the Message as its value',
}).demandOption(['outDir', 'grpcLib']) }).demandOption(['outDir'])
.demand(1) .demand(1)
.usage('$0 [options] filenames...') .usage('$0 [options] filenames...')
.epilogue('WARNING: This tool is in alpha. The CLI and generated code are subject to change') .epilogue('WARNING: This tool is in alpha. The CLI and generated code are subject to change')

View File

@ -1,6 +1,6 @@
{ {
"name": "@grpc/proto-loader", "name": "@grpc/proto-loader",
"version": "0.7.9", "version": "0.7.10",
"author": "Google Inc.", "author": "Google Inc.",
"contributors": [ "contributors": [
{ {