Merge pull request #2276 from install/avoidTsEnums

proto-loader-gen-types Avoid TS enums
This commit is contained in:
Michael Lumish 2022-11-18 12:57:54 -08:00 committed by GitHub
commit 8bee12e9c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 266 additions and 88 deletions

View File

@ -135,20 +135,16 @@ function getImportLine(dependency: Protobuf.Type | Protobuf.Enum | Protobuf.Serv
/* If the dependency is defined within a message, it will be generated in that
* message's file and exported using its typeInterfaceName. */
if (dependency.parent instanceof Protobuf.Type) {
if (dependency instanceof Protobuf.Type) {
if (dependency instanceof Protobuf.Type || dependency instanceof Protobuf.Enum) {
importedTypes = `${inputName(typeInterfaceName)}, ${outputName(typeInterfaceName)}`;
} else if (dependency instanceof Protobuf.Enum) {
importedTypes = `${typeInterfaceName}`;
} else if (dependency instanceof Protobuf.Service) {
importedTypes = `${typeInterfaceName}Client, ${typeInterfaceName}Definition`;
} else {
throw new Error('Invalid object passed to getImportLine');
}
} else {
if (dependency instanceof Protobuf.Type) {
if (dependency instanceof Protobuf.Type || dependency instanceof Protobuf.Enum) {
importedTypes = `${inputName(dependency.name)} as ${inputName(typeInterfaceName)}, ${outputName(dependency.name)} as ${outputName(typeInterfaceName)}`;
} else if (dependency instanceof Protobuf.Enum) {
importedTypes = `${dependency.name} as ${typeInterfaceName}`;
} else if (dependency instanceof Protobuf.Service) {
importedTypes = `${dependency.name}Client as ${typeInterfaceName}Client, ${dependency.name}Definition as ${typeInterfaceName}Definition`;
} else {
@ -220,7 +216,8 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type |
return `${inputName(typeInterfaceName)} | null`;
}
} else {
return `${typeInterfaceName} | keyof typeof ${typeInterfaceName}`;
// Enum
return inputName(typeInterfaceName);
}
}
}
@ -324,11 +321,8 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type |
return `${outputName(typeInterfaceName)}`;
}
} else {
if (options.enums == String) {
return `keyof typeof ${typeInterfaceName}`;
} else {
return typeInterfaceName;
}
// Enum
return outputName(typeInterfaceName);
}
}
}
@ -455,21 +449,46 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob
}
function generateEnumInterface(formatter: TextFormatter, enumType: Protobuf.Enum, options: GeneratorOptions, nameOverride?: string) {
const {inputName, outputName} = useNameFmter(options);
const name = nameOverride ?? enumType.name;
formatter.writeLine(`// Original file: ${(enumType.filename ?? 'null')?.replace(/\\/g, '/')}`);
formatter.writeLine('');
if (options.includeComments) {
formatComment(formatter, enumType.comment);
}
formatter.writeLine(`export enum ${nameOverride ?? enumType.name} {`);
formatter.writeLine(`export const ${name} = {`);
formatter.indent();
for (const key of Object.keys(enumType.values)) {
if (options.includeComments) {
formatComment(formatter, enumType.comments[key]);
}
formatter.writeLine(`${key} = ${enumType.values[key]},`);
formatter.writeLine(`${key}: ${options.enums == String ? `'${key}'` : enumType.values[key]},`);
}
formatter.unindent();
formatter.writeLine('}');
formatter.writeLine('} as const;');
// Permissive Type
formatter.writeLine('');
if (options.includeComments) {
formatComment(formatter, enumType.comment);
}
formatter.writeLine(`export type ${inputName(name)} =`)
formatter.indent();
for (const key of Object.keys(enumType.values)) {
if (options.includeComments) {
formatComment(formatter, enumType.comments[key]);
}
formatter.writeLine(`| '${key}'`);
formatter.writeLine(`| ${enumType.values[key]}`);
}
formatter.unindent();
// Restrictive Type
formatter.writeLine('');
if (options.includeComments) {
formatComment(formatter, enumType.comment);
}
formatter.writeLine(`export type ${outputName(name)} = typeof ${name}[keyof typeof ${name}]`)
}
/**

View File

@ -8,40 +8,101 @@
*
* Note: This enum **may** receive new values in the future.
*/
export enum FieldBehavior {
export const FieldBehavior = {
/**
* Conventional default for enums. Do not use this.
*/
FIELD_BEHAVIOR_UNSPECIFIED = 0,
FIELD_BEHAVIOR_UNSPECIFIED: 'FIELD_BEHAVIOR_UNSPECIFIED',
/**
* Specifically denotes a field as optional.
* While all fields in protocol buffers are optional, this may be specified
* for emphasis if appropriate.
*/
OPTIONAL = 1,
OPTIONAL: 'OPTIONAL',
/**
* Denotes a field as required.
* This indicates that the field **must** be provided as part of the request,
* and failure to do so will cause an error (usually `INVALID_ARGUMENT`).
*/
REQUIRED = 2,
REQUIRED: 'REQUIRED',
/**
* Denotes a field as output only.
* This indicates that the field is provided in responses, but including the
* field in a request does nothing (the server *must* ignore it and
* *must not* throw an error as a result of the field's presence).
*/
OUTPUT_ONLY = 3,
OUTPUT_ONLY: 'OUTPUT_ONLY',
/**
* Denotes a field as input only.
* This indicates that the field is provided in requests, and the
* corresponding field is not included in output.
*/
INPUT_ONLY = 4,
INPUT_ONLY: 'INPUT_ONLY',
/**
* Denotes a field as immutable.
* This indicates that the field may be set once in a request to create a
* resource, but may not be changed thereafter.
*/
IMMUTABLE = 5,
}
IMMUTABLE: 'IMMUTABLE',
} as const;
/**
* An indicator of the behavior of a given field (for example, that a field
* is required in requests, or given as output but ignored as input).
* This **does not** change the behavior in protocol buffers itself; it only
* denotes the behavior and may affect how API tooling handles the field.
*
* Note: This enum **may** receive new values in the future.
*/
export type IFieldBehavior =
/**
* Conventional default for enums. Do not use this.
*/
| 'FIELD_BEHAVIOR_UNSPECIFIED'
| 0
/**
* Specifically denotes a field as optional.
* While all fields in protocol buffers are optional, this may be specified
* for emphasis if appropriate.
*/
| 'OPTIONAL'
| 1
/**
* Denotes a field as required.
* This indicates that the field **must** be provided as part of the request,
* and failure to do so will cause an error (usually `INVALID_ARGUMENT`).
*/
| 'REQUIRED'
| 2
/**
* Denotes a field as output only.
* This indicates that the field is provided in responses, but including the
* field in a request does nothing (the server *must* ignore it and
* *must not* throw an error as a result of the field's presence).
*/
| 'OUTPUT_ONLY'
| 3
/**
* Denotes a field as input only.
* This indicates that the field is provided in requests, and the
* corresponding field is not included in output.
*/
| 'INPUT_ONLY'
| 4
/**
* Denotes a field as immutable.
* This indicates that the field may be set once in a request to create a
* resource, but may not be changed thereafter.
*/
| 'IMMUTABLE'
| 5
/**
* An indicator of the behavior of a given field (for example, that a field
* is required in requests, or given as output but ignored as input).
* This **does not** change the behavior in protocol buffers itself; it only
* denotes the behavior and may affect how API tooling handles the field.
*
* Note: This enum **may** receive new values in the future.
*/
export type OFieldBehavior = typeof FieldBehavior[keyof typeof FieldBehavior]

View File

@ -4,41 +4,91 @@ import type { IFieldOptions as I_google_protobuf_FieldOptions, OFieldOptions as
// Original file: null
export enum _google_protobuf_FieldDescriptorProto_Label {
LABEL_OPTIONAL = 1,
LABEL_REQUIRED = 2,
LABEL_REPEATED = 3,
}
export const _google_protobuf_FieldDescriptorProto_Label = {
LABEL_OPTIONAL: 'LABEL_OPTIONAL',
LABEL_REQUIRED: 'LABEL_REQUIRED',
LABEL_REPEATED: 'LABEL_REPEATED',
} as const;
export type I_google_protobuf_FieldDescriptorProto_Label =
| 'LABEL_OPTIONAL'
| 1
| 'LABEL_REQUIRED'
| 2
| 'LABEL_REPEATED'
| 3
export type O_google_protobuf_FieldDescriptorProto_Label = typeof _google_protobuf_FieldDescriptorProto_Label[keyof typeof _google_protobuf_FieldDescriptorProto_Label]
// Original file: null
export enum _google_protobuf_FieldDescriptorProto_Type {
TYPE_DOUBLE = 1,
TYPE_FLOAT = 2,
TYPE_INT64 = 3,
TYPE_UINT64 = 4,
TYPE_INT32 = 5,
TYPE_FIXED64 = 6,
TYPE_FIXED32 = 7,
TYPE_BOOL = 8,
TYPE_STRING = 9,
TYPE_GROUP = 10,
TYPE_MESSAGE = 11,
TYPE_BYTES = 12,
TYPE_UINT32 = 13,
TYPE_ENUM = 14,
TYPE_SFIXED32 = 15,
TYPE_SFIXED64 = 16,
TYPE_SINT32 = 17,
TYPE_SINT64 = 18,
}
export const _google_protobuf_FieldDescriptorProto_Type = {
TYPE_DOUBLE: 'TYPE_DOUBLE',
TYPE_FLOAT: 'TYPE_FLOAT',
TYPE_INT64: 'TYPE_INT64',
TYPE_UINT64: 'TYPE_UINT64',
TYPE_INT32: 'TYPE_INT32',
TYPE_FIXED64: 'TYPE_FIXED64',
TYPE_FIXED32: 'TYPE_FIXED32',
TYPE_BOOL: 'TYPE_BOOL',
TYPE_STRING: 'TYPE_STRING',
TYPE_GROUP: 'TYPE_GROUP',
TYPE_MESSAGE: 'TYPE_MESSAGE',
TYPE_BYTES: 'TYPE_BYTES',
TYPE_UINT32: 'TYPE_UINT32',
TYPE_ENUM: 'TYPE_ENUM',
TYPE_SFIXED32: 'TYPE_SFIXED32',
TYPE_SFIXED64: 'TYPE_SFIXED64',
TYPE_SINT32: 'TYPE_SINT32',
TYPE_SINT64: 'TYPE_SINT64',
} as const;
export type I_google_protobuf_FieldDescriptorProto_Type =
| 'TYPE_DOUBLE'
| 1
| 'TYPE_FLOAT'
| 2
| 'TYPE_INT64'
| 3
| 'TYPE_UINT64'
| 4
| 'TYPE_INT32'
| 5
| 'TYPE_FIXED64'
| 6
| 'TYPE_FIXED32'
| 7
| 'TYPE_BOOL'
| 8
| 'TYPE_STRING'
| 9
| 'TYPE_GROUP'
| 10
| 'TYPE_MESSAGE'
| 11
| 'TYPE_BYTES'
| 12
| 'TYPE_UINT32'
| 13
| 'TYPE_ENUM'
| 14
| 'TYPE_SFIXED32'
| 15
| 'TYPE_SFIXED64'
| 16
| 'TYPE_SINT32'
| 17
| 'TYPE_SINT64'
| 18
export type O_google_protobuf_FieldDescriptorProto_Type = typeof _google_protobuf_FieldDescriptorProto_Type[keyof typeof _google_protobuf_FieldDescriptorProto_Type]
export interface IFieldDescriptorProto {
'name'?: (string);
'extendee'?: (string);
'number'?: (number);
'label'?: (_google_protobuf_FieldDescriptorProto_Label | keyof typeof _google_protobuf_FieldDescriptorProto_Label);
'type'?: (_google_protobuf_FieldDescriptorProto_Type | keyof typeof _google_protobuf_FieldDescriptorProto_Type);
'label'?: (I_google_protobuf_FieldDescriptorProto_Label);
'type'?: (I_google_protobuf_FieldDescriptorProto_Type);
'typeName'?: (string);
'defaultValue'?: (string);
'options'?: (I_google_protobuf_FieldOptions | null);
@ -50,8 +100,8 @@ export interface OFieldDescriptorProto {
'name': (string);
'extendee': (string);
'number': (number);
'label': (keyof typeof _google_protobuf_FieldDescriptorProto_Label);
'type': (keyof typeof _google_protobuf_FieldDescriptorProto_Type);
'label': (O_google_protobuf_FieldDescriptorProto_Label);
'type': (O_google_protobuf_FieldDescriptorProto_Type);
'typeName': (string);
'defaultValue': (string);
'options': (O_google_protobuf_FieldOptions | null);

View File

@ -1,42 +1,62 @@
// Original file: null
import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption';
import type { FieldBehavior as _google_api_FieldBehavior } from '../../google/api/FieldBehavior';
import type { IFieldBehavior as I_google_api_FieldBehavior, OFieldBehavior as O_google_api_FieldBehavior } from '../../google/api/FieldBehavior';
// Original file: null
export enum _google_protobuf_FieldOptions_CType {
STRING = 0,
CORD = 1,
STRING_PIECE = 2,
}
export const _google_protobuf_FieldOptions_CType = {
STRING: 'STRING',
CORD: 'CORD',
STRING_PIECE: 'STRING_PIECE',
} as const;
export type I_google_protobuf_FieldOptions_CType =
| 'STRING'
| 0
| 'CORD'
| 1
| 'STRING_PIECE'
| 2
export type O_google_protobuf_FieldOptions_CType = typeof _google_protobuf_FieldOptions_CType[keyof typeof _google_protobuf_FieldOptions_CType]
// Original file: null
export enum _google_protobuf_FieldOptions_JSType {
JS_NORMAL = 0,
JS_STRING = 1,
JS_NUMBER = 2,
}
export const _google_protobuf_FieldOptions_JSType = {
JS_NORMAL: 'JS_NORMAL',
JS_STRING: 'JS_STRING',
JS_NUMBER: 'JS_NUMBER',
} as const;
export type I_google_protobuf_FieldOptions_JSType =
| 'JS_NORMAL'
| 0
| 'JS_STRING'
| 1
| 'JS_NUMBER'
| 2
export type O_google_protobuf_FieldOptions_JSType = typeof _google_protobuf_FieldOptions_JSType[keyof typeof _google_protobuf_FieldOptions_JSType]
export interface IFieldOptions {
'ctype'?: (_google_protobuf_FieldOptions_CType | keyof typeof _google_protobuf_FieldOptions_CType);
'ctype'?: (I_google_protobuf_FieldOptions_CType);
'packed'?: (boolean);
'deprecated'?: (boolean);
'lazy'?: (boolean);
'jstype'?: (_google_protobuf_FieldOptions_JSType | keyof typeof _google_protobuf_FieldOptions_JSType);
'jstype'?: (I_google_protobuf_FieldOptions_JSType);
'weak'?: (boolean);
'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[];
'.google.api.field_behavior'?: (_google_api_FieldBehavior | keyof typeof _google_api_FieldBehavior)[];
'.google.api.field_behavior'?: (I_google_api_FieldBehavior)[];
}
export interface OFieldOptions {
'ctype': (keyof typeof _google_protobuf_FieldOptions_CType);
'ctype': (O_google_protobuf_FieldOptions_CType);
'packed': (boolean);
'deprecated': (boolean);
'lazy': (boolean);
'jstype': (keyof typeof _google_protobuf_FieldOptions_JSType);
'jstype': (O_google_protobuf_FieldOptions_JSType);
'weak': (boolean);
'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[];
'.google.api.field_behavior': (keyof typeof _google_api_FieldBehavior)[];
'.google.api.field_behavior': (O_google_api_FieldBehavior)[];
}

View File

@ -4,16 +4,26 @@ import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUn
// Original file: null
export enum _google_protobuf_FileOptions_OptimizeMode {
SPEED = 1,
CODE_SIZE = 2,
LITE_RUNTIME = 3,
}
export const _google_protobuf_FileOptions_OptimizeMode = {
SPEED: 'SPEED',
CODE_SIZE: 'CODE_SIZE',
LITE_RUNTIME: 'LITE_RUNTIME',
} as const;
export type I_google_protobuf_FileOptions_OptimizeMode =
| 'SPEED'
| 1
| 'CODE_SIZE'
| 2
| 'LITE_RUNTIME'
| 3
export type O_google_protobuf_FileOptions_OptimizeMode = typeof _google_protobuf_FileOptions_OptimizeMode[keyof typeof _google_protobuf_FileOptions_OptimizeMode]
export interface IFileOptions {
'javaPackage'?: (string);
'javaOuterClassname'?: (string);
'optimizeFor'?: (_google_protobuf_FileOptions_OptimizeMode | keyof typeof _google_protobuf_FileOptions_OptimizeMode);
'optimizeFor'?: (I_google_protobuf_FileOptions_OptimizeMode);
'javaMultipleFiles'?: (boolean);
'goPackage'?: (string);
'ccGenericServices'?: (boolean);
@ -31,7 +41,7 @@ export interface IFileOptions {
export interface OFileOptions {
'javaPackage': (string);
'javaOuterClassname': (string);
'optimizeFor': (keyof typeof _google_protobuf_FileOptions_OptimizeMode);
'optimizeFor': (O_google_protobuf_FileOptions_OptimizeMode);
'javaMultipleFiles': (boolean);
'goPackage': (string);
'ccGenericServices': (boolean);

View File

@ -1,7 +1,7 @@
// Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto
import type { IStatus as I_google_rpc_Status, OStatus as O_google_rpc_Status } from '../../../google/rpc/Status';
import type { Severity as _google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity';
import type { ISeverity as I_google_showcase_v1beta1_Severity, OSeverity as O_google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity';
/**
* The request message used for the Echo, Collect and Chat methods.
@ -21,7 +21,7 @@ export interface IEchoRequest {
/**
* The severity to be echoed by the server.
*/
'severity'?: (_google_showcase_v1beta1_Severity | keyof typeof _google_showcase_v1beta1_Severity);
'severity'?: (I_google_showcase_v1beta1_Severity);
'response'?: "content"|"error";
}
@ -43,6 +43,6 @@ export interface OEchoRequest {
/**
* The severity to be echoed by the server.
*/
'severity': (keyof typeof _google_showcase_v1beta1_Severity);
'severity': (O_google_showcase_v1beta1_Severity);
'response': "content"|"error";
}

View File

@ -1,6 +1,6 @@
// Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto
import type { Severity as _google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity';
import type { ISeverity as I_google_showcase_v1beta1_Severity, OSeverity as O_google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity';
/**
* The response message for the Echo methods.
@ -13,7 +13,7 @@ export interface IEchoResponse {
/**
* The severity specified in the request.
*/
'severity'?: (_google_showcase_v1beta1_Severity | keyof typeof _google_showcase_v1beta1_Severity);
'severity'?: (I_google_showcase_v1beta1_Severity);
}
/**
@ -27,5 +27,5 @@ export interface OEchoResponse {
/**
* The severity specified in the request.
*/
'severity': (keyof typeof _google_showcase_v1beta1_Severity);
'severity': (O_google_showcase_v1beta1_Severity);
}

View File

@ -3,9 +3,27 @@
/**
* A severity enum used to test enum capabilities in GAPIC surfaces
*/
export enum Severity {
UNNECESSARY = 0,
NECESSARY = 1,
URGENT = 2,
CRITICAL = 3,
}
export const Severity = {
UNNECESSARY: 'UNNECESSARY',
NECESSARY: 'NECESSARY',
URGENT: 'URGENT',
CRITICAL: 'CRITICAL',
} as const;
/**
* A severity enum used to test enum capabilities in GAPIC surfaces
*/
export type ISeverity =
| 'UNNECESSARY'
| 0
| 'NECESSARY'
| 1
| 'URGENT'
| 2
| 'CRITICAL'
| 3
/**
* A severity enum used to test enum capabilities in GAPIC surfaces
*/
export type OSeverity = typeof Severity[keyof typeof Severity]