ts-proto 1.164.2 → 1.165.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
@@ -19,10 +19,10 @@
19
19
  - [Highlights](#highlights)
20
20
  - [Auto-Batching / N+1 Prevention](#auto-batching--n1-prevention)
21
21
  - [Usage](#usage)
22
- - [Supported options](#supported-options)
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)
@@ -121,8 +121,8 @@ plugins:
121
121
 
122
122
  If you're using a modern TS setup with either `esModuleInterop` or running in an ESM environment, you'll need to pass `ts_proto_opt`s of:
123
123
 
124
- * `esModuleInterop=true` if using `esModuleInterop` in your `tsconfig.json`, and
125
- * `importSuffix=.js` if executing the generated ts-proto code in an ESM environment
124
+ - `esModuleInterop=true` if using `esModuleInterop` in your `tsconfig.json`, and
125
+ - `importSuffix=.js` if executing the generated ts-proto code in an ESM environment
126
126
 
127
127
  # Goals
128
128
 
@@ -448,9 +448,11 @@ Generated code will be placed in the Gradle build directory.
448
448
 
449
449
  - With `--ts_proto_opt=outputServices=false`, or `=none`, ts-proto will output NO service definitions.
450
450
 
451
- - With `--ts_proto_opt=outputBeforeRequest=true`, ts-proto will add a function definition to the Rpc interface definition with the signature: `beforeRequest(request: <RequestType>)`. It will will also automatically set `outputTypeRegistry=true` and `outputServices=true`. Each of the Service's methods will call `beforeRequest` before performing it's request.
451
+ - With `--ts_proto_opt=rpcBeforeRequest=true`, ts-proto will add a function definition to the Rpc interface definition with the signature: `beforeRequest(service: string, message: string, request: <RequestType>)`. It will will also automatically set `outputServices=default`. Each of the Service's methods will call `beforeRequest` before performing it's request.
452
452
 
453
- - With `--ts_proto_opt=outputAfterResponse=true`, ts-proto will add a function definition to the Rpc interface definition with the signature: `afterResponse(response: <ResponseType>)`. It will will also automatically set `outputTypeRegistry=true` and `outputServices=true`. Each of the Service's methods will call `afterResponse` before returning the response.
453
+ - With `--ts_proto_opt=rpcAfterResponse=true`, ts-proto will add a function definition to the Rpc interface definition with the signature: `afterResponse(service: string, message: string, response: <ResponseType>)`. It will will also automatically set `outputServices=default`. Each of the Service's methods will call `afterResponse` before returning the response.
454
+
455
+ - With `--ts_proto_opt=rpcErrorHandler=true`, ts-proto will add a function definition to the Rpc interface definition with the signature: `handleError(service: string, message: string, error: Error)`. It will will also automatically set `outputServices=default`.
454
456
 
455
457
  - With `--ts_proto_opt=useAbortSignal=true`, the generated services will accept an `AbortSignal` to cancel RPC calls.
456
458
 
@@ -87,23 +87,32 @@ function generateRegularRpcMethod(ctx, methodDesc) {
87
87
  ];
88
88
  const maybeCtx = options.context ? "ctx," : "";
89
89
  const maybeAbortSignal = options.useAbortSignal ? "abortSignal || undefined," : "";
90
+ let errorHandler;
91
+ if (options.rpcErrorHandler) {
92
+ errorHandler = (0, ts_poet_1.code) `
93
+ if (error instanceof Error && this.rpc.handleError) {
94
+ return Promise.reject(this.rpc.handleError(this.service, "${methodDesc.name}", error));
95
+ }
96
+ return Promise.reject(error);
97
+ `;
98
+ }
90
99
  let encode = (0, ts_poet_1.code) `${rawInputType}.encode(request).finish()`;
91
100
  let beforeRequest;
92
- if (options.outputBeforeRequest) {
101
+ if (options.rpcBeforeRequest) {
93
102
  beforeRequest = (0, ts_poet_1.code) `
94
103
  if (this.rpc.beforeRequest) {
95
- this.rpc.beforeRequest(request);
104
+ this.rpc.beforeRequest(this.service, "${methodDesc.name}", request);
96
105
  }`;
97
106
  }
98
- let decode = (0, ts_poet_1.code) `data => ${rawOutputType}.decode(${Reader}.create(data))`;
99
- if (options.outputAfterResponse) {
100
- decode = (0, ts_poet_1.code) `data => {
107
+ let decode = (0, ts_poet_1.code) `${rawOutputType}.decode(${Reader}.create(data))`;
108
+ if (options.rpcAfterResponse) {
109
+ decode = (0, ts_poet_1.code) `
101
110
  const response = ${rawOutputType}.decode(${Reader}.create(data));
102
111
  if (this.rpc.afterResponse) {
103
- this.rpc.afterResponse(response);
112
+ this.rpc.afterResponse(this.service, "${methodDesc.name}", response);
104
113
  }
105
114
  return response;
106
- }`;
115
+ `;
107
116
  }
108
117
  // if (options.useDate && rawOutputType.toString().includes("Timestamp")) {
109
118
  // decode = code`data => ${utils.fromTimestamp}(${rawOutputType}.decode(${Reader}.create(data)))`;
@@ -116,19 +125,13 @@ function generateRegularRpcMethod(ctx, methodDesc) {
116
125
  encode = (0, ts_poet_1.code) `request.pipe(${(0, ts_poet_1.imp)("map@rxjs/operators")}(request => ${encode}))`;
117
126
  }
118
127
  }
128
+ const returnStatement = createDefaultServiceReturn(ctx, methodDesc, decode, errorHandler);
119
129
  let returnVariable;
120
130
  if (options.returnObservable || methodDesc.serverStreaming) {
121
131
  returnVariable = "result";
122
- if (options.useAsyncIterable) {
123
- decode = (0, ts_poet_1.code) `${rawOutputType}.decodeTransform(result)`;
124
- }
125
- else {
126
- decode = (0, ts_poet_1.code) `result.pipe(${(0, ts_poet_1.imp)("map@rxjs/operators")}(${decode}))`;
127
- }
128
132
  }
129
133
  else {
130
134
  returnVariable = "promise";
131
- decode = (0, ts_poet_1.code) `promise.then(${decode})`;
132
135
  }
133
136
  let rpcMethod;
134
137
  if (methodDesc.clientStreaming && methodDesc.serverStreaming) {
@@ -155,10 +158,33 @@ function generateRegularRpcMethod(ctx, methodDesc) {
155
158
  data,
156
159
  ${maybeAbortSignal}
157
160
  );
158
- return ${decode};
161
+ return ${returnStatement};
159
162
  }
160
163
  `;
161
164
  }
165
+ function createDefaultServiceReturn(ctx, methodDesc, decode, errorHandler) {
166
+ const { options } = ctx;
167
+ const rawOutputType = (0, types_1.responseType)(ctx, methodDesc, { keepValueType: true });
168
+ if (options.returnObservable || methodDesc.serverStreaming) {
169
+ if (options.useAsyncIterable) {
170
+ return (0, ts_poet_1.code) `${rawOutputType}.decodeTransform(result)`;
171
+ }
172
+ else {
173
+ return (0, ts_poet_1.code) `result.pipe(${(0, ts_poet_1.imp)("map@rxjs/operators")}(data => ${decode}))`;
174
+ }
175
+ }
176
+ if (errorHandler) {
177
+ let tryBlock = decode;
178
+ if (!options.rpcAfterResponse) {
179
+ tryBlock = (0, ts_poet_1.code) `return ${decode}`;
180
+ }
181
+ return (0, ts_poet_1.code) `promise.then(data => { ${(0, utils_1.tryCatchBlock)(tryBlock, (0, ts_poet_1.code) `return Promise.reject(error);`)}}).catch((error) => { ${errorHandler} })`;
182
+ }
183
+ else if (options.rpcAfterResponse) {
184
+ return (0, ts_poet_1.code) `promise.then(data => { ${decode} } )`;
185
+ }
186
+ return (0, ts_poet_1.code) `promise.then(data => ${decode})`;
187
+ }
162
188
  function generateServiceClientImpl(ctx, fileDesc, serviceDesc) {
163
189
  const { options } = ctx;
164
190
  const chunks = [];
@@ -302,11 +328,14 @@ function generateRpcType(ctx, hasStreamingMethods) {
302
328
  const maybeAbortSignalParam = options.useAbortSignal ? "abortSignal?: AbortSignal," : "";
303
329
  const methods = [[(0, ts_poet_1.code) `request`, (0, ts_poet_1.code) `Uint8Array`, (0, ts_poet_1.code) `Promise<Uint8Array>`]];
304
330
  const additionalMethods = [];
305
- if (options.outputBeforeRequest) {
306
- additionalMethods.push((0, ts_poet_1.code) `beforeRequest?<T extends { [k in keyof T]: unknown }>(request: T): void;`);
331
+ if (options.rpcBeforeRequest) {
332
+ additionalMethods.push((0, ts_poet_1.code) `beforeRequest?<T extends { [k in keyof T]: unknown }>(service: string, method: string, request: T): void;`);
333
+ }
334
+ if (options.rpcAfterResponse) {
335
+ additionalMethods.push((0, ts_poet_1.code) `afterResponse?<T extends { [k in keyof T]: unknown }>(service: string, method: string, response: T): void;`);
307
336
  }
308
- if (options.outputAfterResponse) {
309
- additionalMethods.push((0, ts_poet_1.code) `afterResponse?<T extends { [k in keyof T]: unknown }>(response: T): void;`);
337
+ if (options.rpcErrorHandler) {
338
+ additionalMethods.push((0, ts_poet_1.code) `handleError?(service: string, method: string, error: Error): Error;`);
310
339
  }
311
340
  if (hasStreamingMethods) {
312
341
  const observable = (0, types_1.observableType)(ctx, true);
package/build/options.js CHANGED
@@ -93,8 +93,9 @@ function defaultOptions() {
93
93
  outputExtensions: false,
94
94
  outputIndex: false,
95
95
  M: {},
96
- outputBeforeRequest: false,
97
- outputAfterResponse: false,
96
+ rpcBeforeRequest: false,
97
+ rpcAfterResponse: false,
98
+ rpcErrorHandler: false,
98
99
  };
99
100
  }
100
101
  exports.defaultOptions = defaultOptions;
@@ -183,8 +184,12 @@ function optionsFromParameter(parameter) {
183
184
  if (options.outputIndex) {
184
185
  options.exportCommonSymbols = false;
185
186
  }
186
- if (options.outputBeforeRequest || options.outputAfterResponse) {
187
+ if (options.rpcBeforeRequest || options.rpcAfterResponse || options.rpcErrorHandler) {
188
+ const includesGeneric = options.outputServices.includes(ServiceOption.GENERIC);
187
189
  options.outputServices = [ServiceOption.DEFAULT];
190
+ if (includesGeneric) {
191
+ options.outputServices.push(ServiceOption.GENERIC);
192
+ }
188
193
  }
189
194
  if (options.unrecognizedEnumValue) {
190
195
  // Make sure to cast number options to an actual number
package/build/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.impProto = exports.impFile = exports.getPropertyAccessor = exports.safeAccessor = exports.getFieldName = exports.getFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.prefixDisableLinter = exports.maybeAddComment = exports.upperFirst = exports.lowerFirst = exports.singular = exports.fail = exports.readToBuffer = exports.generateIndexFiles = exports.protoFilesToGenerate = void 0;
3
+ exports.tryCatchBlock = exports.impProto = exports.impFile = exports.getPropertyAccessor = exports.safeAccessor = exports.getFieldName = exports.getFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.prefixDisableLinter = 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");
@@ -243,3 +243,11 @@ function impProto(options, module, type) {
243
243
  return (0, ts_poet_1.imp)(`${prefix}${type}@./${module}${options.fileSuffix}${options.importSuffix}`);
244
244
  }
245
245
  exports.impProto = impProto;
246
+ function tryCatchBlock(tryBlock, handleErrorBlock) {
247
+ return (0, ts_poet_1.code) `try {
248
+ ${tryBlock}
249
+ } catch (error) {
250
+ ${handleErrorBlock}
251
+ }`;
252
+ }
253
+ exports.tryCatchBlock = tryCatchBlock;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.164.2",
3
+ "version": "1.165.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",
@@ -15,7 +15,7 @@
15
15
  "proto2bin-node": "docker compose run --rm node update-bins.sh",
16
16
  "proto2pbjs": "docker compose run --rm protoc pbjs.sh",
17
17
  "bin2ts": "docker compose run --rm protoc codegen.sh",
18
- "test": "yarn jest -c jest.config.js --maxWorkers=2",
18
+ "test": "yarn jest -c jest.config.js",
19
19
  "tsc:check": "./tsc-check.sh tsconfig.json tests/tsconfig.json integration/tsconfig.json integration/tsconfig.proto.json protos/tsconfig.json",
20
20
  "format": "prettier --write {src,tests}/**/*.ts integration/*.ts",
21
21
  "format:check": "prettier --list-different {src,tests}/**/*.ts",