ts-proto 2.12.3 → 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
|
|
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) {
|
package/build/src/main.d.ts
CHANGED
|
@@ -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
|
|
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");
|
|
@@ -153,12 +153,12 @@ function generateFile(ctx, fileDesc) {
|
|
|
153
153
|
staticMembers.push(generateFromPartial(ctx, fullName, message));
|
|
154
154
|
}
|
|
155
155
|
const structFieldNames = {
|
|
156
|
-
nullValue: (0, case_1.
|
|
157
|
-
numberValue: (0, case_1.
|
|
158
|
-
stringValue: (0, case_1.
|
|
159
|
-
boolValue: (0, case_1.
|
|
160
|
-
structValue: (0, case_1.
|
|
161
|
-
listValue: (0, case_1.
|
|
156
|
+
nullValue: (0, utils_1.getFieldName)({ name: "null_value", jsonName: (0, case_1.snakeToCamel)("null_value") }, ctx.options),
|
|
157
|
+
numberValue: (0, utils_1.getFieldName)({ name: "number_value", jsonName: (0, case_1.snakeToCamel)("number_value") }, ctx.options),
|
|
158
|
+
stringValue: (0, utils_1.getFieldName)({ name: "string_value", jsonName: (0, case_1.snakeToCamel)("string_value") }, ctx.options),
|
|
159
|
+
boolValue: (0, utils_1.getFieldName)({ name: "bool_value", jsonName: (0, case_1.snakeToCamel)("bool_value") }, ctx.options),
|
|
160
|
+
structValue: (0, utils_1.getFieldName)({ name: "struct_value", jsonName: (0, case_1.snakeToCamel)("struct_value") }, ctx.options),
|
|
161
|
+
listValue: (0, utils_1.getFieldName)({ name: "list_value", jsonName: (0, case_1.snakeToCamel)("list_value") }, ctx.options),
|
|
162
162
|
};
|
|
163
163
|
if (options.nestJs) {
|
|
164
164
|
staticMembers.push(...(0, generate_struct_wrappers_1.generateWrapDeep)(ctx, fullTypeName, structFieldNames));
|
|
@@ -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
|
-
|
|
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") {
|
package/build/src/options.d.ts
CHANGED
package/build/src/options.js
CHANGED