From 6f755fe3469b888e7c0bca775f8eac430d0c8fb7 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Wed, 30 Nov 2022 22:31:22 +0900 Subject: [PATCH 1/7] add branded option for proto-loader-gen-types --- packages/proto-loader/bin/proto-loader-gen-types.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index a9ee4a6e..ae7e147b 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -45,6 +45,7 @@ type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeComments?: boolean; inputTemplate: string; outputTemplate: string; + branded: boolean; } class TextFormatter { @@ -263,6 +264,9 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp } formatter.writeLine(`'${oneof.name}'?: ${typeString};`); } + if (options.branded) { + formatter.writeLine(`__type: '${messageType.fullName}'`) + } formatter.unindent(); formatter.writeLine('}'); } @@ -383,6 +387,9 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp formatter.writeLine(`'${oneof.name}': ${typeString};`); } } + if (options.branded) { + formatter.writeLine(`__type: '${messageType.fullName}'`) + } formatter.unindent(); formatter.writeLine('}'); } @@ -815,7 +822,7 @@ async function runScript() { .string(['includeDirs', 'grpcLib']) .normalize(['includeDirs', 'outDir']) .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments']) + .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'branded']) .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) @@ -829,6 +836,7 @@ async function runScript() { .default('bytes', 'Buffer') .default('inputTemplate', `${templateStr}`) .default('outputTemplate', `${templateStr}__Output`) + .default('branded', false) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -868,6 +876,7 @@ async function runScript() { grpcLib: 'The gRPC implementation library that these types will be used with', inputTemplate: 'Template for mapping input or "permissive" type names', outputTemplate: 'Template for mapping output or "restricted" type names', + branded: 'Emit property for branded type whose value is fullName of the Message', }).demandOption(['outDir', 'grpcLib']) .demand(1) .usage('$0 [options] filenames...') From 9e548d4d87c55f2710aa5a62968fa1df565da5d4 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Wed, 30 Nov 2022 22:34:15 +0900 Subject: [PATCH 2/7] update readme --- packages/proto-loader/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index 818f0efd..74065878 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -92,6 +92,8 @@ Options: [string] [default: "%s"] --outputTemplate Template for mapping output or "restricted" type names [string] [default: "%s__Output"] + --branded Emit property for branded type whose value is fullName + of the Message [boolean] [default: false] ``` ### Example Usage From e955c47bd51332e5cf08ac3b3b02c396ebe124f0 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Thu, 1 Dec 2022 11:09:09 +0900 Subject: [PATCH 3/7] rename as outputBranded --- .../bin/proto-loader-gen-types.ts | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index ae7e147b..6327da95 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -37,6 +37,9 @@ const useNameFmter = ({outputTemplate, inputTemplate}: GeneratorOptions) => { }; } +const typeBrandHint = `This field is a type brand and is not populated at runtime. Instances of this type should be created using type assertions. +https://github.com/grpc/grpc-node/pull/2281`; + type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeDirs?: string[]; grpcLib: string; @@ -45,7 +48,7 @@ type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeComments?: boolean; inputTemplate: string; outputTemplate: string; - branded: boolean; + outputBranded: boolean; } class TextFormatter { @@ -179,6 +182,11 @@ function formatComment(formatter: TextFormatter, comment?: string | null) { formatter.writeLine(' */'); } +function formatTypeBrand(formatter: TextFormatter, messageType: Protobuf.Type) { + formatComment(formatter, typeBrandHint); + formatter.writeLine(`__type: '${messageType.fullName}'`); +} + // GENERATOR FUNCTIONS function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean, options: GeneratorOptions): string { @@ -264,9 +272,9 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp } formatter.writeLine(`'${oneof.name}'?: ${typeString};`); } - if (options.branded) { - formatter.writeLine(`__type: '${messageType.fullName}'`) - } + // if (options.inputBranded) { + // formatTypeBrand(formatter, messageType); + // } formatter.unindent(); formatter.writeLine('}'); } @@ -387,8 +395,8 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp formatter.writeLine(`'${oneof.name}': ${typeString};`); } } - if (options.branded) { - formatter.writeLine(`__type: '${messageType.fullName}'`) + if (options.outputBranded) { + formatTypeBrand(formatter, messageType); } formatter.unindent(); formatter.writeLine('}'); @@ -822,7 +830,7 @@ async function runScript() { .string(['includeDirs', 'grpcLib']) .normalize(['includeDirs', 'outDir']) .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'branded']) + .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'outputBranded']) .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) @@ -836,7 +844,7 @@ async function runScript() { .default('bytes', 'Buffer') .default('inputTemplate', `${templateStr}`) .default('outputTemplate', `${templateStr}__Output`) - .default('branded', false) + .default('outputBranded', false) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -876,7 +884,7 @@ async function runScript() { grpcLib: 'The gRPC implementation library that these types will be used with', inputTemplate: 'Template for mapping input or "permissive" type names', outputTemplate: 'Template for mapping output or "restricted" type names', - branded: 'Emit property for branded type whose value is fullName of the Message', + outputBranded: 'Output property for branded type for "restricted" types with fullName of the Message as its value', }).demandOption(['outDir', 'grpcLib']) .demand(1) .usage('$0 [options] filenames...') From 927c29de4ad8ac3f8642b6468fdd59d0cf587361 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Thu, 1 Dec 2022 12:37:48 +0900 Subject: [PATCH 4/7] support both input and output update readme update readme --- packages/proto-loader/README.md | 8 ++++++-- packages/proto-loader/bin/proto-loader-gen-types.ts | 13 +++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index 74065878..99b34a05 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -92,8 +92,12 @@ Options: [string] [default: "%s"] --outputTemplate Template for mapping output or "restricted" type names [string] [default: "%s__Output"] - --branded Emit property for branded type whose value is fullName - of the Message [boolean] [default: false] + --inputBranded Output property for branded type for "permissive" + types with fullName of the Message as its value + [boolean] + --outputBranded Output property for branded type for "restricted" + types with fullName of the Message as its value + [boolean] ``` ### Example Usage diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 6327da95..dc9da1a9 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -48,7 +48,8 @@ type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeComments?: boolean; inputTemplate: string; outputTemplate: string; - outputBranded: boolean; + inputBranded?: boolean; + outputBranded?: boolean; } class TextFormatter { @@ -272,9 +273,9 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp } formatter.writeLine(`'${oneof.name}'?: ${typeString};`); } - // if (options.inputBranded) { - // formatTypeBrand(formatter, messageType); - // } + if (options.inputBranded) { + formatTypeBrand(formatter, messageType); + } formatter.unindent(); formatter.writeLine('}'); } @@ -830,7 +831,7 @@ async function runScript() { .string(['includeDirs', 'grpcLib']) .normalize(['includeDirs', 'outDir']) .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'outputBranded']) + .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'inputBranded', 'outputBranded']) .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) @@ -844,7 +845,6 @@ async function runScript() { .default('bytes', 'Buffer') .default('inputTemplate', `${templateStr}`) .default('outputTemplate', `${templateStr}__Output`) - .default('outputBranded', false) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -884,6 +884,7 @@ async function runScript() { grpcLib: 'The gRPC implementation library that these types will be used with', inputTemplate: 'Template for mapping input or "permissive" 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', outputBranded: 'Output property for branded type for "restricted" types with fullName of the Message as its value', }).demandOption(['outDir', 'grpcLib']) .demand(1) From 256fbd89150e1f69e96a5d631c97745d5f51b169 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Thu, 1 Dec 2022 13:27:04 +0900 Subject: [PATCH 5/7] set defaults for brand option --- packages/proto-loader/README.md | 12 ++++++------ .../proto-loader/bin/proto-loader-gen-types.ts | 14 +++++++++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index 99b34a05..f10831ee 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -63,6 +63,12 @@ proto-loader-gen-types.js [options] filenames... Options: --help Show help [boolean] --version Show version number [boolean] + --inputBranded Output property for branded type for "permissive" + types with fullName of the Message as its value + [boolean] [default: false] + --outputBranded Output property for branded type for "restricted" + types with fullName of the Message as its value + [boolean] [default: false] --keepCase Preserve the case of field names [boolean] [default: false] --longs The type that should be used to output 64 bit integer @@ -92,12 +98,6 @@ Options: [string] [default: "%s"] --outputTemplate Template for mapping output or "restricted" type names [string] [default: "%s__Output"] - --inputBranded Output property for branded type for "permissive" - types with fullName of the Message as its value - [boolean] - --outputBranded Output property for branded type for "restricted" - types with fullName of the Message as its value - [boolean] ``` ### Example Usage diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index dc9da1a9..465f362f 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -48,8 +48,8 @@ type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeComments?: boolean; inputTemplate: string; outputTemplate: string; - inputBranded?: boolean; - outputBranded?: boolean; + inputBranded: boolean; + outputBranded: boolean; } class TextFormatter { @@ -831,7 +831,7 @@ async function runScript() { .string(['includeDirs', 'grpcLib']) .normalize(['includeDirs', 'outDir']) .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'inputBranded', 'outputBranded']) + .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments']) .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) @@ -864,6 +864,14 @@ async function runScript() { default: return undefined; } }) + .option('inputBranded', { + boolean: true, + default: false, + }) + .option('outputBranded', { + boolean: true, + default: false, + }) .alias({ includeDirs: 'I', outDir: 'O', From 80332044c73ba0789efc563b329fd9c9257cad6b Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Thu, 1 Dec 2022 14:12:10 +0900 Subject: [PATCH 6/7] update typeBrandHint location --- packages/proto-loader/bin/proto-loader-gen-types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 465f362f..5a9a32f8 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -37,9 +37,6 @@ const useNameFmter = ({outputTemplate, inputTemplate}: GeneratorOptions) => { }; } -const typeBrandHint = `This field is a type brand and is not populated at runtime. Instances of this type should be created using type assertions. -https://github.com/grpc/grpc-node/pull/2281`; - type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeDirs?: string[]; grpcLib: string; @@ -183,6 +180,9 @@ function formatComment(formatter: TextFormatter, comment?: string | null) { formatter.writeLine(' */'); } +const typeBrandHint = `This field is a type brand and is not populated at runtime. Instances of this type should be created using type assertions. +https://github.com/grpc/grpc-node/pull/2281`; + function formatTypeBrand(formatter: TextFormatter, messageType: Protobuf.Type) { formatComment(formatter, typeBrandHint); formatter.writeLine(`__type: '${messageType.fullName}'`); From f1e3f6d7d3a291ec47b93f726591ca0c46883f44 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Fri, 2 Dec 2022 23:57:22 +0900 Subject: [PATCH 7/7] use option method --- packages/proto-loader/README.md | 12 ++-- .../bin/proto-loader-gen-types.ts | 56 ++++++++++--------- 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index f10831ee..2a7af61e 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -63,12 +63,6 @@ proto-loader-gen-types.js [options] filenames... Options: --help Show help [boolean] --version Show version number [boolean] - --inputBranded Output property for branded type for "permissive" - types with fullName of the Message as its value - [boolean] [default: false] - --outputBranded Output property for branded type for "restricted" - types with fullName of the Message as its value - [boolean] [default: false] --keepCase Preserve the case of field names [boolean] [default: false] --longs The type that should be used to output 64 bit integer @@ -98,6 +92,12 @@ Options: [string] [default: "%s"] --outputTemplate Template for mapping output or "restricted" type names [string] [default: "%s__Output"] + --inputBranded Output property for branded type for "permissive" + types with fullName of the Message as its value + [boolean] [default: false] + --outputBranded Output property for branded type for "restricted" + types with fullName of the Message as its value + [boolean] [default: false] ``` ### Example Usage diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 5a9a32f8..f7582208 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -824,27 +824,39 @@ async function writeAllFiles(protoFiles: string[], options: GeneratorOptions) { } async function runScript() { + const boolDefaultFalseOption = { + boolean: true, + default: false, + }; const argv = yargs .parserConfiguration({ 'parse-positional-numbers': false }) - .string(['includeDirs', 'grpcLib']) - .normalize(['includeDirs', 'outDir']) - .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments']) - .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) - .default('keepCase', false) - .default('defaults', false) - .default('arrays', false) - .default('objects', false) - .default('oneofs', false) - .default('json', false) - .default('includeComments', false) - .default('longs', 'Long') - .default('enums', 'number') - .default('bytes', 'Buffer') - .default('inputTemplate', `${templateStr}`) - .default('outputTemplate', `${templateStr}__Output`) + .option('keepCase', boolDefaultFalseOption) + .option('longs', { string: true, default: 'Long' }) + .option('enums', { string: true, default: 'number' }) + .option('bytes', { string: true, default: 'Buffer' }) + .option('defaults', boolDefaultFalseOption) + .option('arrays', boolDefaultFalseOption) + .option('objects', boolDefaultFalseOption) + .option('oneofs', boolDefaultFalseOption) + .option('json', boolDefaultFalseOption) + .boolean('verbose') + .option('includeComments', boolDefaultFalseOption) + .option('includeDirs', { + normalize: true, + array: true, + alias: 'I' + }) + .option('outDir', { + alias: 'O', + normalize: true, + }) + .option('grpcLib', { string: true }) + .option('inputTemplate', { string: true, default: `${templateStr}` }) + .option('outputTemplate', { string: true, default: `${templateStr}__Output` }) + .option('inputBranded', boolDefaultFalseOption) + .option('outputBranded', boolDefaultFalseOption) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -864,17 +876,7 @@ async function runScript() { default: return undefined; } }) - .option('inputBranded', { - boolean: true, - default: false, - }) - .option('outputBranded', { - boolean: true, - default: false, - }) .alias({ - includeDirs: 'I', - outDir: 'O', verbose: 'v' }).describe({ keepCase: 'Preserve the case of field names',