ts-proto 2.12.4 → 2.13.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
@@ -264,7 +264,7 @@ When ts-proto recognizes methods of this pattern, it will automatically create a
264
264
 
265
265
  This provides the client code with the illusion that it can make individual `Get<OperationName>` calls (which is generally preferable/easier when implementing the client's business logic), but the actual implementation that ts-proto provides will end up making `Batch<OperationName>` calls to the backend service.
266
266
 
267
- You also need to enable the `useContext=true` build-time parameter, which gives all client methods a Go-style `ctx` parameter, with a `getDataLoaders` method that lets ts-proto cache/resolve request-scoped [DataLoaders](https://github.com/graphql/dataloader), which provide the fundamental auto-batch detection/flushing behavior.
267
+ You also need `context=true`, which adds a Go-style `ctx` parameter to every client method. Your `ctx` must implement `getDataLoader`, which ts-proto uses to cache request-scoped [DataLoaders](https://github.com/graphql/dataloader) that handle batch detection and flushing. If you want `ctx` for tracing/metadata only, pass `useContextDataloaders=false` to skip the DataLoader contract.
268
268
 
269
269
  See the `batching.proto` file and related tests for examples/more details.
270
270
 
@@ -317,6 +317,8 @@ Generated code will be placed in the Gradle build directory.
317
317
 
318
318
  - With `--ts_proto_opt=context=true`, the services will have a Go-style `ctx` parameter, which is useful for tracing/logging/etc. if you're not using node's `async_hooks` api due to performance reasons.
319
319
 
320
+ By default `Context` must extend a generated `DataLoaders` interface so ts-proto can emit DataLoader-backed wrappers around `Get*`/`Batch*` methods. Pass `useContextDataloaders=false` to drop the constraint and skip those wrappers when you only need `ctx` for tracing/metadata.
321
+
320
322
  - With `--ts_proto_opt=forceLong=long`, all 64-bit numbers will be parsed as instances of `Long` (using the [long](https://www.npmjs.com/package/long) library).
321
323
 
322
324
  With `--ts_proto_opt=forceLong=string`, all 64-bit numbers will be output as strings.
@@ -13,7 +13,7 @@ function generateNestjsServiceController(ctx, fileDesc, sourceInfo, serviceDesc)
13
13
  const chunks = [];
14
14
  const Metadata = (0, ts_poet_1.imp)("t:Metadata@@grpc/grpc-js");
15
15
  (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, serviceDesc.options?.deprecated);
16
- const t = options.context ? `<${main_1.contextTypeVar}>` : "";
16
+ const t = options.context ? `<${(0, main_1.contextTypeVar)(options)}>` : "";
17
17
  chunks.push((0, ts_poet_1.code) `
18
18
  export interface ${serviceDesc.name}Controller${t} {
19
19
  `);
@@ -53,7 +53,7 @@ function generateNestjsServiceController(ctx, fileDesc, sourceInfo, serviceDesc)
53
53
  chunks.push((0, ts_poet_1.code) `
54
54
  ${methodDesc.formattedName}(${(0, ts_poet_1.joinCode)(params, { on: ", " })}): ${returns};
55
55
  `);
56
- if (options.context) {
56
+ if (options.context && options.useContextDataloaders) {
57
57
  const batchMethod = (0, types_1.detectBatchMethod)(ctx, fileDesc, serviceDesc, methodDesc);
58
58
  if (batchMethod) {
59
59
  const maybeCtx = options.context ? "ctx: Context," : "";
@@ -74,7 +74,7 @@ function generateNestjsServiceClient(ctx, fileDesc, sourceInfo, serviceDesc) {
74
74
  const chunks = [];
75
75
  const Metadata = (0, ts_poet_1.imp)("t:Metadata@@grpc/grpc-js");
76
76
  (0, utils_1.maybeAddComment)(options, sourceInfo, chunks);
77
- const t = options.context ? `<${main_1.contextTypeVar}>` : ``;
77
+ const t = options.context ? `<${(0, main_1.contextTypeVar)(options)}>` : ``;
78
78
  chunks.push((0, ts_poet_1.code) `
79
79
  export interface ${serviceDesc.name}Client${t} {
80
80
  `);
@@ -102,7 +102,7 @@ function generateNestjsServiceClient(ctx, fileDesc, sourceInfo, serviceDesc) {
102
102
  ${(0, ts_poet_1.joinCode)(params, { on: "," })}
103
103
  ): ${returns};
104
104
  `);
105
- if (options.context) {
105
+ if (options.context && options.useContextDataloaders) {
106
106
  const batchMethod = (0, types_1.detectBatchMethod)(ctx, fileDesc, serviceDesc, methodDesc);
107
107
  if (batchMethod) {
108
108
  const maybeContext = options.context ? `ctx: Context,` : "";
@@ -24,7 +24,7 @@ function generateService(ctx, fileDesc, sourceInfo, serviceDesc) {
24
24
  const { options } = ctx;
25
25
  const chunks = [];
26
26
  (0, utils_1.maybeAddComment)(options, sourceInfo, chunks, serviceDesc.options?.deprecated);
27
- const maybeTypeVar = options.context ? `<${main_1.contextTypeVar}>` : "";
27
+ const maybeTypeVar = options.context ? `<${(0, main_1.contextTypeVar)(options)}>` : "";
28
28
  chunks.push((0, ts_poet_1.code) `export interface ${(0, ts_poet_1.def)(serviceDesc.name)}${maybeTypeVar} {`);
29
29
  serviceDesc.method.forEach((methodDesc, index) => {
30
30
  (0, utils_1.assertInstanceOf)(methodDesc, utils_1.FormattedMethodDescriptor);
@@ -61,7 +61,7 @@ function generateService(ctx, fileDesc, sourceInfo, serviceDesc) {
61
61
  }
62
62
  chunks.push((0, ts_poet_1.code) `${methodDesc.formattedName}(${(0, ts_poet_1.joinCode)(params, { on: "," })}): ${(0, types_1.responsePromiseOrObservable)(ctx, methodDesc)};`);
63
63
  // If this is a batch method, auto-generate the singular version of it
64
- if (options.context) {
64
+ if (options.context && options.useContextDataloaders) {
65
65
  const batchMethod = (0, types_1.detectBatchMethod)(ctx, fileDesc, serviceDesc, methodDesc);
66
66
  if (batchMethod) {
67
67
  chunks.push((0, ts_poet_1.code) `${batchMethod.singleMethodName}(
@@ -208,7 +208,7 @@ function generateServiceClientImpl(ctx, fileDesc, serviceDesc) {
208
208
  chunks.push((0, ts_poet_1.code) `export const ${serviceNameConst} = "${serviceName}";`);
209
209
  // Define the FooServiceImpl class
210
210
  const i = options.context ? `${name}<Context>` : name;
211
- const t = options.context ? `<${main_1.contextTypeVar}>` : "";
211
+ const t = options.context ? `<${(0, main_1.contextTypeVar)(options)}>` : "";
212
212
  chunks.push((0, ts_poet_1.code) `export class ${name}ClientImpl${t} implements ${(0, ts_poet_1.def)(i)} {`);
213
213
  // Create the constructor(rpc: Rpc)
214
214
  const rpcType = options.context ? "Rpc<Context>" : "Rpc";
@@ -226,13 +226,14 @@ function generateServiceClientImpl(ctx, fileDesc, serviceDesc) {
226
226
  // Create a method for each FooService method
227
227
  for (const methodDesc of serviceDesc.method) {
228
228
  // See if this fuzzy matches to a batchable method
229
- if (options.context) {
229
+ if (options.context && options.useContextDataloaders) {
230
230
  const batchMethod = (0, types_1.detectBatchMethod)(ctx, fileDesc, serviceDesc, methodDesc);
231
231
  if (batchMethod) {
232
232
  chunks.push(generateBatchingRpcMethod(ctx, batchMethod));
233
233
  }
234
234
  }
235
235
  if (options.context &&
236
+ options.useContextDataloaders &&
236
237
  methodDesc.name.match(/^Get[A-Z]/) &&
237
238
  !methodDesc.serverStreaming &&
238
239
  !methodDesc.clientStreaming) {
@@ -57,5 +57,5 @@ declare function makeExtensionClass(options: Options): {
57
57
  declare function makeAssertionUtils(bytes: ReturnType<typeof makeByteUtils>): {
58
58
  fail: ConditionalOutput;
59
59
  };
60
- export declare const contextTypeVar = "Context extends DataLoaders";
60
+ export declare function contextTypeVar(options: Options): string;
61
61
  export {};
package/build/src/main.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.contextTypeVar = void 0;
4
3
  exports.generateFile = generateFile;
5
4
  exports.makeUtils = makeUtils;
5
+ exports.contextTypeVar = contextTypeVar;
6
6
  const ts_poet_1 = require("ts-poet");
7
7
  const ConditionalOutput_1 = require("ts-poet/build/ConditionalOutput");
8
8
  const ts_proto_descriptors_1 = require("ts-proto-descriptors");
@@ -288,7 +288,7 @@ function generateFile(ctx, fileDesc) {
288
288
  chunks.push((0, generate_grpc_web_1.addGrpcWebMisc)(ctx, hasServerStreamingMethods));
289
289
  }
290
290
  }
291
- if (options.context) {
291
+ if (options.context && options.useContextDataloaders) {
292
292
  chunks.push((0, generate_services_1.generateDataLoaderOptionsType)());
293
293
  chunks.push((0, generate_services_1.generateDataLoadersType)());
294
294
  }
@@ -2629,7 +2629,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
2629
2629
  chunks.push((0, ts_poet_1.code) `}`);
2630
2630
  return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
2631
2631
  }
2632
- exports.contextTypeVar = "Context extends DataLoaders";
2632
+ function contextTypeVar(options) {
2633
+ return options.useContextDataloaders ? "Context extends DataLoaders" : "Context";
2634
+ }
2633
2635
  function convertFromObjectKey(ctx, messageDesc, field, variableName) {
2634
2636
  const { keyType, keyField } = (0, types_1.detectMapType)(ctx, messageDesc, field);
2635
2637
  if (keyType.toCodeString([]) === "string") {
@@ -44,6 +44,7 @@ export declare enum OutputSchemaOption {
44
44
  }
45
45
  export type Options = {
46
46
  context: boolean;
47
+ useContextDataloaders: boolean;
47
48
  snakeToCamel: Array<"json" | "keys">;
48
49
  protoJsonFormat: boolean;
49
50
  forceLong: LongOption;
@@ -59,6 +59,7 @@ var OutputSchemaOption;
59
59
  function defaultOptions() {
60
60
  return {
61
61
  context: false,
62
+ useContextDataloaders: true,
62
63
  snakeToCamel: ["json", "keys"],
63
64
  protoJsonFormat: true,
64
65
  emitDefaultValues: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "2.12.4",
3
+ "version": "2.13.0",
4
4
  "description": "",
5
5
  "main": "build/src/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",