ts-proto 1.159.3 → 1.161.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
@@ -14,15 +14,15 @@
14
14
  - [Buf](#buf)
15
15
  - [ESM](#esm)
16
16
  - [Goals](#goals)
17
+ - [Non-Goals](#non-goals)
17
18
  - [Example Types](#example-types)
18
19
  - [Highlights](#highlights)
19
20
  - [Auto-Batching / N+1 Prevention](#auto-batching--n1-prevention)
20
21
  - [Usage](#usage)
21
- - [Supported options](#supported-options)
22
- - [Only Types](#only-types)
23
- - [NestJS Support](#nestjs-support)
24
- - [Watch Mode](#watch-mode)
25
- - [Basic gRPC implementation](#basic-grpc-implementation)
22
+ - [Supported options](#supported-options)
23
+ - [NestJS Support](#nestjs-support)
24
+ - [Watch Mode](#watch-mode)
25
+ - [Basic gRPC implementation](#basic-grpc-implementation)
26
26
  - [Sponsors](#sponsors)
27
27
  - [Development](#development)
28
28
  - [Assumptions](#assumptions)
@@ -354,7 +354,15 @@ Generated code will be placed in the Gradle build directory.
354
354
 
355
355
  See the "OneOf Handling" section.
356
356
 
357
- - With `--ts_proto_opt=unrecognizedEnum=false` enums will not contain an `UNRECOGNIZED` key with value of -1.
357
+ - With `--ts_proto_opt=unrecognizedEnumName=<NAME>` enums will contain a key `<NAME>` with value of the `unrecognizedEnumValue` option.
358
+
359
+ Defaults to `UNRECOGNIZED`.
360
+
361
+ - With `--ts_proto_opt=unrecognizedEnumValue=<NUMBER>` enums will contain a key provided by the `unrecognizedEnumName` option with value of `<NUMBER>`.
362
+
363
+ Defaults to `-1`.
364
+
365
+ - With `--ts_proto_opt=unrecognizedEnum=false` enums will not contain an unrecognized enum key and value as provided by the `unrecognizedEnumName` and `unrecognizedEnumValue` options.
358
366
 
359
367
  - With `--ts_proto_opt=removeEnumPrefix=true` generated enums will have the enum name removed from members.
360
368
 
package/build/enums.js CHANGED
@@ -5,13 +5,12 @@ const ts_poet_1 = require("ts-poet");
5
5
  const utils_1 = require("./utils");
6
6
  const case_1 = require("./case");
7
7
  const sourceInfo_1 = require("./sourceInfo");
8
- const UNRECOGNIZED_ENUM_NAME = "UNRECOGNIZED";
9
- const UNRECOGNIZED_ENUM_VALUE = -1;
10
8
  // Output the `enum { Foo, A = 0, B = 1 }`
11
9
  function generateEnum(ctx, fullName, enumDesc, sourceInfo) {
12
10
  var _a;
13
11
  const { options } = ctx;
14
12
  const chunks = [];
13
+ let unrecognizedEnum = { present: false };
15
14
  (0, utils_1.maybeAddComment)(sourceInfo, chunks, (_a = enumDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
16
15
  if (options.enumsAsLiterals) {
17
16
  chunks.push((0, ts_poet_1.code) `export const ${(0, ts_poet_1.def)(fullName)} = {`);
@@ -25,12 +24,16 @@ function generateEnum(ctx, fullName, enumDesc, sourceInfo) {
25
24
  const info = sourceInfo.lookup(sourceInfo_1.Fields.enum.value, index);
26
25
  const valueName = getValueName(ctx, fullName, valueDesc);
27
26
  const memberName = getMemberName(ctx, enumDesc, valueDesc);
27
+ if (valueDesc.number === options.unrecognizedEnumValue) {
28
+ unrecognizedEnum = { present: true, name: memberName };
29
+ }
28
30
  (0, utils_1.maybeAddComment)(info, chunks, (_a = valueDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated, `${memberName} - `);
29
31
  chunks.push((0, ts_poet_1.code) `${memberName} ${delimiter} ${options.stringEnums ? `"${valueName}"` : valueDesc.number.toString()},`);
30
32
  });
31
- if (options.unrecognizedEnum)
33
+ if (options.unrecognizedEnum && !unrecognizedEnum.present) {
32
34
  chunks.push((0, ts_poet_1.code) `
33
- ${UNRECOGNIZED_ENUM_NAME} ${delimiter} ${options.stringEnums ? `"${UNRECOGNIZED_ENUM_NAME}"` : UNRECOGNIZED_ENUM_VALUE.toString()},`);
35
+ ${options.unrecognizedEnumName} ${delimiter} ${options.stringEnums ? `"${options.unrecognizedEnumName}"` : options.unrecognizedEnumValue.toString()},`);
36
+ }
34
37
  if (options.enumsAsLiterals) {
35
38
  chunks.push((0, ts_poet_1.code) `} as const`);
36
39
  chunks.push((0, ts_poet_1.code) `\n`);
@@ -43,21 +46,21 @@ function generateEnum(ctx, fullName, enumDesc, sourceInfo) {
43
46
  options.outputJsonMethods === "from-only" ||
44
47
  (options.stringEnums && options.outputEncodeMethods)) {
45
48
  chunks.push((0, ts_poet_1.code) `\n`);
46
- chunks.push(generateEnumFromJson(ctx, fullName, enumDesc));
49
+ chunks.push(generateEnumFromJson(ctx, fullName, enumDesc, unrecognizedEnum));
47
50
  }
48
51
  if (options.outputJsonMethods === true || options.outputJsonMethods === "to-only") {
49
52
  chunks.push((0, ts_poet_1.code) `\n`);
50
- chunks.push(generateEnumToJson(ctx, fullName, enumDesc));
53
+ chunks.push(generateEnumToJson(ctx, fullName, enumDesc, unrecognizedEnum));
51
54
  }
52
55
  if (options.stringEnums && options.outputEncodeMethods) {
53
56
  chunks.push((0, ts_poet_1.code) `\n`);
54
- chunks.push(generateEnumToNumber(ctx, fullName, enumDesc));
57
+ chunks.push(generateEnumToNumber(ctx, fullName, enumDesc, unrecognizedEnum));
55
58
  }
56
59
  return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
57
60
  }
58
61
  exports.generateEnum = generateEnum;
59
62
  /** Generates a function with a big switch statement to decode JSON -> our enum. */
60
- function generateEnumFromJson(ctx, fullName, enumDesc) {
63
+ function generateEnumFromJson(ctx, fullName, enumDesc, unrecognizedEnum) {
61
64
  const { options, utils } = ctx;
62
65
  const chunks = [];
63
66
  const functionName = (0, case_1.uncapitalize)(fullName) + "FromJSON";
@@ -73,12 +76,20 @@ function generateEnumFromJson(ctx, fullName, enumDesc) {
73
76
  `);
74
77
  }
75
78
  if (options.unrecognizedEnum) {
76
- chunks.push((0, ts_poet_1.code) `
77
- case ${UNRECOGNIZED_ENUM_VALUE}:
78
- case "${UNRECOGNIZED_ENUM_NAME}":
79
- default:
80
- return ${fullName}.${UNRECOGNIZED_ENUM_NAME};
81
- `);
79
+ if (!unrecognizedEnum.present) {
80
+ chunks.push((0, ts_poet_1.code) `
81
+ case ${options.unrecognizedEnumValue}:
82
+ case "${options.unrecognizedEnumName}":
83
+ default:
84
+ return ${fullName}.${options.unrecognizedEnumName};
85
+ `);
86
+ }
87
+ else {
88
+ chunks.push((0, ts_poet_1.code) `
89
+ default:
90
+ return ${fullName}.${unrecognizedEnum.name};
91
+ `);
92
+ }
82
93
  }
83
94
  else {
84
95
  // We use globalThis to avoid conflicts on protobuf types named `Error`.
@@ -93,7 +104,7 @@ function generateEnumFromJson(ctx, fullName, enumDesc) {
93
104
  }
94
105
  exports.generateEnumFromJson = generateEnumFromJson;
95
106
  /** Generates a function with a big switch statement to encode our enum -> JSON. */
96
- function generateEnumToJson(ctx, fullName, enumDesc) {
107
+ function generateEnumToJson(ctx, fullName, enumDesc, unrecognizedEnum) {
97
108
  const { options, utils } = ctx;
98
109
  const chunks = [];
99
110
  const functionName = (0, case_1.uncapitalize)(fullName) + "ToJSON";
@@ -111,18 +122,32 @@ function generateEnumToJson(ctx, fullName, enumDesc) {
111
122
  }
112
123
  }
113
124
  if (options.unrecognizedEnum) {
114
- chunks.push((0, ts_poet_1.code) `
115
- case ${fullName}.${UNRECOGNIZED_ENUM_NAME}:`);
116
- if (ctx.options.useNumericEnumForJson) {
125
+ if (!unrecognizedEnum.present) {
117
126
  chunks.push((0, ts_poet_1.code) `
118
- default:
119
- return ${UNRECOGNIZED_ENUM_VALUE};
120
- `);
127
+ case ${fullName}.${options.unrecognizedEnumName}:`);
128
+ if (ctx.options.useNumericEnumForJson) {
129
+ chunks.push((0, ts_poet_1.code) `
130
+ default:
131
+ return ${options.unrecognizedEnumValue};
132
+ `);
133
+ }
134
+ else {
135
+ chunks.push((0, ts_poet_1.code) `
136
+ default:
137
+ return "${options.unrecognizedEnumName}";
138
+ `);
139
+ }
140
+ }
141
+ else if (ctx.options.useNumericEnumForJson) {
142
+ chunks.push((0, ts_poet_1.code) `
143
+ default:
144
+ return ${options.unrecognizedEnumValue};
145
+ `);
121
146
  }
122
147
  else {
123
148
  chunks.push((0, ts_poet_1.code) `
124
149
  default:
125
- return "${UNRECOGNIZED_ENUM_NAME}";
150
+ return "${unrecognizedEnum.name}";
126
151
  `);
127
152
  }
128
153
  }
@@ -139,7 +164,7 @@ function generateEnumToJson(ctx, fullName, enumDesc) {
139
164
  }
140
165
  exports.generateEnumToJson = generateEnumToJson;
141
166
  /** Generates a function with a big switch statement to encode our string enum -> int value. */
142
- function generateEnumToNumber(ctx, fullName, enumDesc) {
167
+ function generateEnumToNumber(ctx, fullName, enumDesc, unrecognizedEnum) {
143
168
  const { options, utils } = ctx;
144
169
  const chunks = [];
145
170
  const functionName = (0, case_1.uncapitalize)(fullName) + "ToNumber";
@@ -149,11 +174,19 @@ function generateEnumToNumber(ctx, fullName, enumDesc) {
149
174
  chunks.push((0, ts_poet_1.code) `case ${fullName}.${getMemberName(ctx, enumDesc, valueDesc)}: return ${valueDesc.number};`);
150
175
  }
151
176
  if (options.unrecognizedEnum) {
152
- chunks.push((0, ts_poet_1.code) `
153
- case ${fullName}.${UNRECOGNIZED_ENUM_NAME}:
154
- default:
155
- return ${UNRECOGNIZED_ENUM_VALUE};
156
- `);
177
+ if (!unrecognizedEnum.present) {
178
+ chunks.push((0, ts_poet_1.code) `
179
+ case ${fullName}.${options.unrecognizedEnumName}:
180
+ default:
181
+ return ${options.unrecognizedEnumValue};
182
+ `);
183
+ }
184
+ else {
185
+ chunks.push((0, ts_poet_1.code) `
186
+ default:
187
+ return ${options.unrecognizedEnumValue};
188
+ `);
189
+ }
157
190
  }
158
191
  else {
159
192
  // We use globalThis to avoid conflicts on protobuf types named `Error`.
package/build/main.js CHANGED
@@ -943,7 +943,24 @@ function getEncodeWriteSnippet(ctx, field) {
943
943
  }
944
944
  else if ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT) {
945
945
  const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
946
- return (place) => (0, ts_poet_1.code) `writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place}.toString())`;
946
+ const fieldType = (0, types_1.toReaderCall)(field);
947
+ switch (fieldType) {
948
+ case "int64":
949
+ case "sint64":
950
+ case "sfixed64":
951
+ return (place) => (0, ts_poet_1.code) `if (BigInt.asIntN(64, ${place}) !== ${place}) {
952
+ throw new Error('value provided for field ${place} of type ${fieldType} too large');
953
+ }
954
+ writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place}.toString())`;
955
+ case "uint64":
956
+ case "fixed64":
957
+ return (place) => (0, ts_poet_1.code) `if (BigInt.asUintN(64, ${place}) !== ${place}) {
958
+ throw new Error('value provided for field ${place} of type ${fieldType} too large');
959
+ }
960
+ writer.uint32(${tag}).${(0, types_1.toReaderCall)(field)}(${place}.toString())`;
961
+ default:
962
+ throw new Error(`unexpected BigInt type: ${fieldType}`);
963
+ }
947
964
  }
948
965
  else if ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) {
949
966
  const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
@@ -1080,13 +1097,47 @@ function generateEncode(ctx, fullName, messageDesc) {
1080
1097
  // Ideally we'd reuse `writeSnippet` but it has tagging embedded inside of it.
1081
1098
  const tag = ((field.number << 3) | 2) >>> 0;
1082
1099
  const rhs = (x) => ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT ? `${x}.toString()` : x);
1083
- const listWriteSnippet = (0, ts_poet_1.code) `
1100
+ let listWriteSnippet = (0, ts_poet_1.code) `
1084
1101
  writer.uint32(${tag}).fork();
1085
1102
  for (const v of message.${fieldName}) {
1086
1103
  writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
1087
1104
  }
1088
1105
  writer.ldelim();
1089
1106
  `;
1107
+ if ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT) {
1108
+ const fieldType = (0, types_1.toReaderCall)(field);
1109
+ switch (fieldType) {
1110
+ case "int64":
1111
+ case "sint64":
1112
+ case "sfixed64":
1113
+ listWriteSnippet = (0, ts_poet_1.code) `
1114
+ writer.uint32(${tag}).fork();
1115
+ for (const v of message.${fieldName}) {
1116
+ if (BigInt.asIntN(64, v) !== v) {
1117
+ throw new Error('a value provided in array field ${fieldName} of type ${fieldType} is too large');
1118
+ }
1119
+ writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
1120
+ }
1121
+ writer.ldelim();
1122
+ `;
1123
+ break;
1124
+ case "uint64":
1125
+ case "fixed64":
1126
+ listWriteSnippet = (0, ts_poet_1.code) `
1127
+ writer.uint32(${tag}).fork();
1128
+ for (const v of message.${fieldName}) {
1129
+ if (BigInt.asUintN(64, v) !== v) {
1130
+ throw new Error('a value provided in array field ${fieldName} of type ${fieldType} is too large');
1131
+ }
1132
+ writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
1133
+ }
1134
+ writer.ldelim();
1135
+ `;
1136
+ break;
1137
+ default:
1138
+ throw new Error(`unexpected BigInt type: ${fieldType}`);
1139
+ }
1140
+ }
1090
1141
  if (isOptional) {
1091
1142
  chunks.push((0, ts_poet_1.code) `
1092
1143
  if (message.${fieldName} !== undefined && message.${fieldName}.length !== 0) {
package/build/options.js CHANGED
@@ -66,6 +66,8 @@ function defaultOptions() {
66
66
  nestJs: false,
67
67
  env: EnvOption.BOTH,
68
68
  unrecognizedEnum: true,
69
+ unrecognizedEnumName: "UNRECOGNIZED",
70
+ unrecognizedEnumValue: -1,
69
71
  exportCommonSymbols: true,
70
72
  outputSchema: false,
71
73
  onlyTypes: false,
@@ -172,6 +174,10 @@ function optionsFromParameter(parameter) {
172
174
  if (options.outputIndex) {
173
175
  options.exportCommonSymbols = false;
174
176
  }
177
+ if (options.unrecognizedEnumValue) {
178
+ // Make sure to cast number options to an actual number
179
+ options.unrecognizedEnumValue = Number(options.unrecognizedEnumValue);
180
+ }
175
181
  return options;
176
182
  }
177
183
  exports.optionsFromParameter = optionsFromParameter;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.159.3",
3
+ "version": "1.161.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",