ts-proto 1.120.0 → 1.121.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## [1.121.2](https://github.com/stephenh/ts-proto/compare/v1.121.1...v1.121.2) (2022-08-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Fix push_to_buf_registry check. ([22ac914](https://github.com/stephenh/ts-proto/commit/22ac914cd8626258ceb35fd435b899a819518988))
7
+
8
+ ## [1.121.1](https://github.com/stephenh/ts-proto/compare/v1.121.0...v1.121.1) (2022-07-28)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Revert "feat: support grpc-web client straming ([#617](https://github.com/stephenh/ts-proto/issues/617))" ([#632](https://github.com/stephenh/ts-proto/issues/632)) ([2f4ecc7](https://github.com/stephenh/ts-proto/commit/2f4ecc7434df6b8f2ff08b929f9032170b04e858))
14
+
15
+ # [1.121.0](https://github.com/stephenh/ts-proto/compare/v1.120.0...v1.121.0) (2022-07-28)
16
+
17
+
18
+ ### Features
19
+
20
+ * Add use-numeric-enum-json option. ([#625](https://github.com/stephenh/ts-proto/issues/625)) ([cd53d8c](https://github.com/stephenh/ts-proto/commit/cd53d8cacd6b4b8fa6517242020b216dd18eebdf))
21
+
1
22
  # [1.120.0](https://github.com/stephenh/ts-proto/compare/v1.119.0...v1.120.0) (2022-07-21)
2
23
 
3
24
 
package/README.markdown CHANGED
@@ -435,6 +435,8 @@ Generated code will be placed in the Gradle build directory.
435
435
  Requires `onlyTypes=true`. Implies `useDate=string` and `stringEnums=true`. This option is to generate types that can be directly used with marshalling/unmarshalling Protobuf messages serialized as JSON.
436
436
  You may also want to set `useOptionals=all`, as gRPC gateways are not required to send default value for scalar values.
437
437
 
438
+ - With `--ts_proto_opt=useNumericEnumForJson=true`, the JSON converter (`toJSON`) will encode enum values as int, rather than a string literal.
439
+
438
440
  ### NestJS Support
439
441
 
440
442
  We have a great way of working together with [nestjs](https://docs.nestjs.com/microservices/grpc). `ts-proto` generates `interfaces` and `decorators` for you controller, client. For more information see the [nestjs readme](NESTJS.markdown).
package/build/enums.js CHANGED
@@ -91,17 +91,31 @@ function generateEnumToJson(ctx, fullName, enumDesc) {
91
91
  const { options, utils } = ctx;
92
92
  const chunks = [];
93
93
  const functionName = (0, case_1.camelCase)(fullName) + 'ToJSON';
94
- chunks.push((0, ts_poet_1.code) `export function ${(0, ts_poet_1.def)(functionName)}(object: ${fullName}): string {`);
94
+ chunks.push((0, ts_poet_1.code) `export function ${(0, ts_poet_1.def)(functionName)}(object: ${fullName}): ${ctx.options.useNumericEnumForJson ? 'number' : 'string'} {`);
95
95
  chunks.push((0, ts_poet_1.code) `switch (object) {`);
96
96
  for (const valueDesc of enumDesc.value) {
97
- chunks.push((0, ts_poet_1.code) `case ${fullName}.${valueDesc.name}: return "${valueDesc.name}";`);
97
+ if (ctx.options.useNumericEnumForJson) {
98
+ chunks.push((0, ts_poet_1.code) `case ${fullName}.${valueDesc.name}: return ${valueDesc.number};`);
99
+ }
100
+ else {
101
+ chunks.push((0, ts_poet_1.code) `case ${fullName}.${valueDesc.name}: return "${valueDesc.name}";`);
102
+ }
98
103
  }
99
104
  if (options.unrecognizedEnum) {
100
105
  chunks.push((0, ts_poet_1.code) `
101
- case ${fullName}.${UNRECOGNIZED_ENUM_NAME}:
106
+ case ${fullName}.${UNRECOGNIZED_ENUM_NAME}:`);
107
+ if (ctx.options.useNumericEnumForJson) {
108
+ chunks.push((0, ts_poet_1.code) `
109
+ default:
110
+ return ${UNRECOGNIZED_ENUM_VALUE};
111
+ `);
112
+ }
113
+ else {
114
+ chunks.push((0, ts_poet_1.code) `
102
115
  default:
103
116
  return "${UNRECOGNIZED_ENUM_NAME}";
104
117
  `);
118
+ }
105
119
  }
106
120
  else {
107
121
  // We use globalThis to avoid conflicts on protobuf types named `Error`.
@@ -18,7 +18,7 @@ function generateGrpcClientImpl(ctx, _fileDesc, serviceDesc) {
18
18
  // Create the constructor(rpc: Rpc)
19
19
  chunks.push((0, ts_poet_1.code) `
20
20
  private readonly rpc: Rpc;
21
-
21
+
22
22
  constructor(rpc: Rpc) {
23
23
  `);
24
24
  chunks.push((0, ts_poet_1.code) `this.rpc = rpc;`);
@@ -46,11 +46,9 @@ function generateRpcMethod(ctx, serviceDesc, methodDesc) {
46
46
  return (0, ts_poet_1.code) `
47
47
  ${methodDesc.formattedName}(
48
48
  request: ${inputType},
49
- options?: {
50
- metadata?: grpc.Metadata,
51
- rpcOptions?: grpc.RpcOptions,
52
- }): ${returns} {
53
- return this.rpc.stream(${methodDescName(serviceDesc, methodDesc)}, request, options?.metadata, options?.rpcOptions)
49
+ metadata?: grpc.Metadata,
50
+ ): ${returns} {
51
+ throw new Error('ts-proto does not yet support client streaming!');
54
52
  }
55
53
  `;
56
54
  }
@@ -85,7 +83,7 @@ exports.generateGrpcServiceDesc = generateGrpcServiceDesc;
85
83
  * implementation.
86
84
  */
87
85
  function generateGrpcMethodDesc(ctx, serviceDesc, methodDesc) {
88
- const inputType = (0, types_1.rawRequestType)(ctx, methodDesc);
86
+ const inputType = (0, types_1.requestType)(ctx, methodDesc);
89
87
  const outputType = (0, types_1.responseType)(ctx, methodDesc);
90
88
  // grpc-web expects this to be a class, but the ts-proto messages are just interfaces.
91
89
  //
@@ -111,15 +109,13 @@ function generateGrpcMethodDesc(ctx, serviceDesc, methodDesc) {
111
109
  deserializeBinary(data: Uint8Array) {
112
110
  return { ...${outputType}.decode(data), toObject() { return this; } };
113
111
  }
114
- }`;
115
- const streaming = methodDesc.clientStreaming || methodDesc.serverStreaming;
116
- const methodDef = streaming ? 'MethodDefinitionish' : 'UnaryMethodDefinitionish';
112
+ }`;
117
113
  return (0, ts_poet_1.code) `
118
- export const ${methodDescName(serviceDesc, methodDesc)}: ${methodDef} = {
114
+ export const ${methodDescName(serviceDesc, methodDesc)}: UnaryMethodDefinitionish = {
119
115
  methodName: "${methodDesc.name}",
120
116
  service: ${serviceDesc.name}Desc,
121
- requestStream: ${methodDesc.clientStreaming ? true : false},
122
- responseStream: ${methodDesc.serverStreaming ? true : false},
117
+ requestStream: false,
118
+ responseStream: ${methodDesc.serverStreaming ? 'true' : 'false'},
123
119
  requestType: ${requestFn} as any,
124
120
  responseType: ${responseFn} as any,
125
121
  };
@@ -137,10 +133,6 @@ function addGrpcWebMisc(ctx, hasStreamingMethods) {
137
133
  interface UnaryMethodDefinitionishR extends ${grpc}.UnaryMethodDefinition<any, any> { requestStream: any; responseStream: any; }
138
134
  `);
139
135
  chunks.push((0, ts_poet_1.code) `type UnaryMethodDefinitionish = UnaryMethodDefinitionishR;`);
140
- chunks.push((0, ts_poet_1.code) `
141
- interface MethodDefinitionishR extends ${grpc}.MethodDefinition<any, any> { requestStream: any; responseStream: any; }
142
- `);
143
- chunks.push((0, ts_poet_1.code) `type MethodDefinitionish = MethodDefinitionishR;`);
144
136
  chunks.push(generateGrpcWebRpcType(ctx, options.returnObservable, hasStreamingMethods));
145
137
  chunks.push(generateGrpcWebImpl(ctx, options.returnObservable, hasStreamingMethods));
146
138
  return (0, ts_poet_1.joinCode)(chunks, { on: '\n\n' });
@@ -164,14 +156,8 @@ function generateGrpcWebRpcType(ctx, returnObservable, hasStreamingMethods) {
164
156
  methodDesc: T,
165
157
  request: any,
166
158
  metadata: grpc.Metadata | undefined,
167
- ): ${(0, types_1.observableType)(ctx)}<any>;`);
168
- chunks.push((0, ts_poet_1.code) `
169
- stream<T extends MethodDefinitionish>(
170
- methodDesc: T,
171
- request: ${(0, types_1.observableType)(ctx)}<any>,
172
- metadata: grpc.Metadata | undefined,
173
- rpcOptions: grpc.RpcOptions | undefined
174
- ): ${(0, types_1.observableType)(ctx)}<any>;`);
159
+ ): ${(0, types_1.observableType)(ctx)}<any>;
160
+ `);
175
161
  }
176
162
  chunks.push((0, ts_poet_1.code) `}`);
177
163
  return (0, ts_poet_1.joinCode)(chunks, { on: '\n' });
@@ -192,7 +178,7 @@ function generateGrpcWebImpl(ctx, returnObservable, hasStreamingMethods) {
192
178
  export class GrpcWebImpl {
193
179
  private host: string;
194
180
  private options: ${options};
195
-
181
+
196
182
  constructor(host: string, options: ${options}) {
197
183
  this.host = host;
198
184
  this.options = options;
@@ -206,7 +192,6 @@ function generateGrpcWebImpl(ctx, returnObservable, hasStreamingMethods) {
206
192
  }
207
193
  if (hasStreamingMethods) {
208
194
  chunks.push(createInvokeMethod(ctx));
209
- chunks.push(createStreamMethod(ctx));
210
195
  }
211
196
  chunks.push((0, ts_poet_1.code) `}`);
212
197
  return (0, ts_poet_1.joinCode)(chunks, { trim: false });
@@ -274,7 +259,7 @@ function createObservableUnaryMethod(ctx) {
274
259
  },
275
260
  });
276
261
  }).pipe(${take}(1));
277
- }
262
+ }
278
263
  `;
279
264
  }
280
265
  function createInvokeMethod(ctx) {
@@ -320,50 +305,3 @@ function createInvokeMethod(ctx) {
320
305
  }
321
306
  `;
322
307
  }
323
- function createStreamMethod(ctx) {
324
- return (0, ts_poet_1.code) `
325
- stream<T extends MethodDefinitionish>(
326
- methodDesc: T,
327
- _request: ${(0, types_1.observableType)(ctx)}<any>,
328
- metadata: ${grpc}.Metadata | undefined,
329
- rpcOptions: ${grpc}.RpcOptions | undefined
330
- ): ${(0, types_1.observableType)(ctx)}<any> {
331
- const defaultOptions = {
332
- host: this.host,
333
- debug: rpcOptions?.debug || this.options.debug,
334
- transport: rpcOptions?.transport || this.options.streamingTransport || this.options.transport,
335
- }
336
-
337
- let started = false;
338
- const client = ${grpc}.client(methodDesc, defaultOptions);
339
-
340
- const subscription = _request.subscribe((_req: any) => {
341
- const request = { ..._req, ...methodDesc.requestType };
342
- if (!started) {
343
- client.start(metadata);
344
- started = true;
345
- }
346
- client.send(request);
347
- })
348
-
349
- subscription.add(() => {
350
- client.finishSend();
351
- })
352
-
353
- return new Observable((observer) => {
354
- client.onEnd((code: ${grpc}.Code, message: string, trailers: ${grpc}.Metadata) => {
355
- subscription.unsubscribe();
356
- if (code === 0) {
357
- observer.complete();
358
- } else {
359
- observer.error(new Error(\`Error \${code} \${message}\`));
360
- }
361
- })
362
- client.onMessage((res: any) => {
363
- observer.next(res);
364
- })
365
- observer.add(() => client.close())
366
- }).pipe(share());
367
- }
368
- `;
369
- }
@@ -42,14 +42,7 @@ function generateService(ctx, fileDesc, sourceInfo, serviceDesc) {
42
42
  // Use metadata as last argument for interface only configuration
43
43
  if (options.outputClientImpl === 'grpc-web') {
44
44
  // We have to use grpc.Metadata where grpc will come from @improbable-eng
45
- if (methodDesc.clientStreaming) {
46
- params.push((0, ts_poet_1.code) `options?: {
47
- metadata?: grpc.Metadata,
48
- rpcOptions?: grpc.RpcOptions}`);
49
- }
50
- else {
51
- params.push((0, ts_poet_1.code) `metadata?: grpc.Metadata`);
52
- }
45
+ params.push((0, ts_poet_1.code) `metadata?: grpc.Metadata`);
53
46
  }
54
47
  else if (options.addGrpcMetadata) {
55
48
  const Metadata = (0, ts_poet_1.imp)('Metadata@@grpc/grpc-js');
package/build/main.js CHANGED
@@ -115,6 +115,7 @@ function generateFile(ctx, fileDesc) {
115
115
  }
116
116
  }, options);
117
117
  }
118
+ let hasServerStreamingMethods = false;
118
119
  let hasStreamingMethods = false;
119
120
  (0, visit_1.visitServices)(fileDesc, sourceInfo, (serviceDesc, sInfo) => {
120
121
  if (options.nestJs) {
@@ -154,7 +155,12 @@ function generateFile(ctx, fileDesc) {
154
155
  chunks.push((0, generate_grpc_web_1.generateGrpcClientImpl)(ctx, fileDesc, serviceDesc));
155
156
  chunks.push((0, generate_grpc_web_1.generateGrpcServiceDesc)(fileDesc, serviceDesc));
156
157
  serviceDesc.method.forEach((method) => {
157
- chunks.push((0, generate_grpc_web_1.generateGrpcMethodDesc)(ctx, serviceDesc, method));
158
+ if (!method.clientStreaming) {
159
+ chunks.push((0, generate_grpc_web_1.generateGrpcMethodDesc)(ctx, serviceDesc, method));
160
+ }
161
+ if (method.serverStreaming) {
162
+ hasServerStreamingMethods = true;
163
+ }
158
164
  });
159
165
  }
160
166
  }
@@ -173,7 +179,7 @@ function generateFile(ctx, fileDesc) {
173
179
  chunks.push((0, generate_services_1.generateRpcType)(ctx, hasStreamingMethods));
174
180
  }
175
181
  else if (options.outputClientImpl === 'grpc-web') {
176
- chunks.push((0, generate_grpc_web_1.addGrpcWebMisc)(ctx, hasStreamingMethods));
182
+ chunks.push((0, generate_grpc_web_1.addGrpcWebMisc)(ctx, hasServerStreamingMethods));
177
183
  }
178
184
  }
179
185
  if (options.context) {
@@ -1481,7 +1487,11 @@ function generateWrap(ctx, fullProtoTypeName, fieldNames) {
1481
1487
  }
1482
1488
  if ((0, types_1.isFieldMaskTypeName)(fullProtoTypeName)) {
1483
1489
  chunks.push((0, ts_poet_1.code) `wrap(paths: string[]): FieldMask {
1484
- return {paths: paths};
1490
+ const result = createBaseFieldMask();
1491
+
1492
+ result.paths = paths;
1493
+
1494
+ return result;
1485
1495
  }`);
1486
1496
  }
1487
1497
  return chunks;
package/build/options.js CHANGED
@@ -70,6 +70,7 @@ function defaultOptions() {
70
70
  unknownFields: false,
71
71
  usePrototypeForDefaults: false,
72
72
  useJsonWireFormat: false,
73
+ useNumericEnumForJson: false,
73
74
  };
74
75
  }
75
76
  exports.defaultOptions = defaultOptions;
package/build/types.js CHANGED
@@ -641,7 +641,7 @@ function responseObservable(ctx, methodDesc) {
641
641
  exports.responseObservable = responseObservable;
642
642
  function responsePromiseOrObservable(ctx, methodDesc) {
643
643
  const { options } = ctx;
644
- if (options.returnObservable || methodDesc.serverStreaming || methodDesc.clientStreaming) {
644
+ if (options.returnObservable || methodDesc.serverStreaming) {
645
645
  return responseObservable(ctx, methodDesc);
646
646
  }
647
647
  return responsePromise(ctx, methodDesc);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.120.0",
3
+ "version": "1.121.2",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",