ts-proto 2.18.6 → 2.20.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 +12 -0
- package/build/src/encode.js +15 -23
- package/build/src/generate-async-iterable.d.ts +3 -3
- package/build/src/generate-async-iterable.js +11 -10
- package/build/src/generate-grpc-web.js +3 -6
- package/build/src/generate-services.js +7 -10
- package/build/src/generate-struct-wrappers.js +16 -13
- package/build/src/main.js +101 -90
- package/build/src/options.d.ts +2 -1
- package/build/src/options.js +30 -6
- package/build/src/schema.js +3 -3
- package/build/src/types.d.ts +1 -0
- package/build/src/types.js +7 -2
- package/build/src/utils.d.ts +5 -1
- package/build/src/utils.js +24 -2
- package/package.json +1 -1
package/README.markdown
CHANGED
|
@@ -443,6 +443,12 @@ With `--ts_proto_opt=protoJsonFormat=false`, strict proto3 compliance is disable
|
|
|
443
443
|
|
|
444
444
|
- With `--ts_proto_opt=outputPartialMethods=false`, the `Message.fromPartial` and `Message.create` methods for accepting partially-formed objects/object literals will not be output.
|
|
445
445
|
|
|
446
|
+
- With `--ts_proto_opt=outputStandaloneFunctions=true`, the message methods are output as standalone functions instead of members of a `Message` const, e.g. `Message.encode` becomes `messageEncode` and `Foo_Bar.fromJSON` becomes `foo_BarFromJSON`, following the enum functions.
|
|
447
|
+
|
|
448
|
+
This is useful if you want bundlers to tree-shake the functions you don't use.
|
|
449
|
+
|
|
450
|
+
This can't be combined with `outputTypeRegistry=true`, `outputTypeAnnotations=static-only`, `outputServices=generic-definitions`, `nestJs=true` or `useMongoObjectId=true`. `outputSchema` leaves messages out of its `references`, and files mapped with `M` options need to be generated with this option as well.
|
|
451
|
+
|
|
446
452
|
- With `--ts_proto_opt=stringEnums=true`, the generated enum types will be string-based instead of int-based.
|
|
447
453
|
|
|
448
454
|
This is useful if you want "only types" and are using a gRPC REST Gateway configured to serialize enums as strings.
|
|
@@ -479,6 +485,12 @@ With `--ts_proto_opt=protoJsonFormat=false`, strict proto3 compliance is disable
|
|
|
479
485
|
|
|
480
486
|
Note that `addGrpcMetadata`, `addNestjsRestParameter`, `returnObservable` and `useNestjsFqnServiceName` will still be false.
|
|
481
487
|
|
|
488
|
+
- With `--ts_proto_opt=nestJs=client` or `--ts_proto_opt=nestJs=server`, only the client-side or server-side NestJS service output will be generated, with the same changed defaults as `nestJs=true`.
|
|
489
|
+
|
|
490
|
+
With `nestJs=client`, only the `FooServiceClient` interface is generated, i.e. there is no `FooServiceController` interface or `@FooServiceControllerMethods()` decorator, so the output doesn't import `@nestjs/microservices`. With `nestJs=server`, only the controller interface and decorator are generated. The message types and the `FOO_PACKAGE_NAME`/`FOO_SERVICE_NAME` consts are generated in both cases.
|
|
491
|
+
|
|
492
|
+
`nestJs=client,nestJs=server` is the same as `nestJs=true`.
|
|
493
|
+
|
|
482
494
|
- With `--ts_proto_opt=useDate=false`, fields of type `google.protobuf.Timestamp` will not be mapped to type `Date` in the generated types. See [Timestamp](#timestamp) for more details.
|
|
483
495
|
|
|
484
496
|
- With `--ts_proto_opt=useMongoObjectId=true`, fields of a type called ObjectId where the message is constructed to have on field called value that is a string will be mapped to type `mongodb.ObjectId` in the generated types. This will require your project to install the mongodb npm package. See [ObjectId](#objectid) for more details.
|
package/build/src/encode.js
CHANGED
|
@@ -5,14 +5,13 @@ exports.generateDecoder = generateDecoder;
|
|
|
5
5
|
const ts_poet_1 = require("ts-poet");
|
|
6
6
|
const types_1 = require("./types");
|
|
7
7
|
const options_1 = require("./options");
|
|
8
|
-
const utils_1 = require("./utils");
|
|
9
8
|
function generateEncoder(ctx, typeName) {
|
|
10
9
|
const name = (0, types_1.wrapperTypeName)(typeName);
|
|
10
|
+
const encode = (0, types_1.getMessageMethod)(ctx, typeName, "encode");
|
|
11
11
|
if (!name) {
|
|
12
|
-
return (0, ts_poet_1.code) `${
|
|
12
|
+
return (0, ts_poet_1.code) `${encode}(value).finish()`;
|
|
13
13
|
}
|
|
14
14
|
if (name == "Timestamp") {
|
|
15
|
-
const TimestampValue = (0, utils_1.impProto)(ctx.options, "google/protobuf/timestamp", (0, utils_1.wrapTypeName)(ctx.options, name));
|
|
16
15
|
let value = (0, ts_poet_1.code) `value`;
|
|
17
16
|
if (ctx.options.useDate === options_1.DateOption.DATE ||
|
|
18
17
|
ctx.options.useDate === options_1.DateOption.STRING ||
|
|
@@ -20,48 +19,43 @@ function generateEncoder(ctx, typeName) {
|
|
|
20
19
|
ctx.options.useDate === options_1.DateOption.TEMPORAL) {
|
|
21
20
|
value = (0, ts_poet_1.code) `${ctx.utils.toTimestamp}(${value})`;
|
|
22
21
|
}
|
|
23
|
-
return (0, ts_poet_1.code) `${
|
|
22
|
+
return (0, ts_poet_1.code) `${encode}(${value}).finish()`;
|
|
24
23
|
}
|
|
25
24
|
if (name == "Struct" || name == "Value") {
|
|
26
|
-
|
|
27
|
-
return (0, ts_poet_1.code) `${StructType}.encode(${StructType}.wrap(value)).finish()`;
|
|
25
|
+
return (0, ts_poet_1.code) `${encode}(${(0, types_1.getMessageMethod)(ctx, typeName, "wrap")}(value)).finish()`;
|
|
28
26
|
}
|
|
29
27
|
if (name == "ListValue") {
|
|
30
|
-
|
|
31
|
-
return (0, ts_poet_1.code) `${ListValueType}.encode({values: value ?? []}).finish()`;
|
|
28
|
+
return (0, ts_poet_1.code) `${encode}({values: value ?? []}).finish()`;
|
|
32
29
|
}
|
|
33
|
-
const TypeValue = (0, utils_1.impProto)(ctx.options, "google/protobuf/wrappers", (0, utils_1.wrapTypeName)(ctx.options, name));
|
|
34
30
|
switch (name) {
|
|
35
31
|
case "StringValue":
|
|
36
|
-
return (0, ts_poet_1.code) `${
|
|
32
|
+
return (0, ts_poet_1.code) `${encode}({value: value ?? ""}).finish()`;
|
|
37
33
|
case "Int32Value":
|
|
38
34
|
case "UInt32Value":
|
|
39
35
|
case "DoubleValue":
|
|
40
36
|
case "FloatValue":
|
|
41
|
-
return (0, ts_poet_1.code) `${
|
|
37
|
+
return (0, ts_poet_1.code) `${encode}({value: value ?? 0}).finish()`;
|
|
42
38
|
case "Int64Value":
|
|
43
39
|
case "UInt64Value":
|
|
44
40
|
if (ctx.options.forceLong === options_1.LongOption.LONG) {
|
|
45
|
-
return (0, ts_poet_1.code) `${
|
|
41
|
+
return (0, ts_poet_1.code) `${encode}({value: value ? value.toNumber(): 0}).finish()`;
|
|
46
42
|
}
|
|
47
|
-
return (0, ts_poet_1.code) `${
|
|
43
|
+
return (0, ts_poet_1.code) `${encode}({value: value ?? 0 }).finish()`;
|
|
48
44
|
case "BoolValue":
|
|
49
|
-
return (0, ts_poet_1.code) `${
|
|
45
|
+
return (0, ts_poet_1.code) `${encode}({value: value ?? false}).finish()`;
|
|
50
46
|
case "BytesValue":
|
|
51
|
-
return (0, ts_poet_1.code) `${
|
|
47
|
+
return (0, ts_poet_1.code) `${encode}({value: value ?? new Uint8Array(0)}).finish()`;
|
|
52
48
|
}
|
|
53
49
|
throw new Error(`unknown wrapper type: ${name}`);
|
|
54
50
|
}
|
|
55
51
|
function generateDecoder(ctx, typeName) {
|
|
56
52
|
const { options } = ctx;
|
|
57
53
|
let name = (0, types_1.wrapperTypeName)(typeName);
|
|
54
|
+
const decoder = (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, typeName, "decode")}(value)`;
|
|
58
55
|
if (!name) {
|
|
59
|
-
return
|
|
56
|
+
return decoder;
|
|
60
57
|
}
|
|
61
|
-
let TypeValue;
|
|
62
58
|
if (name == "Timestamp") {
|
|
63
|
-
TypeValue = (0, utils_1.impProto)(ctx.options, "google/protobuf/timestamp", (0, utils_1.wrapTypeName)(ctx.options, name));
|
|
64
|
-
const decoder = (0, ts_poet_1.code) `${TypeValue}.decode(value)`;
|
|
65
59
|
if (ctx.options.useDate === options_1.DateOption.DATE ||
|
|
66
60
|
ctx.options.useDate === options_1.DateOption.STRING ||
|
|
67
61
|
ctx.options.useDate === options_1.DateOption.STRING_NANO ||
|
|
@@ -71,9 +65,7 @@ function generateDecoder(ctx, typeName) {
|
|
|
71
65
|
return decoder;
|
|
72
66
|
}
|
|
73
67
|
if (name == "Struct" || name == "ListValue" || name == "Value") {
|
|
74
|
-
|
|
75
|
-
return (0, ts_poet_1.code) `${TypeValue}.unwrap(${TypeValue}.decode(value))`;
|
|
68
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, typeName, "unwrap")}(${decoder})`;
|
|
76
69
|
}
|
|
77
|
-
|
|
78
|
-
return (0, ts_poet_1.code) `${TypeValue}.decode(value).value`;
|
|
70
|
+
return (0, ts_poet_1.code) `${decoder}.value`;
|
|
79
71
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Code } from "ts-poet";
|
|
2
|
-
import {
|
|
2
|
+
import { Context } from "./context";
|
|
3
3
|
/** Creates a function to transform a message Source to a Uint8Array Source. */
|
|
4
|
-
export declare function generateEncodeTransform(
|
|
4
|
+
export declare function generateEncodeTransform(ctx: Context, fullName: string): Code;
|
|
5
5
|
/** Creates a function to transform a Uint8Array Source to a message Source. */
|
|
6
|
-
export declare function generateDecodeTransform(
|
|
6
|
+
export declare function generateDecodeTransform(ctx: Context, fullName: string): Code;
|
|
@@ -3,41 +3,42 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateEncodeTransform = generateEncodeTransform;
|
|
4
4
|
exports.generateDecodeTransform = generateDecodeTransform;
|
|
5
5
|
const ts_poet_1 = require("ts-poet");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
6
7
|
/** Creates a function to transform a message Source to a Uint8Array Source. */
|
|
7
|
-
function generateEncodeTransform(
|
|
8
|
+
function generateEncodeTransform(ctx, fullName) {
|
|
8
9
|
return (0, ts_poet_1.code) `
|
|
9
10
|
// encodeTransform encodes a source of message objects.
|
|
10
11
|
// Transform<${fullName}, Uint8Array>
|
|
11
|
-
|
|
12
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "encodeTransform", true)}(
|
|
12
13
|
source: AsyncIterable<${fullName} | ${fullName}[]> | Iterable<${fullName} | ${fullName}[]>
|
|
13
14
|
): AsyncIterable<Uint8Array> {
|
|
14
15
|
for await (const pkt of source) {
|
|
15
|
-
if (${utils.globalThis}.Array.isArray(pkt)) {
|
|
16
|
+
if (${ctx.utils.globalThis}.Array.isArray(pkt)) {
|
|
16
17
|
for (const p of (pkt as any)) {
|
|
17
|
-
yield* [${fullName}
|
|
18
|
+
yield* [${(0, utils_1.localMessageMethod)(ctx.options, fullName, "encode")}(p).finish()]
|
|
18
19
|
}
|
|
19
20
|
} else {
|
|
20
|
-
yield* [${fullName}
|
|
21
|
+
yield* [${(0, utils_1.localMessageMethod)(ctx.options, fullName, "encode")}(pkt as any).finish()]
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
`;
|
|
25
26
|
}
|
|
26
27
|
/** Creates a function to transform a Uint8Array Source to a message Source. */
|
|
27
|
-
function generateDecodeTransform(
|
|
28
|
+
function generateDecodeTransform(ctx, fullName) {
|
|
28
29
|
return (0, ts_poet_1.code) `
|
|
29
30
|
// decodeTransform decodes a source of encoded messages.
|
|
30
31
|
// Transform<Uint8Array, ${fullName}>
|
|
31
|
-
|
|
32
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "decodeTransform", true)}(
|
|
32
33
|
source: AsyncIterable<Uint8Array | Uint8Array[]> | Iterable<Uint8Array | Uint8Array[]>
|
|
33
34
|
): AsyncIterable<${fullName}> {
|
|
34
35
|
for await (const pkt of source) {
|
|
35
|
-
if (${utils.globalThis}.Array.isArray(pkt)) {
|
|
36
|
+
if (${ctx.utils.globalThis}.Array.isArray(pkt)) {
|
|
36
37
|
for (const p of (pkt as any)) {
|
|
37
|
-
yield* [${fullName}
|
|
38
|
+
yield* [${(0, utils_1.localMessageMethod)(ctx.options, fullName, "decode")}(p)]
|
|
38
39
|
}
|
|
39
40
|
} else {
|
|
40
|
-
yield* [${fullName}
|
|
41
|
+
yield* [${(0, utils_1.localMessageMethod)(ctx.options, fullName, "decode")}(pkt as any)]
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
}
|
|
@@ -43,7 +43,6 @@ function generateRpcMethod(ctx, serviceDesc, methodDesc) {
|
|
|
43
43
|
(0, utils_1.assertInstanceOf)(methodDesc, utils_1.FormattedMethodDescriptor);
|
|
44
44
|
const { options } = ctx;
|
|
45
45
|
const { useAbortSignal } = options;
|
|
46
|
-
const requestMessage = (0, types_1.requestType)(ctx, methodDesc, false);
|
|
47
46
|
const inputType = (0, types_1.requestType)(ctx, methodDesc, true);
|
|
48
47
|
const returns = (0, types_1.responsePromiseOrObservable)(ctx, methodDesc);
|
|
49
48
|
if (methodDesc.clientStreaming) {
|
|
@@ -66,7 +65,7 @@ function generateRpcMethod(ctx, serviceDesc, methodDesc) {
|
|
|
66
65
|
): ${returns} {
|
|
67
66
|
return this.rpc.${method}(
|
|
68
67
|
${methodDescName(serviceDesc, methodDesc)},
|
|
69
|
-
${
|
|
68
|
+
${(0, types_1.getMessageMethod)(ctx, methodDesc.inputType, "fromPartial")}(request),
|
|
70
69
|
metadata,
|
|
71
70
|
${useAbortSignal ? "abortSignal," : ""}
|
|
72
71
|
);
|
|
@@ -89,8 +88,6 @@ function generateGrpcServiceDesc(fileDesc, serviceDesc) {
|
|
|
89
88
|
* implementation.
|
|
90
89
|
*/
|
|
91
90
|
function generateGrpcMethodDesc(ctx, serviceDesc, methodDesc) {
|
|
92
|
-
const inputType = (0, types_1.requestType)(ctx, methodDesc);
|
|
93
|
-
const outputType = (0, types_1.responseType)(ctx, methodDesc);
|
|
94
91
|
// grpc-web expects this to be a class, but the ts-proto messages are just interfaces.
|
|
95
92
|
//
|
|
96
93
|
// That said, grpc-web's runtime doesn't really use this (at least so far for what ts-proto
|
|
@@ -104,7 +101,7 @@ function generateGrpcMethodDesc(ctx, serviceDesc, methodDesc) {
|
|
|
104
101
|
// This makes our data look enough like an object/class that grpc-web works just fine.
|
|
105
102
|
const requestFn = (0, ts_poet_1.code) `{
|
|
106
103
|
serializeBinary() {
|
|
107
|
-
return ${inputType}
|
|
104
|
+
return ${(0, types_1.getMessageMethod)(ctx, methodDesc.inputType, "encode")}(this).finish();
|
|
108
105
|
},
|
|
109
106
|
}`;
|
|
110
107
|
// grpc-web also expects this to be a class, but with a static `deserializeBinary` method to
|
|
@@ -113,7 +110,7 @@ function generateGrpcMethodDesc(ctx, serviceDesc, methodDesc) {
|
|
|
113
110
|
// we want/what grpc-web's runtime needs.
|
|
114
111
|
const responseFn = (0, ts_poet_1.code) `{
|
|
115
112
|
deserializeBinary(data: Uint8Array) {
|
|
116
|
-
const value = ${outputType}
|
|
113
|
+
const value = ${(0, types_1.getMessageMethod)(ctx, methodDesc.outputType, "decode")}(data);
|
|
117
114
|
return {
|
|
118
115
|
...value,
|
|
119
116
|
toObject() { return value; },
|
|
@@ -78,9 +78,7 @@ function generateRegularRpcMethod(ctx, methodDesc) {
|
|
|
78
78
|
(0, utils_1.assertInstanceOf)(methodDesc, utils_1.FormattedMethodDescriptor);
|
|
79
79
|
const { options } = ctx;
|
|
80
80
|
const BinaryReader = (0, ts_poet_1.imp)("BinaryReader@@bufbuild/protobuf/wire");
|
|
81
|
-
const rawInputType = (0, types_1.rawRequestType)(ctx, methodDesc, { keepValueType: true });
|
|
82
81
|
const inputType = (0, types_1.requestType)(ctx, methodDesc);
|
|
83
|
-
const rawOutputType = (0, types_1.responseType)(ctx, methodDesc, { keepValueType: true });
|
|
84
82
|
const metadataType = options.metadataType ? (0, ts_poet_1.imp)(options.metadataType) : (0, ts_poet_1.imp)("t:Metadata@@grpc/grpc-js");
|
|
85
83
|
const params = [
|
|
86
84
|
...(options.context ? [(0, ts_poet_1.code) `ctx: Context`] : []),
|
|
@@ -100,7 +98,7 @@ function generateRegularRpcMethod(ctx, methodDesc) {
|
|
|
100
98
|
return Promise.reject(error);
|
|
101
99
|
`;
|
|
102
100
|
}
|
|
103
|
-
let encode = (0, ts_poet_1.code) `${
|
|
101
|
+
let encode = (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, methodDesc.inputType, "encode")}(request).finish()`;
|
|
104
102
|
let beforeRequest;
|
|
105
103
|
if (options.rpcBeforeRequest && !methodDesc.clientStreaming) {
|
|
106
104
|
beforeRequest = generateBeforeRequest(methodDesc.name);
|
|
@@ -108,10 +106,10 @@ function generateRegularRpcMethod(ctx, methodDesc) {
|
|
|
108
106
|
else if (methodDesc.clientStreaming && options.rpcBeforeRequest) {
|
|
109
107
|
encode = (0, ts_poet_1.code) `{const encodedRequest = ${encode}; ${generateBeforeRequest(methodDesc.name, "encodedRequest")}; return encodedRequest}`;
|
|
110
108
|
}
|
|
111
|
-
let decode = (0, ts_poet_1.code) `${
|
|
109
|
+
let decode = (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, methodDesc.outputType, "decode")}(new ${BinaryReader}(data))`;
|
|
112
110
|
if (options.rpcAfterResponse) {
|
|
113
111
|
decode = (0, ts_poet_1.code) `
|
|
114
|
-
const response = ${
|
|
112
|
+
const response = ${decode};
|
|
115
113
|
if (this.rpc.afterResponse) {
|
|
116
114
|
this.rpc.afterResponse(this.service, "${methodDesc.name}", response);
|
|
117
115
|
}
|
|
@@ -123,7 +121,7 @@ function generateRegularRpcMethod(ctx, methodDesc) {
|
|
|
123
121
|
// }
|
|
124
122
|
if (methodDesc.clientStreaming) {
|
|
125
123
|
if (options.useAsyncIterable) {
|
|
126
|
-
encode = (0, ts_poet_1.code) `${
|
|
124
|
+
encode = (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, methodDesc.inputType, "encodeTransform")}(request)`;
|
|
127
125
|
}
|
|
128
126
|
else {
|
|
129
127
|
encode = (0, ts_poet_1.code) `request.pipe(${(0, ts_poet_1.imp)("map@rxjs/operators")}(request => ${encode}))`;
|
|
@@ -175,11 +173,10 @@ function generateBeforeRequest(methodName, requestVariableName = "request") {
|
|
|
175
173
|
}
|
|
176
174
|
function createDefaultServiceReturn(ctx, methodDesc, decode, errorHandler) {
|
|
177
175
|
const { options } = ctx;
|
|
178
|
-
const rawOutputType = (0, types_1.responseType)(ctx, methodDesc, { keepValueType: true });
|
|
179
176
|
const returnStatement = (0, utils_1.arrowFunction)("data", decode, !options.rpcAfterResponse);
|
|
180
177
|
if (options.returnObservable || methodDesc.serverStreaming) {
|
|
181
178
|
if (options.useAsyncIterable) {
|
|
182
|
-
return (0, ts_poet_1.code) `${
|
|
179
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, methodDesc.outputType, "decodeTransform")}(result)`;
|
|
183
180
|
}
|
|
184
181
|
else {
|
|
185
182
|
if (errorHandler) {
|
|
@@ -302,9 +299,9 @@ function generateCachingRpcMethod(ctx, fileDesc, serviceDesc, methodDesc) {
|
|
|
302
299
|
const lambda = (0, ts_poet_1.code) `
|
|
303
300
|
(requests) => {
|
|
304
301
|
const responses = requests.map(async request => {
|
|
305
|
-
const data = ${inputType}
|
|
302
|
+
const data = ${(0, types_1.getMessageMethod)(ctx, methodDesc.inputType, "encode")}(request).finish()
|
|
306
303
|
const response = await this.rpc.request(ctx, "${(0, utils_1.maybePrefixPackage)(fileDesc, serviceDesc.name)}", "${methodDesc.name}", data);
|
|
307
|
-
return ${outputType}
|
|
304
|
+
return ${(0, types_1.getMessageMethod)(ctx, methodDesc.outputType, "decode")}(new ${BinaryReader}(response));
|
|
308
305
|
});
|
|
309
306
|
return Promise.all(responses);
|
|
310
307
|
}
|
|
@@ -164,7 +164,7 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
164
164
|
}
|
|
165
165
|
if (ctx.options.useOptionals !== "all")
|
|
166
166
|
defaultFields = "";
|
|
167
|
-
chunks.push((0, ts_poet_1.code)
|
|
167
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Struct", "wrap")}(object: {[key: string]: any} | undefined): ${(0, utils_1.wrapTypeName)(ctx.options, "Struct")} {
|
|
168
168
|
const struct = createBase${(0, utils_1.wrapTypeName)(ctx.options, "Struct")}();
|
|
169
169
|
${defaultFields}
|
|
170
170
|
if (object !== undefined) {
|
|
@@ -177,7 +177,7 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
177
177
|
}
|
|
178
178
|
if ((0, types_1.isAnyValueTypeName)(fullProtoTypeName)) {
|
|
179
179
|
if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
|
|
180
|
-
chunks.push((0, ts_poet_1.code)
|
|
180
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Value", "wrap")}(value: any): ${(0, utils_1.wrapTypeName)(ctx.options, "Value")} {
|
|
181
181
|
const result = createBase${(0, utils_1.wrapTypeName)(ctx.options, "Value")}()${maybeAsAny(ctx.options)};
|
|
182
182
|
if (value === null) {
|
|
183
183
|
result.kind = {$case: '${fieldNames.nullValue}', ${fieldNames.nullValue}: ${(0, utils_1.wrapTypeName)(ctx.options, "NullValue", "enum")}.NULL_VALUE};
|
|
@@ -198,7 +198,7 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
198
198
|
}`);
|
|
199
199
|
}
|
|
200
200
|
else if (ctx.options.oneof === options_1.OneofOption.UNIONS_VALUE) {
|
|
201
|
-
chunks.push((0, ts_poet_1.code)
|
|
201
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Value", "wrap")}(value: any): ${(0, utils_1.wrapTypeName)(ctx.options, "Value")} {
|
|
202
202
|
const result = createBase${(0, utils_1.wrapTypeName)(ctx.options, "Value")}()${maybeAsAny(ctx.options)};
|
|
203
203
|
if (value === null) {
|
|
204
204
|
result.kind = {$case: '${fieldNames.nullValue}', value: ${(0, utils_1.wrapTypeName)(ctx.options, "NullValue", "enum")}.NULL_VALUE};
|
|
@@ -219,7 +219,7 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
219
219
|
}`);
|
|
220
220
|
}
|
|
221
221
|
else {
|
|
222
|
-
chunks.push((0, ts_poet_1.code)
|
|
222
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Value", "wrap")}(value: any): ${(0, utils_1.wrapTypeName)(ctx.options, "Value")} {
|
|
223
223
|
const result = createBase${(0, utils_1.wrapTypeName)(ctx.options, "Value")}()${maybeAsAny(ctx.options)};
|
|
224
224
|
if (value === null) {
|
|
225
225
|
result.${fieldNames.nullValue} = ${(0, utils_1.wrapTypeName)(ctx.options, "NullValue", "enum")}.NULL_VALUE;
|
|
@@ -242,14 +242,14 @@ function generateWrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
242
242
|
}
|
|
243
243
|
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
244
244
|
const maybeReadyOnly = ctx.options.useReadonlyTypes ? "Readonly" : "";
|
|
245
|
-
chunks.push((0, ts_poet_1.code)
|
|
245
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "ListValue", "wrap")}(array: ${maybeReadyOnly}Array<any> | undefined): ${(0, utils_1.wrapTypeName)(ctx.options, "ListValue")} {
|
|
246
246
|
const result = createBase${(0, utils_1.wrapTypeName)(ctx.options, "ListValue")}()${maybeAsAny(ctx.options)};
|
|
247
247
|
result.values = array ?? [];
|
|
248
248
|
return result;
|
|
249
249
|
}`);
|
|
250
250
|
}
|
|
251
251
|
if ((0, types_1.isFieldMaskTypeName)(fullProtoTypeName)) {
|
|
252
|
-
chunks.push((0, ts_poet_1.code)
|
|
252
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "FieldMask", "wrap")}(paths: ${maybeReadonly(ctx.options)} string[]): ${(0, utils_1.wrapTypeName)(ctx.options, "FieldMask")} {
|
|
253
253
|
const result = createBase${(0, utils_1.wrapTypeName)(ctx.options, "FieldMask")}()${maybeAsAny(ctx.options)};
|
|
254
254
|
result.paths = paths;
|
|
255
255
|
return result;
|
|
@@ -266,7 +266,7 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
266
266
|
const chunks = [];
|
|
267
267
|
if ((0, types_1.isStructTypeName)(fullProtoTypeName)) {
|
|
268
268
|
if (ctx.options.useMapType) {
|
|
269
|
-
chunks.push((0, ts_poet_1.code)
|
|
269
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Struct", "unwrap")}(message: ${(0, utils_1.wrapTypeName)(ctx.options, "Struct")}): {[key: string]: any} {
|
|
270
270
|
const object: { [key: string]: any } = {};
|
|
271
271
|
if (message.fields) {
|
|
272
272
|
for (const key of message.fields.keys()) {
|
|
@@ -277,7 +277,7 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
277
277
|
}`);
|
|
278
278
|
}
|
|
279
279
|
else {
|
|
280
|
-
chunks.push((0, ts_poet_1.code)
|
|
280
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Struct", "unwrap")}(message: ${(0, utils_1.wrapTypeName)(ctx.options, "Struct")}): {[key: string]: any} {
|
|
281
281
|
const object: { [key: string]: any } = {};
|
|
282
282
|
if (message.fields) {
|
|
283
283
|
for (const key of ${ctx.utils.globalThis}.Object.keys(message.fields)) {
|
|
@@ -290,7 +290,7 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
290
290
|
}
|
|
291
291
|
if ((0, types_1.isAnyValueTypeName)(fullProtoTypeName)) {
|
|
292
292
|
if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
|
|
293
|
-
chunks.push((0, ts_poet_1.code)
|
|
293
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Value", "unwrap")}(message: ${(0, utils_1.wrapTypeName)(ctx.options, "Value")}): string | number | boolean | Object | null | Array<any> | undefined {
|
|
294
294
|
if (message.kind?.$case === '${fieldNames.nullValue}') {
|
|
295
295
|
return null;
|
|
296
296
|
} else if (message.kind?.$case === '${fieldNames.numberValue}') {
|
|
@@ -309,12 +309,12 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
309
309
|
}`);
|
|
310
310
|
}
|
|
311
311
|
else if (ctx.options.oneof === options_1.OneofOption.UNIONS_VALUE) {
|
|
312
|
-
chunks.push((0, ts_poet_1.code)
|
|
312
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Value", "unwrap")}(message: ${(0, utils_1.wrapTypeName)(ctx.options, "Value")}): string | number | boolean | Object | null | Array<any> | undefined {
|
|
313
313
|
return (message.kind?.$case === '${fieldNames.nullValue}') ? null : message.kind?.value;
|
|
314
314
|
}`);
|
|
315
315
|
}
|
|
316
316
|
else {
|
|
317
|
-
chunks.push((0, ts_poet_1.code)
|
|
317
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "Value", "unwrap")}(message: any): string | number | boolean | Object | null | Array<any> | undefined {
|
|
318
318
|
if (message.${fieldNames.stringValue} !== undefined) {
|
|
319
319
|
return message.${fieldNames.stringValue};
|
|
320
320
|
} else if (message?.${fieldNames.numberValue} !== undefined) {
|
|
@@ -333,7 +333,7 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
335
|
if ((0, types_1.isListValueTypeName)(fullProtoTypeName)) {
|
|
336
|
-
chunks.push((0, ts_poet_1.code)
|
|
336
|
+
chunks.push((0, ts_poet_1.code) `${methodHead(ctx, "ListValue", "unwrap")}(message: ${ctx.options.useReadonlyTypes ? "any" : (0, utils_1.wrapTypeName)(ctx.options, "ListValue")}): Array<any> {
|
|
337
337
|
if (message?.hasOwnProperty('values') && ${ctx.utils.globalThis}.Array.isArray(message.values)) {
|
|
338
338
|
return message.values;
|
|
339
339
|
} else {
|
|
@@ -349,10 +349,13 @@ function generateUnwrapShallow(ctx, fullProtoTypeName, fieldNames) {
|
|
|
349
349
|
function generateFieldMaskUnwrap(ctx) {
|
|
350
350
|
const returnType = ctx.options.useOptionals === "all" ? "string[] | undefined" : "string[]";
|
|
351
351
|
const pathModifier = ctx.options.useOptionals === "all" ? "?" : "";
|
|
352
|
-
return (0, ts_poet_1.code)
|
|
352
|
+
return (0, ts_poet_1.code) `${methodHead(ctx, "FieldMask", "unwrap")}(message: ${ctx.options.useReadonlyTypes ? "any" : (0, utils_1.wrapTypeName)(ctx.options, "FieldMask")}): ${returnType} {
|
|
353
353
|
return message${pathModifier}.paths;
|
|
354
354
|
}`;
|
|
355
355
|
}
|
|
356
|
+
function methodHead(ctx, name, method) {
|
|
357
|
+
return (0, utils_1.messageMethodHead)(ctx.options, (0, utils_1.wrapTypeName)(ctx.options, name), method);
|
|
358
|
+
}
|
|
356
359
|
function maybeReadonly(options) {
|
|
357
360
|
return options.useReadonlyTypes ? "readonly " : "";
|
|
358
361
|
}
|
package/build/src/main.js
CHANGED
|
@@ -69,7 +69,7 @@ function generateFile(ctx, fileDesc) {
|
|
|
69
69
|
chunks.push((0, enums_1.generateEnum)(ctx, fullName, enumDesc, sInfo));
|
|
70
70
|
});
|
|
71
71
|
// If nestJs=true export [package]_PACKAGE_NAME and [service]_SERVICE_NAME const
|
|
72
|
-
if (options.nestJs) {
|
|
72
|
+
if (options.nestJs.length > 0) {
|
|
73
73
|
if (options.exportCommonSymbols) {
|
|
74
74
|
const prefix = (0, case_1.camelToSnake)(fileDesc.package.replace(/\./g, "_"));
|
|
75
75
|
chunks.push((0, ts_poet_1.code) `export const ${prefix}_PACKAGE_NAME = '${fileDesc.package}';`);
|
|
@@ -85,7 +85,7 @@ function generateFile(ctx, fileDesc) {
|
|
|
85
85
|
options.outputJsonMethods ||
|
|
86
86
|
options.outputTypeAnnotations ||
|
|
87
87
|
options.outputTypeRegistry ||
|
|
88
|
-
options.nestJs) {
|
|
88
|
+
options.nestJs.length > 0) {
|
|
89
89
|
// then add the encoder/decoder/base instance
|
|
90
90
|
(0, visit_1.visit)(fileDesc, sourceInfo, (fullName, message, _sInfo, fullProtoTypeName) => {
|
|
91
91
|
const fullTypeName = (0, utils_1.maybePrefixPackage)(fileDesc, fullProtoTypeName);
|
|
@@ -98,18 +98,23 @@ function generateFile(ctx, fileDesc) {
|
|
|
98
98
|
(options.outputDecodeIncludeTypes === "" ||
|
|
99
99
|
new RegExp(options.outputDecodeIncludeTypes).test(fullTypeName))) ||
|
|
100
100
|
options.outputPartialMethods ||
|
|
101
|
-
(outputWrapAndUnwrap && !(options.nestJs && (0, types_1.isAnyValueTypeName)(fullTypeName)))) {
|
|
101
|
+
(outputWrapAndUnwrap && !(options.nestJs.length > 0 && (0, types_1.isAnyValueTypeName)(fullTypeName)))) {
|
|
102
102
|
chunks.push(generateBaseInstanceFactory(ctx, fullName, message, fullTypeName));
|
|
103
103
|
}
|
|
104
104
|
const staticMembers = [];
|
|
105
105
|
const hasTypeMember = options.outputTypeAnnotations || options.outputTypeRegistry;
|
|
106
|
-
if (hasTypeMember) {
|
|
106
|
+
if (hasTypeMember && !options.outputStandaloneFunctions) {
|
|
107
107
|
staticMembers.push((0, ts_poet_1.code) `$type: '${fullTypeName}' as const`);
|
|
108
108
|
}
|
|
109
109
|
if (options.outputExtensions) {
|
|
110
110
|
for (const extension of message.extension) {
|
|
111
111
|
const { name, type, extensionInfo } = generateExtension(ctx, message, extension);
|
|
112
|
-
|
|
112
|
+
if (options.outputStandaloneFunctions) {
|
|
113
|
+
staticMembers.push((0, ts_poet_1.code) `export const ${(0, ts_poet_1.def)((0, utils_1.messageFunctionName)(fullName, name))}: ${ctx.utils.Extension}<${type}> = ${extensionInfo};`);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
staticMembers.push((0, ts_poet_1.code) `${name}: <${ctx.utils.Extension}<${type}>> ${extensionInfo}`);
|
|
117
|
+
}
|
|
113
118
|
}
|
|
114
119
|
}
|
|
115
120
|
if (options.outputEncodeMethods) {
|
|
@@ -124,7 +129,7 @@ function generateFile(ctx, fileDesc) {
|
|
|
124
129
|
}
|
|
125
130
|
}
|
|
126
131
|
else if (options.outputEncodeMethods === true) {
|
|
127
|
-
staticMembers.push(generateEmptyEncode(fullName));
|
|
132
|
+
staticMembers.push(generateEmptyEncode(ctx, fullName));
|
|
128
133
|
}
|
|
129
134
|
}
|
|
130
135
|
if (options.outputEncodeMethods === true || options.outputEncodeMethods === "decode-only") {
|
|
@@ -136,13 +141,13 @@ function generateFile(ctx, fileDesc) {
|
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
else if (options.outputEncodeMethods === true) {
|
|
139
|
-
staticMembers.push(generateEmptyDecode(fullName));
|
|
144
|
+
staticMembers.push(generateEmptyDecode(ctx, fullName));
|
|
140
145
|
}
|
|
141
146
|
}
|
|
142
147
|
}
|
|
143
148
|
if (options.useAsyncIterable) {
|
|
144
|
-
staticMembers.push((0, generate_async_iterable_1.generateEncodeTransform)(ctx
|
|
145
|
-
staticMembers.push((0, generate_async_iterable_1.generateDecodeTransform)(ctx
|
|
149
|
+
staticMembers.push((0, generate_async_iterable_1.generateEncodeTransform)(ctx, fullName));
|
|
150
|
+
staticMembers.push((0, generate_async_iterable_1.generateDecodeTransform)(ctx, fullName));
|
|
146
151
|
}
|
|
147
152
|
if (options.outputJsonMethods) {
|
|
148
153
|
if (options.outputJsonMethods === true || options.outputJsonMethods === "from-only") {
|
|
@@ -163,7 +168,7 @@ function generateFile(ctx, fileDesc) {
|
|
|
163
168
|
structValue: (0, utils_1.getFieldName)({ name: "struct_value", jsonName: (0, case_1.snakeToCamel)("struct_value") }, ctx.options),
|
|
164
169
|
listValue: (0, utils_1.getFieldName)({ name: "list_value", jsonName: (0, case_1.snakeToCamel)("list_value") }, ctx.options),
|
|
165
170
|
};
|
|
166
|
-
if (options.nestJs) {
|
|
171
|
+
if (options.nestJs.length > 0) {
|
|
167
172
|
staticMembers.push(...(0, generate_struct_wrappers_1.generateWrapDeep)(ctx, fullTypeName, structFieldNames));
|
|
168
173
|
staticMembers.push(...(0, generate_struct_wrappers_1.generateUnwrapDeep)(ctx, fullTypeName, structFieldNames));
|
|
169
174
|
}
|
|
@@ -171,7 +176,10 @@ function generateFile(ctx, fileDesc) {
|
|
|
171
176
|
staticMembers.push(...(0, generate_struct_wrappers_1.generateWrapShallow)(ctx, fullTypeName, structFieldNames));
|
|
172
177
|
staticMembers.push(...(0, generate_struct_wrappers_1.generateUnwrapShallow)(ctx, fullTypeName, structFieldNames));
|
|
173
178
|
}
|
|
174
|
-
if (
|
|
179
|
+
if (options.outputStandaloneFunctions) {
|
|
180
|
+
chunks.push(...staticMembers);
|
|
181
|
+
}
|
|
182
|
+
else if (staticMembers.length > 0) {
|
|
175
183
|
const messageFnsTypeParameters = [fullName, hasTypeMember && `'${fullTypeName}'`]
|
|
176
184
|
.filter((p) => !!p)
|
|
177
185
|
.join(", ");
|
|
@@ -224,7 +232,7 @@ function generateFile(ctx, fileDesc) {
|
|
|
224
232
|
chunks.push((0, ts_poet_1.code) `export const ${name}: ${ctx.utils.Extension}<${type}> = ${extensionInfo};`);
|
|
225
233
|
}
|
|
226
234
|
}
|
|
227
|
-
if (options.nestJs) {
|
|
235
|
+
if (options.nestJs.length > 0) {
|
|
228
236
|
if (fileDesc.messageType.find(hasStructTypeField)) {
|
|
229
237
|
chunks.push(makeProtobufStructWrapper(options));
|
|
230
238
|
}
|
|
@@ -232,14 +240,18 @@ function generateFile(ctx, fileDesc) {
|
|
|
232
240
|
let hasServerStreamingMethods = false;
|
|
233
241
|
let hasStreamingMethods = false;
|
|
234
242
|
(0, visit_1.visitServices)(fileDesc, sourceInfo, (serviceDesc, sInfo) => {
|
|
235
|
-
if (options.nestJs) {
|
|
243
|
+
if (options.nestJs.length > 0) {
|
|
236
244
|
// NestJS is sufficiently different that we special case the client/server interfaces
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
245
|
+
if (options.nestJs.includes("client")) {
|
|
246
|
+
// generate nestjs grpc client interface
|
|
247
|
+
chunks.push((0, generate_nestjs_1.generateNestjsServiceClient)(ctx, fileDesc, sInfo, serviceDesc));
|
|
248
|
+
}
|
|
249
|
+
if (options.nestJs.includes("server")) {
|
|
250
|
+
// generate nestjs grpc service controller interface
|
|
251
|
+
chunks.push((0, generate_nestjs_1.generateNestjsServiceController)(ctx, fileDesc, sInfo, serviceDesc));
|
|
252
|
+
// generate nestjs grpc service controller decorator
|
|
253
|
+
chunks.push((0, generate_nestjs_1.generateNestjsGrpcServiceMethodsDecorator)(ctx, fileDesc, serviceDesc));
|
|
254
|
+
}
|
|
243
255
|
let serviceConstName = `${(0, case_1.camelToSnake)(serviceDesc.name)}_NAME`;
|
|
244
256
|
if (!serviceDesc.name.toLowerCase().endsWith("service")) {
|
|
245
257
|
serviceConstName = `${(0, case_1.camelToSnake)(serviceDesc.name)}_SERVICE_NAME`;
|
|
@@ -694,7 +706,7 @@ function makeObjectIdMethods() {
|
|
|
694
706
|
return { fromJsonObjectId, fromProtoObjectId, toProtoObjectId };
|
|
695
707
|
}
|
|
696
708
|
function makeTimestampMethods(options, longs, bytes) {
|
|
697
|
-
const Timestamp = (0, utils_1.impProto)(options, "google/protobuf/timestamp", (0, utils_1.wrapTypeName)(options, "Timestamp"));
|
|
709
|
+
const Timestamp = (0, utils_1.impProto)(options, "google/protobuf/timestamp", (0, utils_1.wrapTypeName)(options, "Timestamp"), options.outputStandaloneFunctions);
|
|
698
710
|
const NanoDate = (0, ts_poet_1.imp)("NanoDate=nano-date");
|
|
699
711
|
let seconds = "Math.trunc(date.getTime() / 1_000)";
|
|
700
712
|
let toNumberCode = "t.seconds";
|
|
@@ -800,6 +812,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
800
812
|
`);
|
|
801
813
|
// Declared once per file, so the regex isn't compiled on each fromJsonTimestamp call
|
|
802
814
|
const timestampFractionRegex = (0, ts_poet_1.conditionalOutput)("timestampFractionRegex", (0, ts_poet_1.code) `const timestampFractionRegex = /:\\d{2}\\.\\d+/;`);
|
|
815
|
+
const timestampMessageFromJson = (0, utils_1.impProtoMethod)(options, "google/protobuf/timestamp", (0, utils_1.wrapTypeName)(options, "Timestamp"), "fromJSON");
|
|
803
816
|
const fromJsonTimestamp = (0, ts_poet_1.conditionalOutput)("fromJsonTimestamp", options.useDate === options_1.DateOption.DATE
|
|
804
817
|
? (0, ts_poet_1.code) `
|
|
805
818
|
function fromJsonTimestamp(o: any): Date {
|
|
@@ -808,7 +821,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
808
821
|
} else if (typeof o === "string") {
|
|
809
822
|
return new ${bytes.globalThis}.Date(o);
|
|
810
823
|
} else {
|
|
811
|
-
return ${fromTimestamp}(${
|
|
824
|
+
return ${fromTimestamp}(${timestampMessageFromJson}(o));
|
|
812
825
|
}
|
|
813
826
|
}
|
|
814
827
|
`
|
|
@@ -820,7 +833,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
820
833
|
} else if (typeof o === "string") {
|
|
821
834
|
return ${bytes.globalThis}.Temporal.Instant.from(o);
|
|
822
835
|
} else {
|
|
823
|
-
return ${fromTimestamp}(${
|
|
836
|
+
return ${fromTimestamp}(${timestampMessageFromJson}(o));
|
|
824
837
|
}
|
|
825
838
|
}
|
|
826
839
|
`
|
|
@@ -842,7 +855,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
842
855
|
);
|
|
843
856
|
return { ...timestamp, nanos: (timestamp.nanos ?? 0) + (fractionNanos % 1_000_000) };
|
|
844
857
|
} else {
|
|
845
|
-
return ${
|
|
858
|
+
return ${timestampMessageFromJson}(o);
|
|
846
859
|
}
|
|
847
860
|
}
|
|
848
861
|
`);
|
|
@@ -1123,14 +1136,13 @@ function getDecodeReadSnippet(ctx, field) {
|
|
|
1123
1136
|
}
|
|
1124
1137
|
}
|
|
1125
1138
|
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
1126
|
-
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
1127
1139
|
const unwrap = (decodedValue) => {
|
|
1128
1140
|
if ((0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isAnyValueType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
1129
|
-
return (0, ts_poet_1.code) `${
|
|
1141
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "unwrap")}(${decodedValue})`;
|
|
1130
1142
|
}
|
|
1131
1143
|
return (0, ts_poet_1.code) `${decodedValue}.value`;
|
|
1132
1144
|
};
|
|
1133
|
-
const decoder = (0, ts_poet_1.code) `${
|
|
1145
|
+
const decoder = (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "decode")}(reader, reader.uint32())`;
|
|
1134
1146
|
readSnippet = (0, ts_poet_1.code) `${unwrap(decoder)}`;
|
|
1135
1147
|
}
|
|
1136
1148
|
else if ((0, types_1.isTimestamp)(field) &&
|
|
@@ -1138,20 +1150,20 @@ function getDecodeReadSnippet(ctx, field) {
|
|
|
1138
1150
|
options.useDate === options_1.DateOption.STRING ||
|
|
1139
1151
|
options.useDate === options_1.DateOption.STRING_NANO ||
|
|
1140
1152
|
options.useDate === options_1.DateOption.TEMPORAL)) {
|
|
1141
|
-
const
|
|
1142
|
-
readSnippet = (0, ts_poet_1.code) `${utils.fromTimestamp}(${
|
|
1153
|
+
const decode = (0, types_1.getMessageMethod)(ctx, field.typeName, "decode");
|
|
1154
|
+
readSnippet = (0, ts_poet_1.code) `${utils.fromTimestamp}(${decode}(reader, reader.uint32()))`;
|
|
1143
1155
|
}
|
|
1144
1156
|
else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
|
|
1145
1157
|
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
1146
1158
|
readSnippet = (0, ts_poet_1.code) `${utils.fromProtoObjectId}(${type}.decode(reader, reader.uint32()))`;
|
|
1147
1159
|
}
|
|
1148
1160
|
else if ((0, types_1.isMessage)(field)) {
|
|
1149
|
-
const
|
|
1161
|
+
const decode = (0, types_1.getMessageMethod)(ctx, field.typeName, "decode");
|
|
1150
1162
|
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP) {
|
|
1151
|
-
readSnippet = (0, ts_poet_1.code) `${
|
|
1163
|
+
readSnippet = (0, ts_poet_1.code) `${decode}(reader)`;
|
|
1152
1164
|
}
|
|
1153
1165
|
else {
|
|
1154
|
-
readSnippet = (0, ts_poet_1.code) `${
|
|
1166
|
+
readSnippet = (0, ts_poet_1.code) `${decode}(reader, reader.uint32())`;
|
|
1155
1167
|
}
|
|
1156
1168
|
}
|
|
1157
1169
|
else {
|
|
@@ -1159,10 +1171,10 @@ function getDecodeReadSnippet(ctx, field) {
|
|
|
1159
1171
|
}
|
|
1160
1172
|
return readSnippet;
|
|
1161
1173
|
}
|
|
1162
|
-
function generateEmptyDecode(fullName) {
|
|
1174
|
+
function generateEmptyDecode(ctx, fullName) {
|
|
1163
1175
|
const BinaryReader = (0, ts_poet_1.imp)("t:BinaryReader@@bufbuild/protobuf/wire");
|
|
1164
1176
|
return (0, ts_poet_1.code) `
|
|
1165
|
-
decode(
|
|
1177
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "decode")}(
|
|
1166
1178
|
_: ${BinaryReader} | Uint8Array,
|
|
1167
1179
|
length?: number,
|
|
1168
1180
|
): ${fullName} {
|
|
@@ -1181,7 +1193,7 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
1181
1193
|
const BinaryReader = (0, ts_poet_1.imp)("BinaryReader@@bufbuild/protobuf/wire");
|
|
1182
1194
|
// create the basic function declaration
|
|
1183
1195
|
chunks.push((0, ts_poet_1.code) `
|
|
1184
|
-
decode(
|
|
1196
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "decode")}(
|
|
1185
1197
|
input: ${BinaryReader} | Uint8Array,
|
|
1186
1198
|
length?: number,
|
|
1187
1199
|
): ${fullName} {
|
|
@@ -1411,38 +1423,38 @@ function getEncodeWriteSnippet(ctx, field) {
|
|
|
1411
1423
|
options.useDate === options_1.DateOption.STRING_NANO ||
|
|
1412
1424
|
options.useDate === options_1.DateOption.TEMPORAL)) {
|
|
1413
1425
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
1414
|
-
const
|
|
1415
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1426
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1427
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${utils.toTimestamp}(${place}), writer.uint32(${tag}).fork()).join()`;
|
|
1416
1428
|
}
|
|
1417
1429
|
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
1418
1430
|
const maybeTypeField = (0, options_1.addTypeToMessages)(options) ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
1419
|
-
const
|
|
1431
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1420
1432
|
const wrappedValue = (place) => {
|
|
1421
1433
|
if ((0, types_1.isAnyValueType)(field) || (0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
1422
|
-
return (0, ts_poet_1.code) `${
|
|
1434
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "wrap")}(${place})`;
|
|
1423
1435
|
}
|
|
1424
1436
|
return (0, ts_poet_1.code) `{${maybeTypeField} value: ${place}!}`;
|
|
1425
1437
|
};
|
|
1426
1438
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
1427
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1439
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${wrappedValue(place)}, writer.uint32(${tag}).fork()).join()`;
|
|
1428
1440
|
}
|
|
1429
1441
|
else if ((0, types_1.isMessage)(field)) {
|
|
1430
|
-
const
|
|
1442
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1431
1443
|
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP) {
|
|
1432
1444
|
const startTag = ((field.number << 3) | 3) >>> 0, endTag = ((field.number << 3) | 4) >>> 0;
|
|
1433
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1445
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${place}, writer.uint32(${startTag})).uint32(${endTag})`;
|
|
1434
1446
|
}
|
|
1435
1447
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
1436
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1448
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${place}, writer.uint32(${tag}).fork()).join()`;
|
|
1437
1449
|
}
|
|
1438
1450
|
else {
|
|
1439
1451
|
throw new Error(`Unhandled field ${field}`);
|
|
1440
1452
|
}
|
|
1441
1453
|
}
|
|
1442
|
-
function generateEmptyEncode(fullName) {
|
|
1454
|
+
function generateEmptyEncode(ctx, fullName) {
|
|
1443
1455
|
const BinaryWriter = (0, ts_poet_1.imp)("BinaryWriter@@bufbuild/protobuf/wire");
|
|
1444
1456
|
return (0, ts_poet_1.code) `
|
|
1445
|
-
encode(
|
|
1457
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "encode")}(
|
|
1446
1458
|
_: ${fullName},
|
|
1447
1459
|
writer: ${BinaryWriter} = new ${BinaryWriter}(),
|
|
1448
1460
|
): ${BinaryWriter} {
|
|
@@ -1457,7 +1469,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1457
1469
|
const BinaryWriter = (0, ts_poet_1.imp)("BinaryWriter@@bufbuild/protobuf/wire");
|
|
1458
1470
|
// create the basic function declaration
|
|
1459
1471
|
chunks.push((0, ts_poet_1.code) `
|
|
1460
|
-
encode(
|
|
1472
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "encode")}(
|
|
1461
1473
|
${messageDesc.field.length > 0 || options.unknownFields ? "message" : "_"}: ${fullName},
|
|
1462
1474
|
writer: ${BinaryWriter} = new ${BinaryWriter}(),
|
|
1463
1475
|
): ${BinaryWriter} {
|
|
@@ -1673,7 +1685,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1673
1685
|
}
|
|
1674
1686
|
function generateSetExtension(ctx, fullName) {
|
|
1675
1687
|
return (0, ts_poet_1.code) `
|
|
1676
|
-
setExtension <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>, value: T): void {
|
|
1688
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "setExtension")} <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>, value: T): void {
|
|
1677
1689
|
const encoded = extension.encode!(value);
|
|
1678
1690
|
|
|
1679
1691
|
if (message._unknownFields !== undefined) {
|
|
@@ -1699,7 +1711,7 @@ function generateSetExtension(ctx, fullName) {
|
|
|
1699
1711
|
}
|
|
1700
1712
|
function generateGetExtension(ctx, fullName) {
|
|
1701
1713
|
return (0, ts_poet_1.code) `
|
|
1702
|
-
getExtension <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>): T | undefined {
|
|
1714
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "getExtension")} <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>): T | undefined {
|
|
1703
1715
|
let results: T | undefined = undefined;
|
|
1704
1716
|
|
|
1705
1717
|
if (message._unknownFields === undefined) {
|
|
@@ -1787,27 +1799,27 @@ function generateExtension(ctx, message, extension) {
|
|
|
1787
1799
|
options.useDate === options_1.DateOption.STRING ||
|
|
1788
1800
|
options.useDate === options_1.DateOption.STRING_NANO ||
|
|
1789
1801
|
options.useDate === options_1.DateOption.TEMPORAL)) {
|
|
1790
|
-
const
|
|
1791
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1802
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1803
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${utils.toTimestamp}(${place}), writer.fork()).join()`;
|
|
1792
1804
|
}
|
|
1793
1805
|
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
1794
1806
|
const maybeTypeField = (0, options_1.addTypeToMessages)(options) ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
1795
|
-
const
|
|
1807
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1796
1808
|
const wrappedValue = (place) => {
|
|
1797
1809
|
if ((0, types_1.isAnyValueType)(field) || (0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
1798
|
-
return (0, ts_poet_1.code) `${
|
|
1810
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "wrap")}(${place})`;
|
|
1799
1811
|
}
|
|
1800
1812
|
return (0, ts_poet_1.code) `{${maybeTypeField} value: ${place}!}`;
|
|
1801
1813
|
};
|
|
1802
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1814
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${wrappedValue(place)}, writer.fork()).join()`;
|
|
1803
1815
|
}
|
|
1804
1816
|
else if ((0, types_1.isMessage)(field)) {
|
|
1805
|
-
const
|
|
1817
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1806
1818
|
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP) {
|
|
1807
1819
|
const endTag = ((field.number << 3) | 4) >>> 0;
|
|
1808
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1820
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${place}, writer).uint32(${endTag})`;
|
|
1809
1821
|
}
|
|
1810
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1822
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${place}, writer.fork()).join()`;
|
|
1811
1823
|
}
|
|
1812
1824
|
else {
|
|
1813
1825
|
throw new Error(`Unhandled field ${field}`);
|
|
@@ -1962,7 +1974,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1962
1974
|
break;
|
|
1963
1975
|
}
|
|
1964
1976
|
return (0, ts_poet_1.code) `
|
|
1965
|
-
fromJSON(object: string): ${fullName} {
|
|
1977
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromJSON")}(object: string): ${fullName} {
|
|
1966
1978
|
if (!object.endsWith("s")) throw new Error("Invalid duration string");
|
|
1967
1979
|
const body = object.slice(0, -1);
|
|
1968
1980
|
const negative = body.startsWith("-");
|
|
@@ -1982,21 +1994,21 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1982
1994
|
if (fullTypeName === "google.protobuf.Timestamp") {
|
|
1983
1995
|
// The canonical JSON of a Timestamp is an RFC 3339 string; the object form is still accepted.
|
|
1984
1996
|
chunks.push((0, ts_poet_1.code) `
|
|
1985
|
-
fromJSON(object: any): ${fullName} {
|
|
1997
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromJSON")}(object: any): ${fullName} {
|
|
1986
1998
|
if (typeof object === "string") {
|
|
1987
|
-
return ${fullName}
|
|
1999
|
+
return ${(0, utils_1.localMessageMethod)(options, fullName, "fromJSON")}(${utils.timestampFromJson}(object));
|
|
1988
2000
|
}
|
|
1989
2001
|
return {
|
|
1990
2002
|
`);
|
|
1991
2003
|
}
|
|
1992
2004
|
else {
|
|
1993
2005
|
chunks.push((0, ts_poet_1.code) `
|
|
1994
|
-
fromJSON(${messageDesc.field.length > 0 ? "object" : "_"}: any): ${fullName} {
|
|
2006
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromJSON")}(${messageDesc.field.length > 0 ? "object" : "_"}: any): ${fullName} {
|
|
1995
2007
|
return {
|
|
1996
2008
|
`);
|
|
1997
2009
|
}
|
|
1998
2010
|
if ((0, options_1.addTypeToMessages)(options)) {
|
|
1999
|
-
chunks.push((0, ts_poet_1.code) `$type: ${fullName}.$type,`);
|
|
2011
|
+
chunks.push(options.outputStandaloneFunctions ? (0, ts_poet_1.code) `$type: '${fullTypeName}',` : (0, ts_poet_1.code) `$type: ${fullName}.$type,`);
|
|
2000
2012
|
}
|
|
2001
2013
|
const oneofFieldsCases = messageDesc.oneofDecl.map((oneof, oneofIndex) => messageDesc.field.filter(types_1.isWithinOneOf).filter((field) => field.oneofIndex === oneofIndex));
|
|
2002
2014
|
const canonicalFromJson = {
|
|
@@ -2065,8 +2077,9 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2065
2077
|
return (0, ts_poet_1.code) `${from}`;
|
|
2066
2078
|
}
|
|
2067
2079
|
else if ((0, types_1.isFieldMaskType)(field)) {
|
|
2068
|
-
const
|
|
2069
|
-
|
|
2080
|
+
const unwrap = (0, types_1.getMessageMethod)(ctx, field.typeName, "unwrap");
|
|
2081
|
+
const fromJson = (0, types_1.getMessageMethod)(ctx, field.typeName, "fromJSON");
|
|
2082
|
+
return (0, ts_poet_1.code) `${unwrap}(${fromJson}(${from}))`;
|
|
2070
2083
|
}
|
|
2071
2084
|
else if ((0, types_1.isListValueType)(field)) {
|
|
2072
2085
|
return (0, ts_poet_1.code) `[...${from}]`;
|
|
@@ -2125,12 +2138,11 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2125
2138
|
return (0, ts_poet_1.code) `${from}`;
|
|
2126
2139
|
}
|
|
2127
2140
|
else {
|
|
2128
|
-
return (0, ts_poet_1.code) `${
|
|
2141
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, valueField.typeName, "fromJSON")}(${from})`;
|
|
2129
2142
|
}
|
|
2130
2143
|
}
|
|
2131
2144
|
else {
|
|
2132
|
-
|
|
2133
|
-
return (0, ts_poet_1.code) `${type}.fromJSON(${from})`;
|
|
2145
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "fromJSON")}(${from})`;
|
|
2134
2146
|
}
|
|
2135
2147
|
}
|
|
2136
2148
|
else {
|
|
@@ -2300,12 +2312,13 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2300
2312
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
2301
2313
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
2302
2314
|
}
|
|
2303
|
-
function generateCanonicalToJson(fullName, fullProtobufTypeName,
|
|
2315
|
+
function generateCanonicalToJson(fullName, fullProtobufTypeName, options, utils) {
|
|
2316
|
+
const { useOptionals, useNullAsOptional, useDuration, useJsonTimestamp, forceLong } = options;
|
|
2304
2317
|
if ((0, types_1.isFieldMaskTypeName)(fullProtobufTypeName)) {
|
|
2305
2318
|
const returnType = useOptionals === "all" ? `string | ${(0, utils_1.nullOrUndefined)({ useNullAsOptional })}` : "string";
|
|
2306
2319
|
const pathModifier = useOptionals === "all" ? "?" : "";
|
|
2307
2320
|
return (0, ts_poet_1.code) `
|
|
2308
|
-
toJSON(message: ${fullName}): ${returnType} {
|
|
2321
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(message: ${fullName}): ${returnType} {
|
|
2309
2322
|
return message.paths${pathModifier}.join(',');
|
|
2310
2323
|
}
|
|
2311
2324
|
`;
|
|
@@ -2334,7 +2347,7 @@ function generateCanonicalToJson(fullName, fullProtobufTypeName, { useOptionals,
|
|
|
2334
2347
|
break;
|
|
2335
2348
|
}
|
|
2336
2349
|
return (0, ts_poet_1.code) `
|
|
2337
|
-
toJSON(message: ${fullName}): string {
|
|
2350
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(message: ${fullName}): string {
|
|
2338
2351
|
const negative = ${isNegSeconds} || message.nanos < 0;
|
|
2339
2352
|
const sign = negative ? "-" : "";
|
|
2340
2353
|
const absSeconds = ${absSeconds};
|
|
@@ -2351,7 +2364,7 @@ function generateCanonicalToJson(fullName, fullProtobufTypeName, { useOptionals,
|
|
|
2351
2364
|
? (0, ts_poet_1.code) `message.seconds?.toNumber() ?? 0`
|
|
2352
2365
|
: (0, ts_poet_1.code) `${utils.globalThis}.Number(message.seconds ?? 0)`;
|
|
2353
2366
|
return (0, ts_poet_1.code) `
|
|
2354
|
-
toJSON(message: ${fullName}): string {
|
|
2367
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(message: ${fullName}): string {
|
|
2355
2368
|
return ${utils.timestampToJson}(${seconds}, message.nanos ?? 0);
|
|
2356
2369
|
}
|
|
2357
2370
|
`;
|
|
@@ -2381,7 +2394,7 @@ function generateCanonicalAnyToJson(ctx, fullName, messageDesc) {
|
|
|
2381
2394
|
const typeUrl = (0, utils_1.getPropertyAccessor)("message", (0, utils_1.getFieldName)(typeUrlField, options));
|
|
2382
2395
|
const value = (0, utils_1.getPropertyAccessor)("message", (0, utils_1.getFieldName)(valueField, options));
|
|
2383
2396
|
return (0, ts_poet_1.code) `
|
|
2384
|
-
toJSON(message: ${fullName}): unknown {
|
|
2397
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(message: ${fullName}): unknown {
|
|
2385
2398
|
const typeUrl = ${typeUrl} ?? "";
|
|
2386
2399
|
if (typeUrl === "") {
|
|
2387
2400
|
return {};
|
|
@@ -2408,7 +2421,7 @@ function generateCanonicalAnyFromJson(ctx, fullName, messageDesc) {
|
|
|
2408
2421
|
const typeField = (0, options_1.addTypeToMessages)(options) ? (0, ts_poet_1.code) `$type: ${fullName}.$type,` : "";
|
|
2409
2422
|
const bytes = options.env === options_1.EnvOption.NODE ? (0, ts_poet_1.code) `Buffer.from(bytes)` : (0, ts_poet_1.code) `bytes`;
|
|
2410
2423
|
return (0, ts_poet_1.code) `
|
|
2411
|
-
fromJSON(object: any): ${fullName} {
|
|
2424
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromJSON")}(object: any): ${fullName} {
|
|
2412
2425
|
const typeUrl = ${utils.isSet}(object?.["@type"]) ? ${utils.globalThis}.String(object["@type"]) : "";
|
|
2413
2426
|
if (typeUrl === "") {
|
|
2414
2427
|
return { ${typeField} ${typeUrlKey}: ${(0, types_1.defaultValue)(ctx, typeUrlField)}, ${valueKey}: ${(0, types_1.defaultValue)(ctx, valueField)} };
|
|
@@ -2442,7 +2455,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2442
2455
|
}
|
|
2443
2456
|
// create the basic function declaration
|
|
2444
2457
|
chunks.push((0, ts_poet_1.code) `
|
|
2445
|
-
toJSON(${messageDesc.field.length > 0 ? "message" : "_"}: ${fullName}): unknown {
|
|
2458
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(${messageDesc.field.length > 0 ? "message" : "_"}: ${fullName}): unknown {
|
|
2446
2459
|
const obj: any = {};
|
|
2447
2460
|
`);
|
|
2448
2461
|
let currentIfTarget = "";
|
|
@@ -2528,20 +2541,19 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2528
2541
|
return (0, ts_poet_1.code) `${from}`;
|
|
2529
2542
|
}
|
|
2530
2543
|
else {
|
|
2531
|
-
|
|
2532
|
-
return (0, ts_poet_1.code) `${type}.toJSON(${from})`;
|
|
2544
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, valueType.typeName, "toJSON")}(${from})`;
|
|
2533
2545
|
}
|
|
2534
2546
|
}
|
|
2535
2547
|
else if ((0, types_1.isAnyValueType)(field)) {
|
|
2536
2548
|
return (0, ts_poet_1.code) `${from}`;
|
|
2537
2549
|
}
|
|
2538
2550
|
else if ((0, types_1.isFieldMaskType)(field)) {
|
|
2539
|
-
const
|
|
2540
|
-
|
|
2551
|
+
const toJson = (0, types_1.getMessageMethod)(ctx, field.typeName, "toJSON");
|
|
2552
|
+
const wrap = (0, types_1.getMessageMethod)(ctx, field.typeName, "wrap");
|
|
2553
|
+
return (0, ts_poet_1.code) `${toJson}(${wrap}(${from}))`;
|
|
2541
2554
|
}
|
|
2542
2555
|
else if ((0, types_1.isMessage)(field) && !(0, types_1.isValueType)(ctx, field) && !(0, types_1.isMapType)(ctx, messageDesc, field)) {
|
|
2543
|
-
|
|
2544
|
-
return (0, ts_poet_1.code) `${type}.toJSON(${from})`;
|
|
2556
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "toJSON")}(${from})`;
|
|
2545
2557
|
}
|
|
2546
2558
|
else if ((0, types_1.isBytes)(field)) {
|
|
2547
2559
|
return (0, ts_poet_1.code) `${utils.base64FromBytes}(${from})`;
|
|
@@ -2641,31 +2653,32 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2641
2653
|
function generateFromPartial(ctx, fullName, messageDesc) {
|
|
2642
2654
|
const { options, utils } = ctx;
|
|
2643
2655
|
const chunks = [];
|
|
2656
|
+
const maybeComma = options.outputStandaloneFunctions ? "" : ",";
|
|
2644
2657
|
// create the create function definition
|
|
2645
2658
|
if (ctx.options.useExactTypes) {
|
|
2646
2659
|
chunks.push((0, ts_poet_1.code) `
|
|
2647
|
-
create<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(base?: I): ${fullName} {
|
|
2648
|
-
return ${fullName}
|
|
2649
|
-
}
|
|
2660
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "create")}<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(base?: I): ${fullName} {
|
|
2661
|
+
return ${(0, utils_1.localMessageMethod)(options, fullName, "fromPartial")}(base ?? ({} as any));
|
|
2662
|
+
}${maybeComma}
|
|
2650
2663
|
`);
|
|
2651
2664
|
}
|
|
2652
2665
|
else {
|
|
2653
2666
|
chunks.push((0, ts_poet_1.code) `
|
|
2654
|
-
create(base?: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
2655
|
-
return ${fullName}
|
|
2656
|
-
}
|
|
2667
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "create")}(base?: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
2668
|
+
return ${(0, utils_1.localMessageMethod)(options, fullName, "fromPartial")}(base ?? {});
|
|
2669
|
+
}${maybeComma}
|
|
2657
2670
|
`);
|
|
2658
2671
|
}
|
|
2659
2672
|
// create the fromPartial function declaration
|
|
2660
2673
|
const paramName = messageDesc.field.length > 0 ? "object" : "_";
|
|
2661
2674
|
if (ctx.options.useExactTypes) {
|
|
2662
2675
|
chunks.push((0, ts_poet_1.code) `
|
|
2663
|
-
fromPartial<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(${paramName}: I): ${fullName} {
|
|
2676
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromPartial")}<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(${paramName}: I): ${fullName} {
|
|
2664
2677
|
`);
|
|
2665
2678
|
}
|
|
2666
2679
|
else {
|
|
2667
2680
|
chunks.push((0, ts_poet_1.code) `
|
|
2668
|
-
fromPartial(${paramName}: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
2681
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromPartial")}(${paramName}: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
2669
2682
|
`);
|
|
2670
2683
|
}
|
|
2671
2684
|
let createBase = (0, ts_poet_1.code) `createBase${fullName}()`;
|
|
@@ -2745,16 +2758,14 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
2745
2758
|
return (0, ts_poet_1.code) `${from}`;
|
|
2746
2759
|
}
|
|
2747
2760
|
else {
|
|
2748
|
-
|
|
2749
|
-
return (0, ts_poet_1.code) `${type}.fromPartial(${from})`;
|
|
2761
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, valueField.typeName, "fromPartial")}(${from})`;
|
|
2750
2762
|
}
|
|
2751
2763
|
}
|
|
2752
2764
|
else if ((0, types_1.isAnyValueType)(field)) {
|
|
2753
2765
|
return (0, ts_poet_1.code) `${from}`;
|
|
2754
2766
|
}
|
|
2755
2767
|
else {
|
|
2756
|
-
|
|
2757
|
-
return (0, ts_poet_1.code) `${type}.fromPartial(${from})`;
|
|
2768
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "fromPartial")}(${from})`;
|
|
2758
2769
|
}
|
|
2759
2770
|
}
|
|
2760
2771
|
else {
|
package/build/src/options.d.ts
CHANGED
|
@@ -69,6 +69,7 @@ export type Options = {
|
|
|
69
69
|
outputDecodeIncludeTypes: string;
|
|
70
70
|
outputJsonMethods: true | false | "to-only" | "from-only";
|
|
71
71
|
outputPartialMethods: boolean;
|
|
72
|
+
outputStandaloneFunctions: boolean;
|
|
72
73
|
outputTypeAnnotations: boolean | "static-only" | "optional";
|
|
73
74
|
outputTypeRegistry: boolean;
|
|
74
75
|
stringEnums: boolean;
|
|
@@ -83,7 +84,7 @@ export type Options = {
|
|
|
83
84
|
useNestjsFqnServiceName: boolean;
|
|
84
85
|
returnObservable: boolean;
|
|
85
86
|
lowerCaseServiceMethods: boolean;
|
|
86
|
-
nestJs:
|
|
87
|
+
nestJs: Array<"client" | "server">;
|
|
87
88
|
env: EnvOption;
|
|
88
89
|
unrecognizedEnum: boolean;
|
|
89
90
|
unrecognizedEnumName: string;
|
package/build/src/options.js
CHANGED
|
@@ -86,6 +86,7 @@ function defaultOptions() {
|
|
|
86
86
|
outputDecodeIncludeTypes: "",
|
|
87
87
|
outputJsonMethods: true,
|
|
88
88
|
outputPartialMethods: true,
|
|
89
|
+
outputStandaloneFunctions: false,
|
|
89
90
|
outputTypeAnnotations: false,
|
|
90
91
|
outputTypeRegistry: false,
|
|
91
92
|
stringEnums: false,
|
|
@@ -99,7 +100,7 @@ function defaultOptions() {
|
|
|
99
100
|
metadataType: undefined,
|
|
100
101
|
addNestjsRestParameter: false,
|
|
101
102
|
useNestjsFqnServiceName: false,
|
|
102
|
-
nestJs:
|
|
103
|
+
nestJs: [],
|
|
103
104
|
env: EnvOption.BOTH,
|
|
104
105
|
unrecognizedEnum: true,
|
|
105
106
|
unrecognizedEnumName: "UNRECOGNIZED",
|
|
@@ -161,17 +162,32 @@ function optionsFromParameter(parameter) {
|
|
|
161
162
|
}
|
|
162
163
|
Object.assign(options, parsed);
|
|
163
164
|
}
|
|
165
|
+
// Treat nestJs=true as both the client & server interfaces, and nestJs=false as neither
|
|
166
|
+
if (options.nestJs === true) {
|
|
167
|
+
options.nestJs = ["client", "server"];
|
|
168
|
+
}
|
|
169
|
+
else if (options.nestJs === false) {
|
|
170
|
+
options.nestJs = [];
|
|
171
|
+
}
|
|
172
|
+
else if (typeof options.nestJs === "string") {
|
|
173
|
+
options.nestJs = [options.nestJs];
|
|
174
|
+
}
|
|
175
|
+
for (const value of options.nestJs) {
|
|
176
|
+
if (value !== "client" && value !== "server") {
|
|
177
|
+
throw new Error(`nestJs must be true, false, client, or server, but got '${value}'`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
164
180
|
// onlyTypes=true implies outputJsonMethods=false,outputEncodeMethods=false,outputClientImpl=false,nestJs=false
|
|
165
181
|
if (options.onlyTypes) {
|
|
166
182
|
options.outputJsonMethods = false;
|
|
167
183
|
options.outputEncodeMethods = false;
|
|
168
184
|
options.outputClientImpl = false;
|
|
169
|
-
options.nestJs =
|
|
185
|
+
options.nestJs = [];
|
|
170
186
|
}
|
|
171
187
|
else if (!options.outputJsonMethods &&
|
|
172
188
|
!options.outputEncodeMethods &&
|
|
173
189
|
!options.outputClientImpl &&
|
|
174
|
-
|
|
190
|
+
options.nestJs.length === 0) {
|
|
175
191
|
options.onlyTypes = true;
|
|
176
192
|
}
|
|
177
193
|
// Treat forceLong=true as LONG
|
|
@@ -188,11 +204,11 @@ function optionsFromParameter(parameter) {
|
|
|
188
204
|
}
|
|
189
205
|
// Assume the user wants the default service output, unless they're using nestJs, which has
|
|
190
206
|
// its own controllers output (although nestjs users can ask for other services too).
|
|
191
|
-
if (options.outputServices.length == 0 &&
|
|
207
|
+
if (options.outputServices.length == 0 && options.nestJs.length === 0) {
|
|
192
208
|
options.outputServices = [ServiceOption.DEFAULT];
|
|
193
209
|
}
|
|
194
210
|
// If using nestJs + other services, add the encode methods back
|
|
195
|
-
if (options.nestJs && options.outputServices.length > 0) {
|
|
211
|
+
if (options.nestJs.length > 0 && options.outputServices.length > 0) {
|
|
196
212
|
options.outputEncodeMethods = true;
|
|
197
213
|
}
|
|
198
214
|
// Handle outputSchema=true
|
|
@@ -241,7 +257,7 @@ function optionsFromParameter(parameter) {
|
|
|
241
257
|
options.useDate = DateOption.STRING;
|
|
242
258
|
}
|
|
243
259
|
}
|
|
244
|
-
if (options.nestJs) {
|
|
260
|
+
if (options.nestJs.length > 0) {
|
|
245
261
|
options.initializeFieldsAsUndefined = false;
|
|
246
262
|
}
|
|
247
263
|
else {
|
|
@@ -262,6 +278,14 @@ function optionsFromParameter(parameter) {
|
|
|
262
278
|
// Make sure to cast number options to an actual number
|
|
263
279
|
options.unrecognizedEnumValue = Number(options.unrecognizedEnumValue);
|
|
264
280
|
}
|
|
281
|
+
if (options.outputStandaloneFunctions &&
|
|
282
|
+
(options.outputTypeRegistry ||
|
|
283
|
+
options.outputTypeAnnotations === "static-only" ||
|
|
284
|
+
options.outputServices.includes(ServiceOption.GENERIC) ||
|
|
285
|
+
options.nestJs.length > 0 ||
|
|
286
|
+
options.useMongoObjectId)) {
|
|
287
|
+
throw new Error("outputStandaloneFunctions=true can't be used with outputTypeRegistry=true, outputTypeAnnotations=static-only, outputServices=generic-definitions, nestJs=true, or useMongoObjectId=true");
|
|
288
|
+
}
|
|
265
289
|
return options;
|
|
266
290
|
}
|
|
267
291
|
// A very naive parse function, eventually could/should use iots/runtypes
|
package/build/src/schema.js
CHANGED
|
@@ -61,7 +61,7 @@ function generateSchema(ctx, fileDesc, sourceInfo) {
|
|
|
61
61
|
references.push((0, ts_poet_1.code) `'.${(0, utils_1.maybePrefixPackage)(fileDesc, localName.replace(/_/g, "."))}': ${symbol}`);
|
|
62
62
|
}
|
|
63
63
|
(0, visit_1.visit)(fileDesc, sourceInfo, (fullName) => {
|
|
64
|
-
if (options.outputEncodeMethods) {
|
|
64
|
+
if (options.outputEncodeMethods && !options.outputStandaloneFunctions) {
|
|
65
65
|
addReference(fullName, fullName);
|
|
66
66
|
}
|
|
67
67
|
}, options, (fullName) => {
|
|
@@ -147,7 +147,7 @@ function generateSchema(ctx, fileDesc, sourceInfo) {
|
|
|
147
147
|
}
|
|
148
148
|
function getExtensionValue(ctx, extension, data) {
|
|
149
149
|
if (extension.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_MESSAGE) {
|
|
150
|
-
const
|
|
150
|
+
const decode = (0, types_1.getMessageMethod)(ctx, extension.typeName, "decode");
|
|
151
151
|
const resultBuffer = Buffer.concat(data.map((d) => {
|
|
152
152
|
// Skip length byte
|
|
153
153
|
const bytes = new wire_1.BinaryReader(d).bytes();
|
|
@@ -157,7 +157,7 @@ function getExtensionValue(ctx, extension, data) {
|
|
|
157
157
|
const encoded = ctx.options.env === options_1.EnvOption.NODE
|
|
158
158
|
? (0, ts_poet_1.code) `Buffer.from('${result}', 'base64')`
|
|
159
159
|
: (0, ts_poet_1.code) `${ctx.utils.bytesFromBase64}("${result}")`;
|
|
160
|
-
return (0, ts_poet_1.code) `'${extension.name}': ${
|
|
160
|
+
return (0, ts_poet_1.code) `'${extension.name}': ${decode}(${encoded})`;
|
|
161
161
|
}
|
|
162
162
|
else {
|
|
163
163
|
const reader = new wire_1.BinaryReader(data[0]);
|
package/build/src/types.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export declare function messageToTypeName(ctx: Context, protoType: string, typeO
|
|
|
59
59
|
repeated?: boolean;
|
|
60
60
|
}): Code;
|
|
61
61
|
export declare function getEnumMethod(ctx: Context, enumProtoType: string, methodSuffix: string): Import;
|
|
62
|
+
export declare function getMessageMethod(ctx: Context, messageProtoType: string, method: string): Code;
|
|
62
63
|
/** Return the TypeName for any field (primitive/message/etc.) as exposed in the interface. */
|
|
63
64
|
export declare function toTypeName(ctx: Context, messageDesc: DescriptorProto | undefined, field: FieldDescriptorProto, ensureOptional?: boolean): Code;
|
|
64
65
|
/**
|
package/build/src/types.js
CHANGED
|
@@ -41,6 +41,7 @@ exports.valueTypeName = valueTypeName;
|
|
|
41
41
|
exports.wrapperTypeName = wrapperTypeName;
|
|
42
42
|
exports.messageToTypeName = messageToTypeName;
|
|
43
43
|
exports.getEnumMethod = getEnumMethod;
|
|
44
|
+
exports.getMessageMethod = getMessageMethod;
|
|
44
45
|
exports.toTypeName = toTypeName;
|
|
45
46
|
exports.shouldGenerateJSMapType = shouldGenerateJSMapType;
|
|
46
47
|
exports.detectMapType = detectMapType;
|
|
@@ -645,8 +646,8 @@ function messageToTypeName(ctx, protoType, typeOptions = {}) {
|
|
|
645
646
|
if (!typeOptions.keepValueType && options.useMongoObjectId && protoType.endsWith(".ObjectId")) {
|
|
646
647
|
return (0, ts_poet_1.code) `mongodb.ObjectId`;
|
|
647
648
|
}
|
|
648
|
-
const [module, type] = toModuleAndType(typeMap, protoType);
|
|
649
|
-
return (0, ts_poet_1.code) `${(0, utils_1.impProto)(options, module, type)}`;
|
|
649
|
+
const [module, type, descriptor] = toModuleAndType(typeMap, protoType);
|
|
650
|
+
return (0, ts_poet_1.code) `${(0, utils_1.impProto)(options, module, type, options.outputStandaloneFunctions && "field" in descriptor)}`;
|
|
650
651
|
}
|
|
651
652
|
/** Breaks `.some_proto_namespace.Some.Message` into `['some_proto_namespace', 'Some_Message', Descriptor]. */
|
|
652
653
|
function toModuleAndType(typeMap, protoType) {
|
|
@@ -656,6 +657,10 @@ function getEnumMethod(ctx, enumProtoType, methodSuffix) {
|
|
|
656
657
|
const [module, type] = toModuleAndType(ctx.typeMap, enumProtoType);
|
|
657
658
|
return (0, utils_1.impProto)(ctx.options, module, `${(0, case_1.uncapitalize)(type)}${methodSuffix}`);
|
|
658
659
|
}
|
|
660
|
+
function getMessageMethod(ctx, messageProtoType, method) {
|
|
661
|
+
const [module, type] = toModuleAndType(ctx.typeMap, messageProtoType);
|
|
662
|
+
return (0, utils_1.impProtoMethod)(ctx.options, module, type, method);
|
|
663
|
+
}
|
|
659
664
|
/** Return the TypeName for any field (primitive/message/etc.) as exposed in the interface. */
|
|
660
665
|
function toTypeName(ctx, messageDesc, field, ensureOptional = false) {
|
|
661
666
|
function finalize(type, isOptional) {
|
package/build/src/utils.d.ts
CHANGED
|
@@ -65,7 +65,11 @@ export declare function safeAccessor(propertyName: string): string;
|
|
|
65
65
|
*/
|
|
66
66
|
export declare function getPropertyAccessor(objectName: string, propertyName: string, optional?: boolean): string;
|
|
67
67
|
export declare function impFile(options: Options, spec: string): Import;
|
|
68
|
-
export declare function impProto(options: Options, module: string, type: string): Import;
|
|
68
|
+
export declare function impProto(options: Options, module: string, type: string, typeOnly?: boolean): Import;
|
|
69
|
+
export declare function messageFunctionName(type: string, method: string): string;
|
|
70
|
+
export declare function impProtoMethod(options: Options, module: string, type: string, method: string): Code;
|
|
71
|
+
export declare function localMessageMethod(options: Options, type: string, method: string): string;
|
|
72
|
+
export declare function messageMethodHead(options: Options, type: string, method: string, isAsyncGenerator?: boolean): Code;
|
|
69
73
|
export declare function tryCatchBlock(tryBlock: Code | string, handleErrorBlock: Code | string): Code;
|
|
70
74
|
export declare function arrowFunction(params: string, body: Code | string, isOneLine?: boolean): Code;
|
|
71
75
|
export declare function nullOrUndefined(options: Pick<Options, "useNullAsOptional">, hasProto3Optional?: boolean): string;
|
package/build/src/utils.js
CHANGED
|
@@ -17,6 +17,10 @@ exports.safeAccessor = safeAccessor;
|
|
|
17
17
|
exports.getPropertyAccessor = getPropertyAccessor;
|
|
18
18
|
exports.impFile = impFile;
|
|
19
19
|
exports.impProto = impProto;
|
|
20
|
+
exports.messageFunctionName = messageFunctionName;
|
|
21
|
+
exports.impProtoMethod = impProtoMethod;
|
|
22
|
+
exports.localMessageMethod = localMessageMethod;
|
|
23
|
+
exports.messageMethodHead = messageMethodHead;
|
|
20
24
|
exports.tryCatchBlock = tryCatchBlock;
|
|
21
25
|
exports.arrowFunction = arrowFunction;
|
|
22
26
|
exports.nullOrUndefined = nullOrUndefined;
|
|
@@ -243,14 +247,32 @@ function getPropertyAccessor(objectName, propertyName, optional = false) {
|
|
|
243
247
|
function impFile(options, spec) {
|
|
244
248
|
return (0, ts_poet_1.imp)(`${spec}${options.importSuffix}`);
|
|
245
249
|
}
|
|
246
|
-
function impProto(options, module, type) {
|
|
247
|
-
const prefix = options.onlyTypes ? "t:" : "";
|
|
250
|
+
function impProto(options, module, type, typeOnly = false) {
|
|
251
|
+
const prefix = options.onlyTypes || typeOnly ? "t:" : "";
|
|
248
252
|
const protoFile = `${module}.proto`;
|
|
249
253
|
if (options.M[protoFile]) {
|
|
250
254
|
return (0, ts_poet_1.imp)(`${prefix}${type}@${options.M[protoFile]}`);
|
|
251
255
|
}
|
|
252
256
|
return (0, ts_poet_1.imp)(`${prefix}${type}@./${module}${options.fileSuffix}${options.importSuffix}`);
|
|
253
257
|
}
|
|
258
|
+
function messageFunctionName(type, method) {
|
|
259
|
+
return (0, case_1.uncapitalize)(type) + (0, case_1.capitalize)(method);
|
|
260
|
+
}
|
|
261
|
+
function impProtoMethod(options, module, type, method) {
|
|
262
|
+
if (options.outputStandaloneFunctions) {
|
|
263
|
+
return (0, ts_poet_1.code) `${impProto(options, module, messageFunctionName(type, method))}`;
|
|
264
|
+
}
|
|
265
|
+
return (0, ts_poet_1.code) `${impProto(options, module, type)}.${method}`;
|
|
266
|
+
}
|
|
267
|
+
function localMessageMethod(options, type, method) {
|
|
268
|
+
return options.outputStandaloneFunctions ? messageFunctionName(type, method) : `${type}.${method}`;
|
|
269
|
+
}
|
|
270
|
+
function messageMethodHead(options, type, method, isAsyncGenerator = false) {
|
|
271
|
+
if (options.outputStandaloneFunctions) {
|
|
272
|
+
return (0, ts_poet_1.code) `export ${isAsyncGenerator ? "async function*" : "function"} ${(0, ts_poet_1.def)(messageFunctionName(type, method))}`;
|
|
273
|
+
}
|
|
274
|
+
return (0, ts_poet_1.code) `${isAsyncGenerator ? "async *" : ""}${method}`;
|
|
275
|
+
}
|
|
254
276
|
function tryCatchBlock(tryBlock, handleErrorBlock) {
|
|
255
277
|
return (0, ts_poet_1.code) `try {
|
|
256
278
|
${tryBlock}
|