Skip to content

Commit 8bee12e

Browse files
authored
Merge pull request #2276 from install/avoidTsEnums
proto-loader-gen-types Avoid TS enums
2 parents 89e132a + ef7b8e8 commit 8bee12e

File tree

8 files changed

+266
-88
lines changed

8 files changed

+266
-88
lines changed

packages/proto-loader/bin/proto-loader-gen-types.ts

+34-15
Original file line numberDiff line numberDiff line change
@@ -135,20 +135,16 @@ function getImportLine(dependency: Protobuf.Type | Protobuf.Enum | Protobuf.Serv
135135
/* If the dependency is defined within a message, it will be generated in that
136136
* message's file and exported using its typeInterfaceName. */
137137
if (dependency.parent instanceof Protobuf.Type) {
138-
if (dependency instanceof Protobuf.Type) {
138+
if (dependency instanceof Protobuf.Type || dependency instanceof Protobuf.Enum) {
139139
importedTypes = `${inputName(typeInterfaceName)}, ${outputName(typeInterfaceName)}`;
140-
} else if (dependency instanceof Protobuf.Enum) {
141-
importedTypes = `${typeInterfaceName}`;
142140
} else if (dependency instanceof Protobuf.Service) {
143141
importedTypes = `${typeInterfaceName}Client, ${typeInterfaceName}Definition`;
144142
} else {
145143
throw new Error('Invalid object passed to getImportLine');
146144
}
147145
} else {
148-
if (dependency instanceof Protobuf.Type) {
146+
if (dependency instanceof Protobuf.Type || dependency instanceof Protobuf.Enum) {
149147
importedTypes = `${inputName(dependency.name)} as ${inputName(typeInterfaceName)}, ${outputName(dependency.name)} as ${outputName(typeInterfaceName)}`;
150-
} else if (dependency instanceof Protobuf.Enum) {
151-
importedTypes = `${dependency.name} as ${typeInterfaceName}`;
152148
} else if (dependency instanceof Protobuf.Service) {
153149
importedTypes = `${dependency.name}Client as ${typeInterfaceName}Client, ${dependency.name}Definition as ${typeInterfaceName}Definition`;
154150
} else {
@@ -220,7 +216,8 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type |
220216
return `${inputName(typeInterfaceName)} | null`;
221217
}
222218
} else {
223-
return `${typeInterfaceName} | keyof typeof ${typeInterfaceName}`;
219+
// Enum
220+
return inputName(typeInterfaceName);
224221
}
225222
}
226223
}
@@ -324,11 +321,8 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type |
324321
return `${outputName(typeInterfaceName)}`;
325322
}
326323
} else {
327-
if (options.enums == String) {
328-
return `keyof typeof ${typeInterfaceName}`;
329-
} else {
330-
return typeInterfaceName;
331-
}
324+
// Enum
325+
return outputName(typeInterfaceName);
332326
}
333327
}
334328
}
@@ -455,21 +449,46 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob
455449
}
456450

457451
function generateEnumInterface(formatter: TextFormatter, enumType: Protobuf.Enum, options: GeneratorOptions, nameOverride?: string) {
452+
const {inputName, outputName} = useNameFmter(options);
453+
const name = nameOverride ?? enumType.name;
458454
formatter.writeLine(`// Original file: ${(enumType.filename ?? 'null')?.replace(/\\/g, '/')}`);
459455
formatter.writeLine('');
460456
if (options.includeComments) {
461457
formatComment(formatter, enumType.comment);
462458
}
463-
formatter.writeLine(`export enum ${nameOverride ?? enumType.name} {`);
459+
formatter.writeLine(`export const ${name} = {`);
464460
formatter.indent();
465461
for (const key of Object.keys(enumType.values)) {
466462
if (options.includeComments) {
467463
formatComment(formatter, enumType.comments[key]);
468464
}
469-
formatter.writeLine(`${key} = ${enumType.values[key]},`);
465+
formatter.writeLine(`${key}: ${options.enums == String ? `'${key}'` : enumType.values[key]},`);
470466
}
471467
formatter.unindent();
472-
formatter.writeLine('}');
468+
formatter.writeLine('} as const;');
469+
470+
// Permissive Type
471+
formatter.writeLine('');
472+
if (options.includeComments) {
473+
formatComment(formatter, enumType.comment);
474+
}
475+
formatter.writeLine(`export type ${inputName(name)} =`)
476+
formatter.indent();
477+
for (const key of Object.keys(enumType.values)) {
478+
if (options.includeComments) {
479+
formatComment(formatter, enumType.comments[key]);
480+
}
481+
formatter.writeLine(`| '${key}'`);
482+
formatter.writeLine(`| ${enumType.values[key]}`);
483+
}
484+
formatter.unindent();
485+
486+
// Restrictive Type
487+
formatter.writeLine('');
488+
if (options.includeComments) {
489+
formatComment(formatter, enumType.comment);
490+
}
491+
formatter.writeLine(`export type ${outputName(name)} = typeof ${name}[keyof typeof ${name}]`)
473492
}
474493

475494
/**

packages/proto-loader/golden-generated/google/api/FieldBehavior.ts

+69-8
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,101 @@
88
*
99
* Note: This enum **may** receive new values in the future.
1010
*/
11-
export enum FieldBehavior {
11+
export const FieldBehavior = {
1212
/**
1313
* Conventional default for enums. Do not use this.
1414
*/
15-
FIELD_BEHAVIOR_UNSPECIFIED = 0,
15+
FIELD_BEHAVIOR_UNSPECIFIED: 'FIELD_BEHAVIOR_UNSPECIFIED',
1616
/**
1717
* Specifically denotes a field as optional.
1818
* While all fields in protocol buffers are optional, this may be specified
1919
* for emphasis if appropriate.
2020
*/
21-
OPTIONAL = 1,
21+
OPTIONAL: 'OPTIONAL',
2222
/**
2323
* Denotes a field as required.
2424
* This indicates that the field **must** be provided as part of the request,
2525
* and failure to do so will cause an error (usually `INVALID_ARGUMENT`).
2626
*/
27-
REQUIRED = 2,
27+
REQUIRED: 'REQUIRED',
2828
/**
2929
* Denotes a field as output only.
3030
* This indicates that the field is provided in responses, but including the
3131
* field in a request does nothing (the server *must* ignore it and
3232
* *must not* throw an error as a result of the field's presence).
3333
*/
34-
OUTPUT_ONLY = 3,
34+
OUTPUT_ONLY: 'OUTPUT_ONLY',
3535
/**
3636
* Denotes a field as input only.
3737
* This indicates that the field is provided in requests, and the
3838
* corresponding field is not included in output.
3939
*/
40-
INPUT_ONLY = 4,
40+
INPUT_ONLY: 'INPUT_ONLY',
4141
/**
4242
* Denotes a field as immutable.
4343
* This indicates that the field may be set once in a request to create a
4444
* resource, but may not be changed thereafter.
4545
*/
46-
IMMUTABLE = 5,
47-
}
46+
IMMUTABLE: 'IMMUTABLE',
47+
} as const;
48+
49+
/**
50+
* An indicator of the behavior of a given field (for example, that a field
51+
* is required in requests, or given as output but ignored as input).
52+
* This **does not** change the behavior in protocol buffers itself; it only
53+
* denotes the behavior and may affect how API tooling handles the field.
54+
*
55+
* Note: This enum **may** receive new values in the future.
56+
*/
57+
export type IFieldBehavior =
58+
/**
59+
* Conventional default for enums. Do not use this.
60+
*/
61+
| 'FIELD_BEHAVIOR_UNSPECIFIED'
62+
| 0
63+
/**
64+
* Specifically denotes a field as optional.
65+
* While all fields in protocol buffers are optional, this may be specified
66+
* for emphasis if appropriate.
67+
*/
68+
| 'OPTIONAL'
69+
| 1
70+
/**
71+
* Denotes a field as required.
72+
* This indicates that the field **must** be provided as part of the request,
73+
* and failure to do so will cause an error (usually `INVALID_ARGUMENT`).
74+
*/
75+
| 'REQUIRED'
76+
| 2
77+
/**
78+
* Denotes a field as output only.
79+
* This indicates that the field is provided in responses, but including the
80+
* field in a request does nothing (the server *must* ignore it and
81+
* *must not* throw an error as a result of the field's presence).
82+
*/
83+
| 'OUTPUT_ONLY'
84+
| 3
85+
/**
86+
* Denotes a field as input only.
87+
* This indicates that the field is provided in requests, and the
88+
* corresponding field is not included in output.
89+
*/
90+
| 'INPUT_ONLY'
91+
| 4
92+
/**
93+
* Denotes a field as immutable.
94+
* This indicates that the field may be set once in a request to create a
95+
* resource, but may not be changed thereafter.
96+
*/
97+
| 'IMMUTABLE'
98+
| 5
99+
100+
/**
101+
* An indicator of the behavior of a given field (for example, that a field
102+
* is required in requests, or given as output but ignored as input).
103+
* This **does not** change the behavior in protocol buffers itself; it only
104+
* denotes the behavior and may affect how API tooling handles the field.
105+
*
106+
* Note: This enum **may** receive new values in the future.
107+
*/
108+
export type OFieldBehavior = typeof FieldBehavior[keyof typeof FieldBehavior]

packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts

+79-29
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,91 @@ import type { IFieldOptions as I_google_protobuf_FieldOptions, OFieldOptions as
44

55
// Original file: null
66

7-
export enum _google_protobuf_FieldDescriptorProto_Label {
8-
LABEL_OPTIONAL = 1,
9-
LABEL_REQUIRED = 2,
10-
LABEL_REPEATED = 3,
11-
}
7+
export const _google_protobuf_FieldDescriptorProto_Label = {
8+
LABEL_OPTIONAL: 'LABEL_OPTIONAL',
9+
LABEL_REQUIRED: 'LABEL_REQUIRED',
10+
LABEL_REPEATED: 'LABEL_REPEATED',
11+
} as const;
12+
13+
export type I_google_protobuf_FieldDescriptorProto_Label =
14+
| 'LABEL_OPTIONAL'
15+
| 1
16+
| 'LABEL_REQUIRED'
17+
| 2
18+
| 'LABEL_REPEATED'
19+
| 3
20+
21+
export type O_google_protobuf_FieldDescriptorProto_Label = typeof _google_protobuf_FieldDescriptorProto_Label[keyof typeof _google_protobuf_FieldDescriptorProto_Label]
1222

1323
// Original file: null
1424

15-
export enum _google_protobuf_FieldDescriptorProto_Type {
16-
TYPE_DOUBLE = 1,
17-
TYPE_FLOAT = 2,
18-
TYPE_INT64 = 3,
19-
TYPE_UINT64 = 4,
20-
TYPE_INT32 = 5,
21-
TYPE_FIXED64 = 6,
22-
TYPE_FIXED32 = 7,
23-
TYPE_BOOL = 8,
24-
TYPE_STRING = 9,
25-
TYPE_GROUP = 10,
26-
TYPE_MESSAGE = 11,
27-
TYPE_BYTES = 12,
28-
TYPE_UINT32 = 13,
29-
TYPE_ENUM = 14,
30-
TYPE_SFIXED32 = 15,
31-
TYPE_SFIXED64 = 16,
32-
TYPE_SINT32 = 17,
33-
TYPE_SINT64 = 18,
34-
}
25+
export const _google_protobuf_FieldDescriptorProto_Type = {
26+
TYPE_DOUBLE: 'TYPE_DOUBLE',
27+
TYPE_FLOAT: 'TYPE_FLOAT',
28+
TYPE_INT64: 'TYPE_INT64',
29+
TYPE_UINT64: 'TYPE_UINT64',
30+
TYPE_INT32: 'TYPE_INT32',
31+
TYPE_FIXED64: 'TYPE_FIXED64',
32+
TYPE_FIXED32: 'TYPE_FIXED32',
33+
TYPE_BOOL: 'TYPE_BOOL',
34+
TYPE_STRING: 'TYPE_STRING',
35+
TYPE_GROUP: 'TYPE_GROUP',
36+
TYPE_MESSAGE: 'TYPE_MESSAGE',
37+
TYPE_BYTES: 'TYPE_BYTES',
38+
TYPE_UINT32: 'TYPE_UINT32',
39+
TYPE_ENUM: 'TYPE_ENUM',
40+
TYPE_SFIXED32: 'TYPE_SFIXED32',
41+
TYPE_SFIXED64: 'TYPE_SFIXED64',
42+
TYPE_SINT32: 'TYPE_SINT32',
43+
TYPE_SINT64: 'TYPE_SINT64',
44+
} as const;
45+
46+
export type I_google_protobuf_FieldDescriptorProto_Type =
47+
| 'TYPE_DOUBLE'
48+
| 1
49+
| 'TYPE_FLOAT'
50+
| 2
51+
| 'TYPE_INT64'
52+
| 3
53+
| 'TYPE_UINT64'
54+
| 4
55+
| 'TYPE_INT32'
56+
| 5
57+
| 'TYPE_FIXED64'
58+
| 6
59+
| 'TYPE_FIXED32'
60+
| 7
61+
| 'TYPE_BOOL'
62+
| 8
63+
| 'TYPE_STRING'
64+
| 9
65+
| 'TYPE_GROUP'
66+
| 10
67+
| 'TYPE_MESSAGE'
68+
| 11
69+
| 'TYPE_BYTES'
70+
| 12
71+
| 'TYPE_UINT32'
72+
| 13
73+
| 'TYPE_ENUM'
74+
| 14
75+
| 'TYPE_SFIXED32'
76+
| 15
77+
| 'TYPE_SFIXED64'
78+
| 16
79+
| 'TYPE_SINT32'
80+
| 17
81+
| 'TYPE_SINT64'
82+
| 18
83+
84+
export type O_google_protobuf_FieldDescriptorProto_Type = typeof _google_protobuf_FieldDescriptorProto_Type[keyof typeof _google_protobuf_FieldDescriptorProto_Type]
3585

3686
export interface IFieldDescriptorProto {
3787
'name'?: (string);
3888
'extendee'?: (string);
3989
'number'?: (number);
40-
'label'?: (_google_protobuf_FieldDescriptorProto_Label | keyof typeof _google_protobuf_FieldDescriptorProto_Label);
41-
'type'?: (_google_protobuf_FieldDescriptorProto_Type | keyof typeof _google_protobuf_FieldDescriptorProto_Type);
90+
'label'?: (I_google_protobuf_FieldDescriptorProto_Label);
91+
'type'?: (I_google_protobuf_FieldDescriptorProto_Type);
4292
'typeName'?: (string);
4393
'defaultValue'?: (string);
4494
'options'?: (I_google_protobuf_FieldOptions | null);
@@ -50,8 +100,8 @@ export interface OFieldDescriptorProto {
50100
'name': (string);
51101
'extendee': (string);
52102
'number': (number);
53-
'label': (keyof typeof _google_protobuf_FieldDescriptorProto_Label);
54-
'type': (keyof typeof _google_protobuf_FieldDescriptorProto_Type);
103+
'label': (O_google_protobuf_FieldDescriptorProto_Label);
104+
'type': (O_google_protobuf_FieldDescriptorProto_Type);
55105
'typeName': (string);
56106
'defaultValue': (string);
57107
'options': (O_google_protobuf_FieldOptions | null);

0 commit comments

Comments
 (0)