ts-proto 1.139.0 → 1.141.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
@@ -352,6 +352,10 @@ Generated code will be placed in the Gradle build directory.
352
352
 
353
353
  - With `--ts_proto_opt=unrecognizedEnum=false` enums will not contain an `UNRECOGNIZED` key with value of -1.
354
354
 
355
+ - With `--ts_proto_opt=removeEnumPrefix=true` generated enums will have the enum name removed from members.
356
+
357
+ `FooBar.FOO_BAR_BAZ = "FOO_BAR_BAZ"` will generate `FooBar.BAZ = "FOO_BAR_BAZ"`
358
+
355
359
  - With `--ts_proto_opt=lowerCaseServiceMethods=true`, the method names of service methods will be lowered/camel-case, i.e. `service.findFoo` instead of `service.FindFoo`.
356
360
 
357
361
  - With `--ts_proto_opt=snakeToCamel=false`, fields will be kept snake case in both the message keys and the `toJSON` / `fromJSON` methods.
@@ -400,7 +404,7 @@ Generated code will be placed in the Gradle build directory.
400
404
 
401
405
  - With `--ts_proto_opt=nestJs=true`, the defaults will change to generate [NestJS protobuf](https://docs.nestjs.com/microservices/grpc) friendly types & service interfaces that can be used in both the client-side and server-side of NestJS protobuf implementations. See the [nestjs readme](NESTJS.markdown) for more information and implementation examples.
402
406
 
403
- Specifically `outputEncodeMethods`, `outputJsonMethods`, and `outputClientImpl` will all be false, and `lowerCaseServiceMethods` will be true.
407
+ Specifically `outputEncodeMethods`, `outputJsonMethods`, and `outputClientImpl` will all be false, `lowerCaseServiceMethods` will be true and `outputServices` will be ignored.
404
408
 
405
409
  Note that `addGrpcMetadata`, `addNestjsRestParameter` and `returnObservable` will still be false.
406
410
 
package/build/enums.js CHANGED
@@ -23,8 +23,10 @@ function generateEnum(ctx, fullName, enumDesc, sourceInfo) {
23
23
  enumDesc.value.forEach((valueDesc, index) => {
24
24
  var _a;
25
25
  const info = sourceInfo.lookup(sourceInfo_1.Fields.enum.value, index);
26
- (0, utils_1.maybeAddComment)(info, chunks, (_a = valueDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated, `${valueDesc.name} - `);
27
- chunks.push((0, ts_poet_1.code) `${valueDesc.name} ${delimiter} ${options.stringEnums ? `"${valueDesc.name}"` : valueDesc.number.toString()},`);
26
+ const valueName = getValueName(ctx, fullName, valueDesc);
27
+ const memberName = getMemberName(ctx, fullName, valueDesc);
28
+ (0, utils_1.maybeAddComment)(info, chunks, (_a = valueDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated, `${memberName} - `);
29
+ chunks.push((0, ts_poet_1.code) `${memberName} ${delimiter} ${options.stringEnums ? `"${valueName}"` : valueDesc.number.toString()},`);
28
30
  });
29
31
  if (options.unrecognizedEnum)
30
32
  chunks.push((0, ts_poet_1.code) `
@@ -60,10 +62,12 @@ function generateEnumFromJson(ctx, fullName, enumDesc) {
60
62
  chunks.push((0, ts_poet_1.code) `export function ${(0, ts_poet_1.def)(functionName)}(object: any): ${fullName} {`);
61
63
  chunks.push((0, ts_poet_1.code) `switch (object) {`);
62
64
  for (const valueDesc of enumDesc.value) {
65
+ const memberName = getMemberName(ctx, fullName, valueDesc);
66
+ const valueName = getValueName(ctx, fullName, valueDesc);
63
67
  chunks.push((0, ts_poet_1.code) `
64
68
  case ${valueDesc.number}:
65
- case "${valueDesc.name}":
66
- return ${fullName}.${valueDesc.name};
69
+ case "${valueName}":
70
+ return ${fullName}.${memberName};
67
71
  `);
68
72
  }
69
73
  if (options.unrecognizedEnum) {
@@ -95,10 +99,13 @@ function generateEnumToJson(ctx, fullName, enumDesc) {
95
99
  chunks.push((0, ts_poet_1.code) `switch (object) {`);
96
100
  for (const valueDesc of enumDesc.value) {
97
101
  if (ctx.options.useNumericEnumForJson) {
98
- chunks.push((0, ts_poet_1.code) `case ${fullName}.${valueDesc.name}: return ${valueDesc.number};`);
102
+ const memberName = getMemberName(ctx, fullName, valueDesc);
103
+ chunks.push((0, ts_poet_1.code) `case ${fullName}.${memberName}: return ${valueDesc.number};`);
99
104
  }
100
105
  else {
101
- chunks.push((0, ts_poet_1.code) `case ${fullName}.${valueDesc.name}: return "${valueDesc.name}";`);
106
+ const memberName = getMemberName(ctx, fullName, valueDesc);
107
+ const valueName = getValueName(ctx, fullName, valueDesc);
108
+ chunks.push((0, ts_poet_1.code) `case ${fullName}.${memberName}: return "${valueName}";`);
102
109
  }
103
110
  }
104
111
  if (options.unrecognizedEnum) {
@@ -137,7 +144,7 @@ function generateEnumToNumber(ctx, fullName, enumDesc) {
137
144
  chunks.push((0, ts_poet_1.code) `export function ${(0, ts_poet_1.def)(functionName)}(object: ${fullName}): number {`);
138
145
  chunks.push((0, ts_poet_1.code) `switch (object) {`);
139
146
  for (const valueDesc of enumDesc.value) {
140
- chunks.push((0, ts_poet_1.code) `case ${fullName}.${valueDesc.name}: return ${valueDesc.number};`);
147
+ chunks.push((0, ts_poet_1.code) `case ${fullName}.${getMemberName(ctx, fullName, valueDesc)}: return ${valueDesc.number};`);
141
148
  }
142
149
  if (options.unrecognizedEnum) {
143
150
  chunks.push((0, ts_poet_1.code) `
@@ -158,3 +165,12 @@ function generateEnumToNumber(ctx, fullName, enumDesc) {
158
165
  return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
159
166
  }
160
167
  exports.generateEnumToNumber = generateEnumToNumber;
168
+ function getMemberName(ctx, fullName, valueDesc) {
169
+ if (ctx.options.removeEnumPrefix) {
170
+ return valueDesc.name.replace(`${(0, case_1.camelToSnake)(fullName)}_`, "");
171
+ }
172
+ return valueDesc.name;
173
+ }
174
+ function getValueName(ctx, fullName, valueDesc) {
175
+ return valueDesc.name;
176
+ }
@@ -39,6 +39,8 @@ exports.generateGrpcClientImpl = generateGrpcClientImpl;
39
39
  /** Creates the RPC methods that client code actually calls. */
40
40
  function generateRpcMethod(ctx, serviceDesc, methodDesc) {
41
41
  (0, utils_1.assertInstanceOf)(methodDesc, utils_1.FormattedMethodDescriptor);
42
+ const { options } = ctx;
43
+ const { useAbortSignal } = options;
42
44
  const requestMessage = (0, types_1.rawRequestType)(ctx, methodDesc);
43
45
  const inputType = (0, types_1.requestType)(ctx, methodDesc, true);
44
46
  const returns = (0, types_1.responsePromiseOrObservable)(ctx, methodDesc);
@@ -47,6 +49,7 @@ function generateRpcMethod(ctx, serviceDesc, methodDesc) {
47
49
  ${methodDesc.formattedName}(
48
50
  request: ${inputType},
49
51
  metadata?: grpc.Metadata,
52
+ ${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
50
53
  ): ${returns} {
51
54
  throw new Error('ts-proto does not yet support client streaming!');
52
55
  }
@@ -57,10 +60,12 @@ function generateRpcMethod(ctx, serviceDesc, methodDesc) {
57
60
  ${methodDesc.formattedName}(
58
61
  request: ${inputType},
59
62
  metadata?: grpc.Metadata,
63
+ ${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
60
64
  ): ${returns} {
61
65
  return this.rpc.${method}(
62
66
  ${methodDescName(serviceDesc, methodDesc)},
63
67
  ${requestMessage}.fromPartial(request),
68
+ ${useAbortSignal ? "abortSignal," : ""}
64
69
  metadata,
65
70
  );
66
71
  }
@@ -145,6 +150,8 @@ exports.addGrpcWebMisc = addGrpcWebMisc;
145
150
  /** Makes an `Rpc` interface to decouple from the low-level grpc-web `grpc.invoke and grpc.unary`/etc. methods. */
146
151
  function generateGrpcWebRpcType(ctx, returnObservable, hasStreamingMethods) {
147
152
  const chunks = [];
153
+ const { options } = ctx;
154
+ const { useAbortSignal } = options;
148
155
  chunks.push((0, ts_poet_1.code) `interface Rpc {`);
149
156
  const wrapper = returnObservable ? (0, types_1.observableType)(ctx) : "Promise";
150
157
  chunks.push((0, ts_poet_1.code) `
@@ -152,6 +159,7 @@ function generateGrpcWebRpcType(ctx, returnObservable, hasStreamingMethods) {
152
159
  methodDesc: T,
153
160
  request: any,
154
161
  metadata: grpc.Metadata | undefined,
162
+ ${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
155
163
  ): ${wrapper}<any>;
156
164
  `);
157
165
  if (hasStreamingMethods) {
@@ -160,6 +168,7 @@ function generateGrpcWebRpcType(ctx, returnObservable, hasStreamingMethods) {
160
168
  methodDesc: T,
161
169
  request: any,
162
170
  metadata: grpc.Metadata | undefined,
171
+ ${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
163
172
  ): ${(0, types_1.observableType)(ctx)}<any>;
164
173
  `);
165
174
  }
@@ -201,11 +210,23 @@ function generateGrpcWebImpl(ctx, returnObservable, hasStreamingMethods) {
201
210
  return (0, ts_poet_1.joinCode)(chunks, { trim: false });
202
211
  }
203
212
  function createPromiseUnaryMethod(ctx) {
213
+ const { options } = ctx;
214
+ const { useAbortSignal } = options;
215
+ const maybeAbortSignal = useAbortSignal
216
+ ? `
217
+ const abortHandler = () => {
218
+ client.close();
219
+ reject(new Error("Aborted"));
220
+ }
221
+
222
+ if (abortSignal) abortSignal.addEventListener("abort", abortHandler);`
223
+ : "";
204
224
  return (0, ts_poet_1.code) `
205
225
  unary<T extends UnaryMethodDefinitionish>(
206
226
  methodDesc: T,
207
227
  _request: any,
208
- metadata: grpc.Metadata | undefined
228
+ metadata: grpc.Metadata | undefined,
229
+ ${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
209
230
  ): Promise<any> {
210
231
  const request = { ..._request, ...methodDesc.requestType };
211
232
  const maybeCombinedMetadata =
@@ -213,7 +234,7 @@ function createPromiseUnaryMethod(ctx) {
213
234
  ? new ${BrowserHeaders}({ ...this.options?.metadata.headersMap, ...metadata?.headersMap })
214
235
  : metadata || this.options.metadata;
215
236
  return new Promise((resolve, reject) => {
216
- ${grpc}.unary(methodDesc, {
237
+ ${useAbortSignal ? `const client =` : ""} ${grpc}.unary(methodDesc, {
217
238
  request,
218
239
  host: this.host,
219
240
  metadata: maybeCombinedMetadata,
@@ -228,16 +249,29 @@ function createPromiseUnaryMethod(ctx) {
228
249
  }
229
250
  },
230
251
  });
252
+
253
+ ${maybeAbortSignal}
231
254
  });
232
255
  }
233
256
  `;
234
257
  }
235
258
  function createObservableUnaryMethod(ctx) {
259
+ const { options } = ctx;
260
+ const { useAbortSignal } = options;
261
+ const maybeAbortSignal = useAbortSignal
262
+ ? `
263
+ const abortHandler = () => {
264
+ observer.error("Aborted");
265
+ client.close();
266
+ };
267
+ if (abortSignal) abortSignal.addEventListener("abort", abortHandler);`
268
+ : "";
236
269
  return (0, ts_poet_1.code) `
237
270
  unary<T extends UnaryMethodDefinitionish>(
238
271
  methodDesc: T,
239
272
  _request: any,
240
- metadata: grpc.Metadata | undefined
273
+ metadata: grpc.Metadata | undefined,
274
+ ${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
241
275
  ): ${(0, types_1.observableType)(ctx)}<any> {
242
276
  const request = { ..._request, ...methodDesc.requestType };
243
277
  const maybeCombinedMetadata =
@@ -245,7 +279,7 @@ function createObservableUnaryMethod(ctx) {
245
279
  ? new ${BrowserHeaders}({ ...this.options?.metadata.headersMap, ...metadata?.headersMap })
246
280
  : metadata || this.options.metadata;
247
281
  return new Observable(observer => {
248
- ${grpc}.unary(methodDesc, {
282
+ ${useAbortSignal ? `const client =` : ""} ${grpc}.unary(methodDesc, {
249
283
  request,
250
284
  host: this.host,
251
285
  metadata: maybeCombinedMetadata,
@@ -261,16 +295,31 @@ function createObservableUnaryMethod(ctx) {
261
295
  }
262
296
  },
263
297
  });
298
+
299
+
300
+ ${maybeAbortSignal}
301
+
264
302
  }).pipe(${take}(1));
265
303
  }
266
304
  `;
267
305
  }
268
306
  function createInvokeMethod(ctx) {
307
+ const { options } = ctx;
308
+ const { useAbortSignal } = options;
309
+ const maybeAbortSignal = useAbortSignal
310
+ ? `
311
+ const abortHandler = () => {
312
+ observer.error("Aborted");
313
+ client.close();
314
+ };
315
+ if (abortSignal) abortSignal.addEventListener("abort", abortHandler);`
316
+ : "";
269
317
  return (0, ts_poet_1.code) `
270
318
  invoke<T extends UnaryMethodDefinitionish>(
271
319
  methodDesc: T,
272
320
  _request: any,
273
- metadata: grpc.Metadata | undefined
321
+ metadata: grpc.Metadata | undefined,
322
+ ${useAbortSignal ? "abortSignal?: AbortSignal," : ""}
274
323
  ): ${(0, types_1.observableType)(ctx)}<any> {
275
324
  const upStreamCodes = this.options.upStreamRetryCodes || [];
276
325
  const DEFAULT_TIMEOUT_TIME: number = 3_000;
@@ -301,7 +350,11 @@ function createInvokeMethod(ctx) {
301
350
  }
302
351
  },
303
352
  });
304
- observer.add(() => client.close());
353
+ observer.add(() => {
354
+ if (!observer.closed) return client.close()
355
+ });
356
+
357
+ ${maybeAbortSignal}
305
358
  });
306
359
  upStream();
307
360
  }).pipe(${share}());
@@ -39,9 +39,6 @@ function generateService(ctx, fileDesc, sourceInfo, serviceDesc) {
39
39
  const partialInput = options.outputClientImpl === "grpc-web";
40
40
  const inputType = (0, types_1.requestType)(ctx, methodDesc, partialInput);
41
41
  params.push((0, ts_poet_1.code) `request: ${inputType}`);
42
- if (options.useAbortSignal) {
43
- params.push((0, ts_poet_1.code) `abortSignal?: AbortSignal`);
44
- }
45
42
  // Use metadata as last argument for interface only configuration
46
43
  if (options.outputClientImpl === "grpc-web") {
47
44
  // We have to use grpc.Metadata where grpc will come from @improbable-eng
@@ -56,6 +53,9 @@ function generateService(ctx, fileDesc, sourceInfo, serviceDesc) {
56
53
  const Metadata = (0, ts_poet_1.imp)(options.metadataType);
57
54
  params.push((0, ts_poet_1.code) `metadata?: ${Metadata}`);
58
55
  }
56
+ if (options.useAbortSignal) {
57
+ params.push((0, ts_poet_1.code) `abortSignal?: AbortSignal`);
58
+ }
59
59
  if (options.addNestjsRestParameter) {
60
60
  params.push((0, ts_poet_1.code) `...rest: any`);
61
61
  }
package/build/main.js CHANGED
@@ -82,7 +82,9 @@ function generateFile(ctx, fileDesc) {
82
82
  const fullTypeName = (0, utils_1.maybePrefixPackage)(fileDesc, fullProtoTypeName);
83
83
  const outputWrapAndUnwrap = (0, generate_struct_wrappers_1.isWrapperType)(fullTypeName);
84
84
  // Only decode, fromPartial, and wrap use the createBase method
85
- if (options.outputEncodeMethods || options.outputPartialMethods || outputWrapAndUnwrap) {
85
+ if ((options.outputEncodeMethods && options.outputEncodeMethods !== "encode-no-creation") ||
86
+ options.outputPartialMethods ||
87
+ outputWrapAndUnwrap) {
86
88
  chunks.push(generateBaseInstanceFactory(ctx, fullName, message, fullTypeName));
87
89
  }
88
90
  const staticMembers = [];
@@ -90,8 +92,14 @@ function generateFile(ctx, fileDesc) {
90
92
  staticMembers.push((0, ts_poet_1.code) `$type: '${fullTypeName}' as const`);
91
93
  }
92
94
  if (options.outputEncodeMethods) {
93
- staticMembers.push(generateEncode(ctx, fullName, message));
94
- staticMembers.push(generateDecode(ctx, fullName, message));
95
+ if (options.outputEncodeMethods === true ||
96
+ options.outputEncodeMethods === "encode-only" ||
97
+ options.outputEncodeMethods === "encode-no-creation") {
98
+ staticMembers.push(generateEncode(ctx, fullName, message));
99
+ }
100
+ if (options.outputEncodeMethods === true || options.outputEncodeMethods === "decode-only") {
101
+ staticMembers.push(generateDecode(ctx, fullName, message));
102
+ }
95
103
  }
96
104
  if (options.useAsyncIterable) {
97
105
  staticMembers.push((0, generate_async_iterable_1.generateEncodeTransform)(fullName));
package/build/options.js CHANGED
@@ -52,6 +52,7 @@ function defaultOptions() {
52
52
  outputTypeRegistry: false,
53
53
  stringEnums: false,
54
54
  constEnums: false,
55
+ removeEnumPrefix: false,
55
56
  enumsAsLiterals: false,
56
57
  outputClientImpl: true,
57
58
  outputServices: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.139.0",
3
+ "version": "1.141.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",