ts-proto 1.178.0 → 1.180.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.markdown CHANGED
@@ -551,6 +551,8 @@ Generated code will be placed in the Gradle build directory.
551
551
 
552
552
  - With `--ts_proto_opt=comments=false`, comments won't be copied from the proto files to the generated code.
553
553
 
554
+ - With `--ts_proto_opt=bigIntLiteral=false`, the generated code will use `BigInt("0")` instead of `0n` for BigInt literals. BigInt literals aren't supported by TypeScript when the "target" compiler option set to something older than "ES2020".
555
+
554
556
  - With `--ts_proto_opt=useNullAsOptional=true`, `undefined` values will be converted to `null`, and if you use `optional` label in your `.proto` file, the field will have `undefined` type as well. for example:
555
557
 
556
558
  ```protobuf
@@ -603,7 +605,7 @@ export interface User {
603
605
  }
604
606
  ```
605
607
 
606
- - With `--ts_proto_opt=noDefaultsForOptionals=true`, `undefined` primitive values will not be defaulted as per the protobuf spec. Additionally unlike the standard behavior, when a field is set to it's standard default value, it *will* be encoded allowing it to be sent over the wire and distinguished from undefined values. For example if a message does not set a boolean value, ordinarily this would be defaulted to `false` which is different to it being undefined.
608
+ - With `--ts_proto_opt=noDefaultsForOptionals=true`, `undefined` primitive values will not be defaulted as per the protobuf spec. Additionally unlike the standard behavior, when a field is set to it's standard default value, it *will* be encoded allowing it to be sent over the wire and distinguished from undefined values. For example if a message does not set a boolean value, ordinarily this would be defaulted to `false` which is different to it being undefined.
607
609
 
608
610
  This option allows the library to act in a compatible way with the [Wire implementation](https://square.github.io/wire/) maintained and used by Square/Block. Note: this option should only be used in combination with other client/server code generated using Wire or ts-proto with this option enabled.
609
611
 
@@ -752,7 +754,7 @@ ts-protoc --ts_proto_out=./output -I=./protos ./protoc/*.proto
752
754
  # Todo
753
755
 
754
756
  - Support the string-based encoding of duration in `fromJSON`/`toJSON`
755
- - Make `oneof=unions` the default behavior in 2.0
757
+ - Make `oneof=unions-value` the default behavior in 2.0
756
758
  - Probably change `forceLong` default in 2.0, should default to `forceLong=long`
757
759
  - Make `esModuleInterop=true` the default in 2.0
758
760
 
@@ -770,11 +772,11 @@ Will generate a `Foo` type with two fields: `field_a: string | undefined;` and `
770
772
 
771
773
  With this output, you'll have to check both `if object.field_a` and `if object.field_b`, and if you set one, you'll have to remember to unset the other.
772
774
 
773
- Instead, we recommend using the `oneof=unions` option, which will change the output to be an Abstract Data Type/ADT like:
775
+ Instead, we recommend using the `oneof=unions-value` option, which will change the output to be an Abstract Data Type/ADT like:
774
776
 
775
777
  ```typescript
776
778
  interface YourMessage {
777
- eitherField?: { $case: "field_a"; field_a: string } | { $case: "field_b"; field_b: string };
779
+ eitherField?: { $case: "field_a"; value: string } | { $case: "field_b"; value: string };
778
780
  }
779
781
  ```
780
782
 
@@ -782,11 +784,21 @@ As this will automatically enforce only one of `field_a` or `field_b` "being set
782
784
 
783
785
  (Note that `eitherField` is optional b/c `oneof` in Protobuf means "at most one field" is set, and does not mean one of the fields _must_ be set.)
784
786
 
785
- In ts-proto's currently-unscheduled 2.x release, `oneof=unions` will become the default behavior.
787
+ In ts-proto's currently-unscheduled 2.x release, `oneof=unions-value` will become the default behavior.
788
+
789
+ There is also a `oneof=unions` option, which generates a union where the field names are included in each option:
790
+
791
+ ```typescript
792
+ interface YourMessage {
793
+ eitherField?: { $case: "field_a"; field_a: string } | { $case: "field_b"; field_b: string };
794
+ }
795
+ ```
796
+
797
+ This is no longer recommended as it can be difficult to write code and types to handle multiple oneof options:
786
798
 
787
799
  ## OneOf Type Helpers
788
800
 
789
- The following helper types may make it easier to work with the types generated from `oneof=unions`:
801
+ The following helper types may make it easier to work with the types generated from `oneof=unions`, though they are generally not needed if you use `oneof=unions-value`:
790
802
 
791
803
  ```ts
792
804
  /** Extracts all the case names from a oneOf field. */
@@ -797,19 +809,45 @@ type OneOfValues<T> = T extends { $case: infer U extends string; [key: string]:
797
809
 
798
810
  /** Extracts the specific type of a oneOf case based on its field name */
799
811
  type OneOfCase<T, K extends OneOfCases<T>> = T extends {
812
+ $case: K;
813
+ [key: string]: unknown;
814
+ }
815
+ ? T
816
+ : never;
817
+
818
+ /** Extracts the specific type of a value type from a oneOf field */
819
+ type OneOfValue<T, K extends OneOfCases<T>> = T extends {
800
820
  $case: infer U extends K;
801
821
  [key: string]: unknown;
802
822
  }
803
823
  ? T[U]
804
824
  : never;
825
+ ```
805
826
 
806
- /** Extracts the specific type of a value type from a oneOf field */
807
- export type OneOfValue<T, K extends OneOfCases<T>> = T extends {
827
+ For comparison, the equivalents for `oneof=unions-value`:
828
+
829
+ ```ts
830
+ /** Extracts all the case names from a oneOf field. */
831
+ type OneOfCases<T> = T['$case'];
832
+
833
+ /** Extracts a union of all the value types from a oneOf field */
834
+ type OneOfValues<T> = T['value'];
835
+
836
+ /** Extracts the specific type of a oneOf case based on its field name */
837
+ type OneOfCase<T, K extends OneOfCases<T>> = T extends {
808
838
  $case: K;
809
839
  [key: string]: unknown;
810
840
  }
811
841
  ? T
812
842
  : never;
843
+
844
+ /** Extracts the specific type of a value type from a oneOf field */
845
+ type OneOfValue<T, K extends OneOfCases<T>> = T extends {
846
+ $case: infer U extends K;
847
+ value: unknown;
848
+ }
849
+ ? T[U]
850
+ : never;
813
851
  ```
814
852
 
815
853
  # Default values and unset fields
package/build/enums.js CHANGED
@@ -7,11 +7,10 @@ const case_1 = require("./case");
7
7
  const sourceInfo_1 = require("./sourceInfo");
8
8
  // Output the `enum { Foo, A = 0, B = 1 }`
9
9
  function generateEnum(ctx, fullName, enumDesc, sourceInfo) {
10
- var _a;
11
10
  const { options } = ctx;
12
11
  const chunks = [];
13
12
  let unrecognizedEnum = { present: false };
14
- (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, (_a = enumDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
13
+ (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, enumDesc.options?.deprecated);
15
14
  if (options.enumsAsLiterals) {
16
15
  chunks.push((0, ts_poet_1.code) `export const ${(0, ts_poet_1.def)(fullName)} = {`);
17
16
  }
@@ -20,14 +19,13 @@ function generateEnum(ctx, fullName, enumDesc, sourceInfo) {
20
19
  }
21
20
  const delimiter = options.enumsAsLiterals ? ":" : "=";
22
21
  enumDesc.value.forEach((valueDesc, index) => {
23
- var _a;
24
22
  const info = sourceInfo.lookup(sourceInfo_1.Fields.enum.value, index);
25
23
  const valueName = getValueName(ctx, fullName, valueDesc);
26
24
  const memberName = getMemberName(ctx, enumDesc, valueDesc);
27
25
  if (valueDesc.number === options.unrecognizedEnumValue) {
28
26
  unrecognizedEnum = { present: true, name: memberName };
29
27
  }
30
- (0, utils_1.maybeAddComment)(options, info, chunks, (_a = valueDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated, `${memberName} - `);
28
+ (0, utils_1.maybeAddComment)(options, info, chunks, valueDesc.options?.deprecated, `${memberName} - `);
31
29
  chunks.push((0, ts_poet_1.code) `${memberName} ${delimiter} ${options.stringEnums ? `"${valueName}"` : valueDesc.number.toString()},`);
32
30
  });
33
31
  if (options.unrecognizedEnum && !unrecognizedEnum.present) {
@@ -11,9 +11,8 @@ const utils_1 = require("./utils");
11
11
  * Generates a framework-agnostic service descriptor.
12
12
  */
13
13
  function generateGenericServiceDefinition(ctx, fileDesc, sourceInfo, serviceDesc) {
14
- var _a, _b, _c;
15
14
  const chunks = [];
16
- (0, utils_1.maybeAddComment)(ctx.options, sourceInfo, chunks, (_a = serviceDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
15
+ (0, utils_1.maybeAddComment)(ctx.options, sourceInfo, chunks, serviceDesc.options?.deprecated);
17
16
  // Service definition type
18
17
  const name = (0, ts_poet_1.def)(`${serviceDesc.name}Definition`);
19
18
  chunks.push((0, ts_poet_1.code) `
@@ -23,7 +22,7 @@ function generateGenericServiceDefinition(ctx, fileDesc, sourceInfo, serviceDesc
23
22
  chunks.push((0, ts_poet_1.code) `
24
23
  export const ${name} = {
25
24
  `);
26
- (_b = serviceDesc.options) === null || _b === void 0 ? void 0 : _b.uninterpretedOption;
25
+ serviceDesc.options?.uninterpretedOption;
27
26
  chunks.push((0, ts_poet_1.code) `
28
27
  name: '${serviceDesc.name}',
29
28
  fullName: '${(0, utils_1.maybePrefixPackage)(fileDesc, serviceDesc.name)}',
@@ -31,7 +30,7 @@ function generateGenericServiceDefinition(ctx, fileDesc, sourceInfo, serviceDesc
31
30
  `);
32
31
  for (const [index, methodDesc] of serviceDesc.method.entries()) {
33
32
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
34
- (0, utils_1.maybeAddComment)(ctx.options, info, chunks, (_c = methodDesc.options) === null || _c === void 0 ? void 0 : _c.deprecated);
33
+ (0, utils_1.maybeAddComment)(ctx.options, info, chunks, methodDesc.options?.deprecated);
35
34
  chunks.push((0, ts_poet_1.code) `
36
35
  ${(0, case_1.uncapitalize)(methodDesc.name)}: ${generateMethodDefinition(ctx, methodDesc)},
37
36
  `);
@@ -39,9 +39,8 @@ function generateGrpcJsService(ctx, fileDesc, sourceInfo, serviceDesc) {
39
39
  }
40
40
  exports.generateGrpcJsService = generateGrpcJsService;
41
41
  function generateServiceDefinition(ctx, fileDesc, sourceInfo, serviceDesc) {
42
- var _a, _b;
43
42
  const chunks = [];
44
- (0, utils_1.maybeAddComment)(ctx.options, sourceInfo, chunks, (_a = serviceDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
43
+ (0, utils_1.maybeAddComment)(ctx.options, sourceInfo, chunks, serviceDesc.options?.deprecated);
45
44
  // Service definition type
46
45
  const name = (0, ts_poet_1.def)(`${serviceDesc.name}Service`);
47
46
  chunks.push((0, ts_poet_1.code) `
@@ -56,7 +55,7 @@ function generateServiceDefinition(ctx, fileDesc, sourceInfo, serviceDesc) {
56
55
  const inputType = (0, types_1.messageToTypeName)(ctx, methodDesc.inputType);
57
56
  const outputType = (0, types_1.messageToTypeName)(ctx, methodDesc.outputType);
58
57
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
59
- (0, utils_1.maybeAddComment)(ctx.options, info, chunks, (_b = methodDesc.options) === null || _b === void 0 ? void 0 : _b.deprecated);
58
+ (0, utils_1.maybeAddComment)(ctx.options, info, chunks, methodDesc.options?.deprecated);
60
59
  const inputEncoder = (0, encode_1.generateEncoder)(ctx, methodDesc.inputType);
61
60
  const outputEncoder = (0, encode_1.generateEncoder)(ctx, methodDesc.outputType);
62
61
  const inputDecoder = (0, encode_1.generateDecoder)(ctx, methodDesc.inputType);
@@ -79,7 +78,6 @@ function generateServiceDefinition(ctx, fileDesc, sourceInfo, serviceDesc) {
79
78
  return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
80
79
  }
81
80
  function generateServerStub(ctx, sourceInfo, serviceDesc) {
82
- var _a;
83
81
  const chunks = [];
84
82
  chunks.push((0, ts_poet_1.code) `export interface ${(0, ts_poet_1.def)(`${serviceDesc.name}Server`)} extends ${UntypedServiceImplementation} {`);
85
83
  for (const [index, methodDesc] of serviceDesc.method.entries()) {
@@ -87,7 +85,7 @@ function generateServerStub(ctx, sourceInfo, serviceDesc) {
87
85
  const inputType = (0, types_1.messageToTypeName)(ctx, methodDesc.inputType);
88
86
  const outputType = (0, types_1.messageToTypeName)(ctx, methodDesc.outputType);
89
87
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
90
- (0, utils_1.maybeAddComment)(ctx.options, info, chunks, (_a = methodDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
88
+ (0, utils_1.maybeAddComment)(ctx.options, info, chunks, methodDesc.options?.deprecated);
91
89
  const callType = methodDesc.clientStreaming
92
90
  ? methodDesc.serverStreaming
93
91
  ? handleBidiStreamingCall
@@ -103,7 +101,6 @@ function generateServerStub(ctx, sourceInfo, serviceDesc) {
103
101
  return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
104
102
  }
105
103
  function generateClientStub(ctx, sourceInfo, serviceDesc) {
106
- var _a;
107
104
  const chunks = [];
108
105
  chunks.push((0, ts_poet_1.code) `export interface ${(0, ts_poet_1.def)(`${serviceDesc.name}Client`)} extends ${Client} {`);
109
106
  for (const [index, methodDesc] of serviceDesc.method.entries()) {
@@ -111,7 +108,7 @@ function generateClientStub(ctx, sourceInfo, serviceDesc) {
111
108
  const inputType = (0, types_1.messageToTypeName)(ctx, methodDesc.inputType);
112
109
  const outputType = (0, types_1.messageToTypeName)(ctx, methodDesc.outputType);
113
110
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
114
- (0, utils_1.maybeAddComment)(ctx.options, info, chunks, (_a = methodDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
111
+ (0, utils_1.maybeAddComment)(ctx.options, info, chunks, methodDesc.options?.deprecated);
115
112
  const responseCallback = (0, ts_poet_1.code) `(error: ${ServiceError} | null, response: ${outputType}) => void`;
116
113
  if (methodDesc.clientStreaming) {
117
114
  if (methodDesc.serverStreaming) {
@@ -7,20 +7,18 @@ const sourceInfo_1 = require("./sourceInfo");
7
7
  const main_1 = require("./main");
8
8
  const utils_1 = require("./utils");
9
9
  function generateNestjsServiceController(ctx, fileDesc, sourceInfo, serviceDesc) {
10
- var _a;
11
10
  const { options } = ctx;
12
11
  const chunks = [];
13
12
  const Metadata = (0, ts_poet_1.imp)("Metadata@@grpc/grpc-js");
14
- (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, (_a = serviceDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
13
+ (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, serviceDesc.options?.deprecated);
15
14
  const t = options.context ? `<${main_1.contextTypeVar}>` : "";
16
15
  chunks.push((0, ts_poet_1.code) `
17
16
  export interface ${serviceDesc.name}Controller${t} {
18
17
  `);
19
18
  serviceDesc.method.forEach((methodDesc, index) => {
20
- var _a;
21
19
  (0, utils_1.assertInstanceOf)(methodDesc, utils_1.FormattedMethodDescriptor);
22
20
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
23
- (0, utils_1.maybeAddComment)(options, info, chunks, (_a = serviceDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
21
+ (0, utils_1.maybeAddComment)(options, info, chunks, serviceDesc.options?.deprecated);
24
22
  const params = [];
25
23
  if (options.context) {
26
24
  params.push((0, ts_poet_1.code) `ctx: Context`);
@@ -80,7 +78,6 @@ function generateNestjsServiceClient(ctx, fileDesc, sourceInfo, serviceDesc) {
80
78
  export interface ${serviceDesc.name}Client${t} {
81
79
  `);
82
80
  serviceDesc.method.forEach((methodDesc, index) => {
83
- var _a;
84
81
  (0, utils_1.assertInstanceOf)(methodDesc, utils_1.FormattedMethodDescriptor);
85
82
  const params = [];
86
83
  if (options.context) {
@@ -98,7 +95,7 @@ function generateNestjsServiceClient(ctx, fileDesc, sourceInfo, serviceDesc) {
98
95
  // Return observable since nestjs client always returns an Observable
99
96
  const returns = (0, types_1.responseObservable)(ctx, methodDesc);
100
97
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
101
- (0, utils_1.maybeAddComment)(options, info, chunks, (_a = methodDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
98
+ (0, utils_1.maybeAddComment)(options, info, chunks, methodDesc.options?.deprecated);
102
99
  chunks.push((0, ts_poet_1.code) `
103
100
  ${methodDesc.formattedName}(
104
101
  ${(0, ts_poet_1.joinCode)(params, { on: "," })}
@@ -19,7 +19,6 @@ function generateNiceGrpcService(ctx, fileDesc, sourceInfo, serviceDesc) {
19
19
  }
20
20
  exports.generateNiceGrpcService = generateNiceGrpcService;
21
21
  function generateServerStub(ctx, sourceInfo, serviceDesc) {
22
- var _a;
23
22
  const chunks = [];
24
23
  const maybeSuffix = serviceDesc.name.endsWith("Service") ? "" : "Service";
25
24
  chunks.push((0, ts_poet_1.code) `export interface ${(0, ts_poet_1.def)(`${serviceDesc.name}${maybeSuffix}Implementation`)}<CallContextExt = {}> {`);
@@ -32,7 +31,7 @@ function generateServerStub(ctx, sourceInfo, serviceDesc) {
32
31
  }
33
32
  const ServerStreamingMethodResult = ctx.utils.NiceGrpcServerStreamingMethodResult;
34
33
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
35
- (0, utils_1.maybeAddComment)(ctx.options, info, chunks, (_a = methodDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
34
+ (0, utils_1.maybeAddComment)(ctx.options, info, chunks, methodDesc.options?.deprecated);
36
35
  if (methodDesc.clientStreaming) {
37
36
  if (methodDesc.serverStreaming) {
38
37
  // bidi streaming
@@ -78,7 +77,6 @@ function generateServerStub(ctx, sourceInfo, serviceDesc) {
78
77
  return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
79
78
  }
80
79
  function generateClientStub(ctx, sourceInfo, serviceDesc) {
81
- var _a;
82
80
  const chunks = [];
83
81
  chunks.push((0, ts_poet_1.code) `export interface ${(0, ts_poet_1.def)(`${serviceDesc.name}Client`)}<CallOptionsExt = {}> {`);
84
82
  for (const [index, methodDesc] of serviceDesc.method.entries()) {
@@ -89,7 +87,7 @@ function generateClientStub(ctx, sourceInfo, serviceDesc) {
89
87
  }
90
88
  const outputType = (0, types_1.messageToTypeName)(ctx, methodDesc.outputType, { keepValueType: true });
91
89
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
92
- (0, utils_1.maybeAddComment)(ctx.options, info, chunks, (_a = methodDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
90
+ (0, utils_1.maybeAddComment)(ctx.options, info, chunks, methodDesc.options?.deprecated);
93
91
  if (methodDesc.clientStreaming) {
94
92
  if (methodDesc.serverStreaming) {
95
93
  // bidi streaming
@@ -17,17 +17,15 @@ const main_1 = require("./main");
17
17
  * vs. server-side code/interfaces are handled separately.
18
18
  */
19
19
  function generateService(ctx, fileDesc, sourceInfo, serviceDesc) {
20
- var _a;
21
20
  const { options } = ctx;
22
21
  const chunks = [];
23
- (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, (_a = serviceDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
22
+ (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, serviceDesc.options?.deprecated);
24
23
  const maybeTypeVar = options.context ? `<${main_1.contextTypeVar}>` : "";
25
24
  chunks.push((0, ts_poet_1.code) `export interface ${(0, ts_poet_1.def)(serviceDesc.name)}${maybeTypeVar} {`);
26
25
  serviceDesc.method.forEach((methodDesc, index) => {
27
- var _a;
28
26
  (0, utils_1.assertInstanceOf)(methodDesc, utils_1.FormattedMethodDescriptor);
29
27
  const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
30
- (0, utils_1.maybeAddComment)(options, info, chunks, (_a = methodDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
28
+ (0, utils_1.maybeAddComment)(options, info, chunks, methodDesc.options?.deprecated);
31
29
  const params = [];
32
30
  if (options.context) {
33
31
  params.push((0, ts_poet_1.code) `ctx: Context`);
@@ -193,6 +193,27 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
193
193
  throw new ${ctx.utils.globalThis}.Error('Unsupported any value type: ' + typeof value);
194
194
  }
195
195
  return result;
196
+ }`);
197
+ }
198
+ else if (ctx.options.oneof === options_1.OneofOption.UNIONS_VALUE) {
199
+ chunks.push((0, ts_poet_1.code) `wrap(value: any): Value {
200
+ const result = createBaseValue()${maybeAsAny(ctx.options)};
201
+ if (value === null) {
202
+ result.kind = {$case: '${fieldNames.nullValue}', value };
203
+ } else if (typeof value === 'boolean') {
204
+ result.kind = {$case: '${fieldNames.boolValue}', value };
205
+ } else if (typeof value === 'number') {
206
+ result.kind = {$case: '${fieldNames.numberValue}', value };
207
+ } else if (typeof value === 'string') {
208
+ result.kind = {$case: '${fieldNames.stringValue}', value };
209
+ } else if (${ctx.utils.globalThis}.Array.isArray(value)) {
210
+ result.kind = {$case: '${fieldNames.listValue}', value };
211
+ } else if (typeof value === 'object') {
212
+ result.kind = {$case: '${fieldNames.structValue}', value };
213
+ } else if (typeof value !== 'undefined') {
214
+ throw new ${ctx.utils.globalThis}.Error('Unsupported any value type: ' + typeof value);
215
+ }
216
+ return result;
196
217
  }`);
197
218
  }
198
219
  else {
@@ -284,6 +305,11 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
284
305
  } else {
285
306
  return undefined;
286
307
  }
308
+ }`);
309
+ }
310
+ else if (ctx.options.oneof === options_1.OneofOption.UNIONS_VALUE) {
311
+ chunks.push((0, ts_poet_1.code) `unwrap(message: Value): string | number | boolean | Object | null | Array<any> | undefined {
312
+ return message.kind?.value;
287
313
  }`);
288
314
  }
289
315
  else {
package/build/main.js CHANGED
@@ -21,7 +21,6 @@ const types_1 = require("./types");
21
21
  const utils_1 = require("./utils");
22
22
  const visit_1 = require("./visit");
23
23
  function generateFile(ctx, fileDesc) {
24
- var _a;
25
24
  const { options, utils } = ctx;
26
25
  if (options.useOptionals === false) {
27
26
  console.warn("ts-proto: Passing useOptionals as a boolean option is deprecated and will be removed in a future version. Please pass the string 'none' instead of false.");
@@ -52,7 +51,7 @@ function generateFile(ctx, fileDesc) {
52
51
  // Syntax, unlike most fields, is not repeated and thus does not use an index
53
52
  const sourceInfo = sourceInfo_1.default.fromDescriptor(fileDesc);
54
53
  const headerComment = sourceInfo.lookup(sourceInfo_1.Fields.file.syntax, undefined);
55
- (0, utils_1.maybeAddComment)(options, headerComment, chunks, (_a = fileDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
54
+ (0, utils_1.maybeAddComment)(options, headerComment, chunks, fileDesc.options?.deprecated);
56
55
  // Apply formatting to methods here, so they propagate globally
57
56
  for (let svc of fileDesc.service) {
58
57
  for (let i = 0; i < svc.method.length; i++) {
@@ -449,6 +448,12 @@ function makeDeepPartial(options, longs) {
449
448
  ? { [K in keyof Omit<T, '$case'>]?: DeepPartial<T[K]> } & { ${maybeReadonly(options)}$case: T['$case'] }
450
449
  `;
451
450
  }
451
+ else if (options.oneof === options_1.OneofOption.UNIONS_VALUE) {
452
+ oneofCase = `
453
+ : T extends { ${maybeReadonly(options)}$case: string; value: unknown; }
454
+ ? { ${maybeReadonly(options)}$case: T['$case']; value?: DeepPartial<T['value']>; }
455
+ `;
456
+ }
452
457
  const maybeExport = options.exportCommonSymbols ? "export" : "";
453
458
  // Allow passing longs as numbers or strings, nad we'll convert them
454
459
  const maybeLong = options.forceLong === options_1.LongOption.LONG ? (0, ts_poet_1.code) ` : T extends ${longs.Long} ? string | number | Long ` : "";
@@ -673,10 +678,9 @@ function makeAssertionUtils(bytes) {
673
678
  }
674
679
  // Create the interface with properties
675
680
  function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fullTypeName) {
676
- var _a;
677
681
  const { options, currentFile } = ctx;
678
682
  const chunks = [];
679
- (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, (_a = messageDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
683
+ (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, messageDesc.options?.deprecated);
680
684
  // interface name should be defined to avoid import collisions
681
685
  chunks.push((0, ts_poet_1.code) `export interface ${(0, ts_poet_1.def)(fullName)} {`);
682
686
  if ((0, options_1.addTypeToMessages)(options)) {
@@ -685,7 +689,6 @@ function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fu
685
689
  // When oneof=unions, we generate a single property with an ADT per `oneof` clause.
686
690
  const processedOneofs = new Set();
687
691
  messageDesc.field.forEach((fieldDesc, index) => {
688
- var _a;
689
692
  if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, fieldDesc)) {
690
693
  const { oneofIndex } = fieldDesc;
691
694
  if (!processedOneofs.has(oneofIndex)) {
@@ -695,7 +698,7 @@ function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fu
695
698
  return;
696
699
  }
697
700
  const info = sourceInfo.lookup(sourceInfo_1.Fields.message.field, index);
698
- (0, utils_1.maybeAddComment)(options, info, chunks, (_a = fieldDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
701
+ (0, utils_1.maybeAddComment)(options, info, chunks, fieldDesc.options?.deprecated);
699
702
  const fieldKey = (0, utils_1.safeAccessor)((0, utils_1.getFieldName)(fieldDesc, options));
700
703
  const isOptional = (0, types_1.isOptionalProperty)(fieldDesc, messageDesc.options, options, currentFile.isProto3Syntax);
701
704
  const type = (0, types_1.toTypeName)(ctx, messageDesc, fieldDesc, isOptional);
@@ -714,7 +717,8 @@ function generateOneofProperty(ctx, messageDesc, oneofIndex, sourceInfo) {
714
717
  const unionType = (0, ts_poet_1.joinCode)(fields.map((f) => {
715
718
  let fieldName = (0, case_1.maybeSnakeToCamel)(f.name, options);
716
719
  let typeName = (0, types_1.toTypeName)(ctx, messageDesc, f);
717
- return (0, ts_poet_1.code) `{ ${mbReadonly}$case: '${fieldName}', ${mbReadonly}${fieldName}: ${typeName} }`;
720
+ let valueName = (0, utils_1.oneofValueName)(fieldName, options);
721
+ return (0, ts_poet_1.code) `{ ${mbReadonly}$case: '${fieldName}', ${mbReadonly}${valueName}: ${typeName} }`;
718
722
  }), { on: " | " });
719
723
  const name = (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[oneofIndex].name, options);
720
724
  return (0, ts_poet_1.code) `${mbReadonly}${name}?: ${unionType} | ${(0, utils_1.nullOrUndefined)(options)},`;
@@ -982,9 +986,10 @@ function generateDecode(ctx, fullName, messageDesc) {
982
986
  const oneofNameWithMessage = options.useJsonName
983
987
  ? messageProperty
984
988
  : (0, utils_1.getPropertyAccessor)("message", (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options));
989
+ const valueName = (0, utils_1.oneofValueName)(fieldName, options);
985
990
  chunks.push((0, ts_poet_1.code) `
986
991
  ${tagCheck}
987
- ${oneofNameWithMessage} = { $case: '${fieldName}', ${fieldName}: ${readSnippet} };
992
+ ${oneofNameWithMessage} = { $case: '${fieldName}', ${valueName}: ${readSnippet} };
988
993
  `);
989
994
  }
990
995
  else {
@@ -1054,13 +1059,13 @@ function getEncodeWriteSnippet(ctx, field) {
1054
1059
  case "int64":
1055
1060
  case "sint64":
1056
1061
  case "sfixed64":
1057
- return (place, placeAlt) => (0, ts_poet_1.code) `if (BigInt.asIntN(64, ${place}) !== ${placeAlt !== null && placeAlt !== void 0 ? placeAlt : place}) {
1062
+ return (place, placeAlt) => (0, ts_poet_1.code) `if (BigInt.asIntN(64, ${place}) !== ${placeAlt ?? place}) {
1058
1063
  throw new ${utils.globalThis}.Error('value provided for field ${place} of type ${fieldType} too large');
1059
1064
  }
1060
1065
  writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place}.toString())`;
1061
1066
  case "uint64":
1062
1067
  case "fixed64":
1063
- return (place, placeAlt) => (0, ts_poet_1.code) `if (BigInt.asUintN(64, ${place}) !== ${placeAlt !== null && placeAlt !== void 0 ? placeAlt : place}) {
1068
+ return (place, placeAlt) => (0, ts_poet_1.code) `if (BigInt.asUintN(64, ${place}) !== ${placeAlt ?? place}) {
1064
1069
  throw new ${utils.globalThis}.Error('value provided for field ${place} of type ${fieldType} too large');
1065
1070
  }
1066
1071
  writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place}.toString())`;
@@ -1270,8 +1275,9 @@ function generateEncode(ctx, fullName, messageDesc) {
1270
1275
  for (const oneOfField of oneOfFieldsDict[field.oneofIndex]) {
1271
1276
  const writeSnippet = getEncodeWriteSnippet(ctx, oneOfField);
1272
1277
  const oneOfFieldName = (0, case_1.maybeSnakeToCamel)(oneOfField.name, ctx.options);
1278
+ const valueName = (0, utils_1.oneofValueName)(oneOfFieldName, ctx.options);
1273
1279
  chunks.push((0, ts_poet_1.code) `case "${oneOfFieldName}":
1274
- ${writeSnippet(`${oneofNameWithMessage}.${oneOfFieldName}`)};
1280
+ ${writeSnippet(`${oneofNameWithMessage}.${valueName}`)};
1275
1281
  break;`);
1276
1282
  }
1277
1283
  chunks.push((0, ts_poet_1.code) `}`);
@@ -1385,11 +1391,10 @@ function generateGetExtension(ctx, fullName) {
1385
1391
  `;
1386
1392
  }
1387
1393
  function generateExtension(ctx, message, extension) {
1388
- var _a;
1389
1394
  const type = (0, types_1.toTypeName)(ctx, message, extension);
1390
1395
  const packedTag = (0, types_1.isRepeated)(extension) && (0, types_1.packedType)(extension.type) !== undefined ? ((extension.number << 3) | 2) >>> 0 : undefined;
1391
1396
  const singularTag = ((extension.number << 3) | (0, types_1.basicWireType)(extension.type)) >>> 0;
1392
- const tag = packedTag !== null && packedTag !== void 0 ? packedTag : singularTag;
1397
+ const tag = packedTag ?? singularTag;
1393
1398
  const chunks = [];
1394
1399
  chunks.push((0, ts_poet_1.code) `{`);
1395
1400
  chunks.push((0, ts_poet_1.code) `number: ${extension.number},`);
@@ -1397,7 +1402,7 @@ function generateExtension(ctx, message, extension) {
1397
1402
  if (packedTag !== undefined)
1398
1403
  chunks.push((0, ts_poet_1.code) `singularTag: ${singularTag},`);
1399
1404
  chunks.push((0, ts_poet_1.code) `repeated: ${extension.label == ts_proto_descriptors_1.FieldDescriptorProto_Label.LABEL_REPEATED},`);
1400
- chunks.push((0, ts_poet_1.code) `packed: ${((_a = extension.options) === null || _a === void 0 ? void 0 : _a.packed) ? true : false},`);
1405
+ chunks.push((0, ts_poet_1.code) `packed: ${extension.options?.packed ? true : false},`);
1401
1406
  const Reader = (0, utils_1.impFile)(ctx.options, "Reader@protobufjs/minimal");
1402
1407
  const Writer = (0, utils_1.impFile)(ctx.options, "Writer@protobufjs/minimal");
1403
1408
  if (ctx.options.outputEncodeMethods === true ||
@@ -1479,7 +1484,7 @@ function generateExtension(ctx, message, extension) {
1479
1484
  }
1480
1485
  else if ((0, types_1.isScalar)(extension) || (0, types_1.isEnum)(extension)) {
1481
1486
  chunks.push((0, ts_poet_1.code) `
1482
- if (${(0, types_1.notDefaultCheck)(ctx, extension, message === null || message === void 0 ? void 0 : message.options, "value")}) {
1487
+ if (${(0, types_1.notDefaultCheck)(ctx, extension, message?.options, "value")}) {
1483
1488
  const writer = ${Writer}.create();
1484
1489
  ${writeSnippet("value")};
1485
1490
  encoded.push(writer.finish());
@@ -1578,7 +1583,6 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1578
1583
  };
1579
1584
  // add a check for each incoming field
1580
1585
  messageDesc.field.forEach((field) => {
1581
- var _a;
1582
1586
  const fieldName = (0, utils_1.getFieldName)(field, options);
1583
1587
  const fieldKey = (0, utils_1.safeAccessor)(fieldName);
1584
1588
  const jsonName = (0, utils_1.getFieldJsonName)(field, options);
@@ -1586,7 +1590,6 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1586
1590
  const jsonPropertyOptional = (0, utils_1.getPropertyAccessor)("object", jsonName, true);
1587
1591
  // get code that extracts value from incoming object
1588
1592
  const readSnippet = (from) => {
1589
- var _a;
1590
1593
  if ((0, types_1.isEnum)(field)) {
1591
1594
  const fromJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "FromJSON");
1592
1595
  return (0, ts_poet_1.code) `${fromJson}(${from})`;
@@ -1602,7 +1605,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1602
1605
  }
1603
1606
  }
1604
1607
  else if ((0, types_1.isLong)(field) && (0, types_1.isJsTypeFieldOption)(options, field)) {
1605
- const fieldType = (_a = (0, types_1.getFieldOptionsJsType)(field, ctx.options)) !== null && _a !== void 0 ? _a : field.type;
1608
+ const fieldType = (0, types_1.getFieldOptionsJsType)(field, ctx.options) ?? field.type;
1606
1609
  const cstr = (0, case_1.capitalize)((0, types_1.basicTypeName)(ctx, { ...field, type: fieldType }, { keepValueType: true }).toCodeString([]));
1607
1610
  return (0, ts_poet_1.code) `${utils.globalThis}.${cstr}(${from})`;
1608
1611
  }
@@ -1715,7 +1718,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1715
1718
  const noDefaultValue = !options.initializeFieldsAsUndefined &&
1716
1719
  (0, types_1.isOptionalProperty)(field, messageDesc.options, options, currentFile.isProto3Syntax);
1717
1720
  // and then use the snippet to handle repeated fields if necessary
1718
- if ((_a = canonicalFromJson[fullTypeName]) === null || _a === void 0 ? void 0 : _a[fieldName]) {
1721
+ if (canonicalFromJson[fullTypeName]?.[fieldName]) {
1719
1722
  chunks.push((0, ts_poet_1.code) `${fieldName}: ${canonicalFromJson[fullTypeName][fieldName]("object")},`);
1720
1723
  }
1721
1724
  else if ((0, types_1.isRepeated)(field)) {
@@ -1767,8 +1770,9 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1767
1770
  const fieldName = (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options);
1768
1771
  chunks.push((0, ts_poet_1.code) `${fieldName}: `);
1769
1772
  }
1773
+ const valueName = (0, utils_1.oneofValueName)(fieldKey, options);
1770
1774
  const ternaryIf = (0, ts_poet_1.code) `${ctx.utils.isSet}(${jsonProperty})`;
1771
- const ternaryThen = (0, ts_poet_1.code) `{ $case: '${fieldName}', ${fieldKey}: ${readSnippet(`${jsonProperty}`)}`;
1775
+ const ternaryThen = (0, ts_poet_1.code) `{ $case: '${fieldName}', ${valueName}: ${readSnippet(`${jsonProperty}`)}`;
1772
1776
  chunks.push((0, ts_poet_1.code) `${ternaryIf} ? ${ternaryThen}} : `);
1773
1777
  if (field === lastCase) {
1774
1778
  chunks.push((0, ts_poet_1.code) `${(0, utils_1.nullOrUndefined)(options)},`);
@@ -1838,7 +1842,6 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1838
1842
  const jsonProperty = (0, utils_1.getPropertyAccessor)("obj", jsonName);
1839
1843
  const messageProperty = (0, utils_1.getPropertyAccessor)("message", fieldName);
1840
1844
  const readSnippet = (from) => {
1841
- var _a;
1842
1845
  if ((0, types_1.isEnum)(field)) {
1843
1846
  const toJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToJSON");
1844
1847
  return (0, ts_poet_1.code) `${toJson}(${from})`;
@@ -1917,7 +1920,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1917
1920
  return (0, ts_poet_1.code) `${utils.base64FromBytes}(${from})`;
1918
1921
  }
1919
1922
  else if ((0, types_1.isLong)(field) && (0, types_1.isJsTypeFieldOption)(options, field)) {
1920
- const fieldType = (_a = (0, types_1.getFieldOptionsJsType)(field, ctx.options)) !== null && _a !== void 0 ? _a : field.type;
1923
+ const fieldType = (0, types_1.getFieldOptionsJsType)(field, ctx.options) ?? field.type;
1921
1924
  if (!fieldType) {
1922
1925
  return (0, ts_poet_1.code) `${from}`;
1923
1926
  }
@@ -1979,9 +1982,10 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1979
1982
  const oneofNameWithMessage = options.useJsonName
1980
1983
  ? messageProperty
1981
1984
  : (0, utils_1.getPropertyAccessor)("message", (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options));
1985
+ const valueName = (0, utils_1.oneofValueName)(fieldName, options);
1982
1986
  chunks.push((0, ts_poet_1.code) `
1983
1987
  if (${oneofNameWithMessage}?.$case === '${fieldName}') {
1984
- ${jsonProperty} = ${readSnippet(`${oneofNameWithMessage}.${fieldName}`)};
1988
+ ${jsonProperty} = ${readSnippet(`${oneofNameWithMessage}.${valueName}`)};
1985
1989
  }
1986
1990
  `);
1987
1991
  }
@@ -2155,14 +2159,15 @@ function generateFromPartial(ctx, fullName, messageDesc) {
2155
2159
  const oneofName = (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options);
2156
2160
  const oneofNameWithMessage = (0, utils_1.getPropertyAccessor)("message", oneofName);
2157
2161
  const oneofNameWithObject = (0, utils_1.getPropertyAccessor)("object", oneofName);
2158
- const v = readSnippet(`${oneofNameWithObject}.${fieldName}`);
2162
+ const valueName = (0, utils_1.oneofValueName)(fieldName, options);
2163
+ const v = readSnippet(`${oneofNameWithObject}.${valueName}`);
2159
2164
  chunks.push((0, ts_poet_1.code) `
2160
2165
  if (
2161
2166
  ${oneofNameWithObject}?.$case === '${fieldName}'
2162
- && ${oneofNameWithObject}?.${fieldName} !== undefined
2163
- && ${oneofNameWithObject}?.${fieldName} !== null
2167
+ && ${oneofNameWithObject}?.${valueName} !== undefined
2168
+ && ${oneofNameWithObject}?.${valueName} !== null
2164
2169
  ) {
2165
- ${oneofNameWithMessage} = { $case: '${fieldName}', ${fieldName}: ${v} };
2170
+ ${oneofNameWithMessage} = { $case: '${fieldName}', ${valueName}: ${v} };
2166
2171
  }
2167
2172
  `);
2168
2173
  }
@@ -22,7 +22,8 @@ export declare enum EnvOption {
22
22
  }
23
23
  export declare enum OneofOption {
24
24
  PROPERTIES = "properties",
25
- UNIONS = "unions"
25
+ UNIONS = "unions",
26
+ UNIONS_VALUE = "unions-value"
26
27
  }
27
28
  export declare enum ServiceOption {
28
29
  GRPC = "grpc-js",
@@ -97,6 +98,7 @@ export type Options = {
97
98
  useNullAsOptional: boolean;
98
99
  annotateFilesWithVersion: boolean;
99
100
  noDefaultsForOptionals: boolean;
101
+ bigIntLiteral: boolean;
100
102
  };
101
103
  export declare function defaultOptions(): Options;
102
104
  export declare function optionsFromParameter(parameter: string | undefined): Options;
package/build/options.js CHANGED
@@ -30,6 +30,7 @@ var OneofOption;
30
30
  (function (OneofOption) {
31
31
  OneofOption["PROPERTIES"] = "properties";
32
32
  OneofOption["UNIONS"] = "unions";
33
+ OneofOption["UNIONS_VALUE"] = "unions-value";
33
34
  })(OneofOption || (exports.OneofOption = OneofOption = {}));
34
35
  var ServiceOption;
35
36
  (function (ServiceOption) {
@@ -104,6 +105,7 @@ function defaultOptions() {
104
105
  useNullAsOptional: false,
105
106
  annotateFilesWithVersion: true,
106
107
  noDefaultsForOptionals: false,
108
+ bigIntLiteral: true,
107
109
  };
108
110
  }
109
111
  exports.defaultOptions = defaultOptions;
package/build/schema.js CHANGED
@@ -10,7 +10,6 @@ const minimal_1 = require("protobufjs/minimal");
10
10
  const fileDescriptorProto = (0, ts_poet_1.imp)("FileDescriptorProto@ts-proto-descriptors");
11
11
  const extensionCache = {};
12
12
  function generateSchema(ctx, fileDesc, sourceInfo) {
13
- var _a;
14
13
  const { options } = ctx;
15
14
  const chunks = [];
16
15
  fileDesc.extension.forEach((extension) => {
@@ -73,7 +72,7 @@ function generateSchema(ctx, fileDesc, sourceInfo) {
73
72
  const descriptor = ts_proto_descriptors_1.FileDescriptorProto.fromPartial(fileDesc);
74
73
  // Only keep locations that include comments
75
74
  descriptor.sourceCodeInfo = {
76
- location: ((_a = descriptor.sourceCodeInfo) === null || _a === void 0 ? void 0 : _a.location.filter((loc) => loc["leadingComments"] || loc["trailingComments"])) || [],
75
+ location: descriptor.sourceCodeInfo?.location.filter((loc) => loc["leadingComments"] || loc["trailingComments"]) || [],
77
76
  };
78
77
  let fileOptions;
79
78
  if (fileDesc.options) {
package/build/types.js CHANGED
@@ -61,9 +61,8 @@ function basicLongWireType(type) {
61
61
  exports.basicLongWireType = basicLongWireType;
62
62
  /** Returns the type name without any repeated/required/etc. labels. */
63
63
  function basicTypeName(ctx, field, typeOptions = {}) {
64
- var _a, _b;
65
64
  const { options } = ctx;
66
- const fieldType = (_a = getFieldOptionsJsType(field, ctx.options)) !== null && _a !== void 0 ? _a : field.type;
65
+ const fieldType = getFieldOptionsJsType(field, ctx.options) ?? field.type;
67
66
  switch (fieldType) {
68
67
  case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_DOUBLE:
69
68
  case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_FLOAT:
@@ -79,7 +78,7 @@ function basicTypeName(ctx, field, typeOptions = {}) {
79
78
  case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_FIXED64:
80
79
  case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_SFIXED64:
81
80
  return isJsTypeFieldOption(options, field)
82
- ? (_b = jsTypeName(field)) !== null && _b !== void 0 ? _b : longTypeName(ctx)
81
+ ? jsTypeName(field) ?? longTypeName(ctx)
83
82
  : // this handles 2^53, Long is only needed for 2^64; this is effectively pbjs's forceNumber
84
83
  longTypeName(ctx);
85
84
  case ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_BOOL:
@@ -170,8 +169,7 @@ function packedType(type) {
170
169
  }
171
170
  exports.packedType = packedType;
172
171
  function getFieldOptionsJsType(field, options) {
173
- var _a;
174
- if (!options.useJsTypeOverride || ((_a = field.options) === null || _a === void 0 ? void 0 : _a.jstype) === undefined) {
172
+ if (!options.useJsTypeOverride || field.options?.jstype === undefined) {
175
173
  return;
176
174
  }
177
175
  switch (field.options.jstype) {
@@ -242,7 +240,7 @@ function defaultValue(ctx, field) {
242
240
  return `"${numericDefaultVal}"`;
243
241
  }
244
242
  else if (options.forceLong === options_1.LongOption.BIGINT) {
245
- return `BigInt("${numericDefaultVal}")`;
243
+ return options.bigIntLiteral ? (0, ts_poet_1.code) `${numericDefaultVal}n` : (0, ts_poet_1.code) `BigInt("${numericDefaultVal}")`;
246
244
  }
247
245
  else {
248
246
  return numericDefaultVal;
@@ -375,12 +373,12 @@ function isOptionalProperty(field, messageOptions, options, isProto3Syntax) {
375
373
  const optionalAll = options.useOptionals === "all";
376
374
  const deprecatedOnly = options.useOptionals === "deprecatedOnly" && field.options && field.options.deprecated;
377
375
  return ((optionalMessages && isMessage(field) && !isRepeated(field)) ||
378
- ((optionalAll || deprecatedOnly) && !(messageOptions === null || messageOptions === void 0 ? void 0 : messageOptions.mapEntry)) ||
376
+ ((optionalAll || deprecatedOnly) && !messageOptions?.mapEntry) ||
379
377
  (options.noDefaultsForOptionals && !isRepeated(field) && (isScalar(field) || isEnum(field))) ||
380
378
  // file is proto2, we have enabled proto2 optionals, and the field itself is optional
381
379
  (!isProto3Syntax &&
382
380
  field.label === ts_proto_descriptors_1.FieldDescriptorProto_Label.LABEL_OPTIONAL &&
383
- !(messageOptions === null || messageOptions === void 0 ? void 0 : messageOptions.mapEntry) &&
381
+ !messageOptions?.mapEntry &&
384
382
  !options.disableProto2Optionals) ||
385
383
  // don't bother verifying that oneof is not union. union oneofs generate their own properties.
386
384
  isWithinOneOf(field) ||
@@ -409,7 +407,9 @@ function isWithinOneOf(field) {
409
407
  }
410
408
  exports.isWithinOneOf = isWithinOneOf;
411
409
  function isWithinOneOfThatShouldBeUnion(options, field) {
412
- return isWithinOneOf(field) && options.oneof === options_1.OneofOption.UNIONS && !field.proto3Optional;
410
+ return (isWithinOneOf(field) &&
411
+ (options.oneof === options_1.OneofOption.UNIONS || options.oneof === options_1.OneofOption.UNIONS_VALUE) &&
412
+ !field.proto3Optional);
413
413
  }
414
414
  exports.isWithinOneOfThatShouldBeUnion = isWithinOneOfThatShouldBeUnion;
415
415
  function isRepeated(field) {
@@ -573,17 +573,15 @@ function longTypeName(ctx) {
573
573
  }
574
574
  }
575
575
  function jsTypeName(field) {
576
- var _a, _b;
577
- if (((_a = field.options) === null || _a === void 0 ? void 0 : _a.jstype) === ts_proto_descriptors_1.FieldOptions_JSType.JS_STRING) {
576
+ if (field.options?.jstype === ts_proto_descriptors_1.FieldOptions_JSType.JS_STRING) {
578
577
  return (0, ts_poet_1.code) `string`;
579
578
  }
580
- else if (((_b = field.options) === null || _b === void 0 ? void 0 : _b.jstype) === ts_proto_descriptors_1.FieldOptions_JSType.JS_NUMBER) {
579
+ else if (field.options?.jstype === ts_proto_descriptors_1.FieldOptions_JSType.JS_NUMBER) {
581
580
  return (0, ts_poet_1.code) `number`;
582
581
  }
583
582
  }
584
583
  /** Maps `.some_proto_namespace.Message` to a TypeName. */
585
584
  function messageToTypeName(ctx, protoType, typeOptions = {}) {
586
- var _a;
587
585
  const { options, typeMap } = ctx;
588
586
  // Watch for the wrapper types `.google.protobuf.*Value`. If we're mapping
589
587
  // them to basic built-in types, we union the type with undefined to
@@ -591,7 +589,7 @@ function messageToTypeName(ctx, protoType, typeOptions = {}) {
591
589
  // - If the field is repeated, values cannot be undefined.
592
590
  let valueType = valueTypeName(ctx, protoType);
593
591
  if (!typeOptions.keepValueType && valueType) {
594
- if ((_a = typeOptions.repeated) !== null && _a !== void 0 ? _a : false) {
592
+ if (typeOptions.repeated ?? false) {
595
593
  return valueType;
596
594
  }
597
595
  return (0, ts_poet_1.code) `${valueType} | ${(0, utils_1.nullOrUndefined)(options)}`;
@@ -624,14 +622,13 @@ function getEnumMethod(ctx, enumProtoType, methodSuffix) {
624
622
  exports.getEnumMethod = getEnumMethod;
625
623
  /** Return the TypeName for any field (primitive/message/etc.) as exposed in the interface. */
626
624
  function toTypeName(ctx, messageDesc, field, ensureOptional = false) {
627
- var _a;
628
625
  function finalize(type, isOptional) {
629
626
  if (isOptional) {
630
627
  return (0, ts_poet_1.code) `${type} | ${(0, utils_1.nullOrUndefined)(ctx.options, field.proto3Optional)}`;
631
628
  }
632
629
  return type;
633
630
  }
634
- const fieldType = (_a = getFieldOptionsJsType(field, ctx.options)) !== null && _a !== void 0 ? _a : field.type;
631
+ const fieldType = getFieldOptionsJsType(field, ctx.options) ?? field.type;
635
632
  const type = basicTypeName(ctx, { ...field, type: fieldType }, { keepValueType: false });
636
633
  if (isRepeated(field)) {
637
634
  const mapType = messageDesc ? detectMapType(ctx, messageDesc, field) : false;
@@ -697,12 +694,11 @@ function shouldGenerateJSMapType(ctx, message, field) {
697
694
  }
698
695
  exports.shouldGenerateJSMapType = shouldGenerateJSMapType;
699
696
  function detectMapType(ctx, messageDesc, fieldDesc) {
700
- var _a;
701
697
  const { typeMap } = ctx;
702
698
  if (fieldDesc.label === ts_proto_descriptors_1.FieldDescriptorProto_Label.LABEL_REPEATED &&
703
699
  fieldDesc.type === ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_MESSAGE) {
704
700
  const mapType = typeMap.get(fieldDesc.typeName)[2];
705
- if (!((_a = mapType.options) === null || _a === void 0 ? void 0 : _a.mapEntry))
701
+ if (!mapType.options?.mapEntry)
706
702
  return undefined;
707
703
  const [keyField, valueField] = mapType.field;
708
704
  const keyType = toTypeName(ctx, messageDesc, keyField);
@@ -799,8 +795,7 @@ function hasSingleRepeatedField(messageDesc) {
799
795
  return messageDesc.field.length == 1 && messageDesc.field[0].label === ts_proto_descriptors_1.FieldDescriptorProto_Label.LABEL_REPEATED;
800
796
  }
801
797
  function isJsTypeFieldOption(options, field) {
802
- var _a, _b;
803
798
  return (options.useJsTypeOverride &&
804
- (((_a = field.options) === null || _a === void 0 ? void 0 : _a.jstype) === ts_proto_descriptors_1.FieldOptions_JSType.JS_NUMBER || ((_b = field.options) === null || _b === void 0 ? void 0 : _b.jstype) === ts_proto_descriptors_1.FieldOptions_JSType.JS_STRING));
799
+ (field.options?.jstype === ts_proto_descriptors_1.FieldOptions_JSType.JS_NUMBER || field.options?.jstype === ts_proto_descriptors_1.FieldOptions_JSType.JS_STRING));
805
800
  }
806
801
  exports.isJsTypeFieldOption = isJsTypeFieldOption;
package/build/utils.d.ts CHANGED
@@ -73,6 +73,7 @@ export declare function arrowFunction(params: string, body: Code | string, isOne
73
73
  export declare function nullOrUndefined(options: Pick<Options, "useNullAsOptional">, hasProto3Optional?: boolean): string;
74
74
  export declare function maybeCheckIsNotNull(options: Pick<Options, "useNullAsOptional">, typeName: string, prefix?: string): string;
75
75
  export declare function maybeCheckIsNull(options: Pick<Options, "useNullAsOptional">, typeName: string, prefix?: string): string;
76
+ export declare function oneofValueName(fieldName: string, options: Pick<Options, "oneof">): string;
76
77
  export declare function withOrMaybeCheckIsNotNull(options: Pick<Options, "useNullAsOptional">, typeName: string): string;
77
78
  export declare function withOrMaybeCheckIsNull(options: Pick<Options, "useNullAsOptional">, typeName: string): string;
78
79
  export declare function withAndMaybeCheckIsNotNull(options: Pick<Options, "useNullAsOptional">, typeName: string): string;
package/build/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getVersions = exports.withAndMaybeCheckIsNull = exports.withAndMaybeCheckIsNotNull = exports.withOrMaybeCheckIsNull = exports.withOrMaybeCheckIsNotNull = exports.maybeCheckIsNull = exports.maybeCheckIsNotNull = exports.nullOrUndefined = exports.arrowFunction = exports.tryCatchBlock = exports.impProto = exports.impFile = exports.getPropertyAccessor = exports.safeAccessor = exports.getFieldName = exports.getFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.maybeAddComment = exports.upperFirst = exports.lowerFirst = exports.singular = exports.fail = exports.readToBuffer = exports.generateIndexFiles = exports.protoFilesToGenerate = void 0;
3
+ exports.getVersions = exports.withAndMaybeCheckIsNull = exports.withAndMaybeCheckIsNotNull = exports.withOrMaybeCheckIsNull = exports.withOrMaybeCheckIsNotNull = exports.oneofValueName = exports.maybeCheckIsNull = exports.maybeCheckIsNotNull = exports.nullOrUndefined = exports.arrowFunction = exports.tryCatchBlock = exports.impProto = exports.impFile = exports.getPropertyAccessor = exports.safeAccessor = exports.getFieldName = exports.getFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.maybeAddComment = exports.upperFirst = exports.lowerFirst = exports.singular = exports.fail = exports.readToBuffer = exports.generateIndexFiles = exports.protoFilesToGenerate = void 0;
4
4
  const path = require("path");
5
5
  const ts_poet_1 = require("ts-poet");
6
6
  const options_1 = require("./options");
@@ -266,6 +266,10 @@ function maybeCheckIsNull(options, typeName, prefix) {
266
266
  return options.useNullAsOptional ? ` ${prefix} ${typeName} === null` : "";
267
267
  }
268
268
  exports.maybeCheckIsNull = maybeCheckIsNull;
269
+ function oneofValueName(fieldName, options) {
270
+ return options.oneof === options_1.OneofOption.UNIONS ? fieldName : "value";
271
+ }
272
+ exports.oneofValueName = oneofValueName;
269
273
  function withOrMaybeCheckIsNotNull(options, typeName) {
270
274
  return maybeCheckIsNotNull(options, typeName, "||");
271
275
  }
@@ -283,7 +287,6 @@ function withAndMaybeCheckIsNull(options, typeName) {
283
287
  }
284
288
  exports.withAndMaybeCheckIsNull = withAndMaybeCheckIsNull;
285
289
  async function getVersions(request) {
286
- var _a;
287
290
  let protocVersion = "unknown";
288
291
  if (request.compilerVersion) {
289
292
  const { major, minor, patch } = request.compilerVersion;
@@ -291,7 +294,7 @@ async function getVersions(request) {
291
294
  }
292
295
  const path = "../package.json";
293
296
  const packageJson = await Promise.resolve(`${path}`).then(s => require(s));
294
- const tsProtoVersion = `v${(_a = packageJson === null || packageJson === void 0 ? void 0 : packageJson.version) !== null && _a !== void 0 ? _a : "unknown"}`;
297
+ const tsProtoVersion = `v${packageJson?.version ?? "unknown"}`;
295
298
  return {
296
299
  protocVersion,
297
300
  tsProtoVersion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.178.0",
3
+ "version": "1.180.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",