diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index bb5b35f8..a9ee4a6e 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -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}]`) } /** diff --git a/packages/proto-loader/golden-generated/google/api/FieldBehavior.ts b/packages/proto-loader/golden-generated/google/api/FieldBehavior.ts index 8ab67670..189d25be 100644 --- a/packages/proto-loader/golden-generated/google/api/FieldBehavior.ts +++ b/packages/proto-loader/golden-generated/google/api/FieldBehavior.ts @@ -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] diff --git a/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts index 0a713e9d..1bcb69ab 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts @@ -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); diff --git a/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts index 076b3598..16e532d9 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts @@ -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)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts index 2b832e0f..fdeac9cd 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts @@ -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); diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts index 649a5d50..a5fb8f76 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts @@ -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"; } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts index 96b7ba25..ac50115b 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts @@ -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); } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Severity.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Severity.ts index fc3fe641..d109fe1c 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Severity.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Severity.ts @@ -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]