ts-proto 2.18.5 → 2.19.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 +7 -1
- 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/generate-type-registry.js +15 -4
- package/build/src/main.js +85 -78
- package/build/src/options.d.ts +1 -0
- package/build/src/options.js +9 -0
- 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.
|
|
@@ -493,7 +499,7 @@ With `--ts_proto_opt=protoJsonFormat=false`, strict proto3 compliance is disable
|
|
|
493
499
|
|
|
494
500
|
- With `--ts_proto_opt=outputTypeAnnotations=true`, each message will be given a `$type` field containing its fully-qualified name. You can use `--ts_proto_opt=outputTypeAnnotations=static-only` to omit it from the `interface` declaration, or `--ts_proto_opt=outputTypeAnnotations=optional` to make it an optional property on the `interface` definition. The latter option may be useful if you want to use the `$type` field for runtime type checking on responses from a server.
|
|
495
501
|
|
|
496
|
-
- With `--ts_proto_opt=outputTypeRegistry=true`, the type registry will be generated that can be used to resolve message types by fully-qualified name. Also, each message will be given a `$type` field containing its fully-qualified name.
|
|
502
|
+
- With `--ts_proto_opt=outputTypeRegistry=true`, the type registry will be generated that can be used to resolve message types by fully-qualified name. Also, each message will be given a `$type` field containing its fully-qualified name. The registry's `MessageType` only declares the methods that are generated, so it also works with options like `outputEncodeMethods=encode-only` or `outputJsonMethods=to-only`.
|
|
497
503
|
|
|
498
504
|
- With `--ts_proto_opt=outputServices=grpc-js`, ts-proto will output service definitions and server / client stubs in [grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) format.
|
|
499
505
|
|
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
|
}
|
|
@@ -33,14 +33,25 @@ function generateMessageType(ctx) {
|
|
|
33
33
|
else {
|
|
34
34
|
chunks.push((0, ts_poet_1.code) `$type: string;`);
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
// Only declare the methods that are actually generated on each message, e.g. with
|
|
37
|
+
// `outputJsonMethods=to-only` the messages have no `fromJSON` to register.
|
|
38
|
+
const { outputEncodeMethods, outputJsonMethods } = ctx.options;
|
|
39
|
+
const hasEncode = outputEncodeMethods === true ||
|
|
40
|
+
outputEncodeMethods === "encode-only" ||
|
|
41
|
+
outputEncodeMethods === "encode-no-creation";
|
|
42
|
+
const hasDecode = outputEncodeMethods === true || outputEncodeMethods === "decode-only";
|
|
43
|
+
const BinaryReader = (0, ts_poet_1.imp)("t:BinaryReader@@bufbuild/protobuf/wire");
|
|
44
|
+
const BinaryWriter = (0, ts_poet_1.imp)("t:BinaryWriter@@bufbuild/protobuf/wire");
|
|
45
|
+
if (hasEncode) {
|
|
39
46
|
chunks.push((0, ts_poet_1.code) `encode(message: Message, writer?: ${BinaryWriter}): ${BinaryWriter};`);
|
|
47
|
+
}
|
|
48
|
+
if (hasDecode) {
|
|
40
49
|
chunks.push((0, ts_poet_1.code) `decode(input: ${BinaryReader} | Uint8Array, length?: number): Message;`);
|
|
41
50
|
}
|
|
42
|
-
if (
|
|
51
|
+
if (outputJsonMethods === true || outputJsonMethods === "from-only") {
|
|
43
52
|
chunks.push((0, ts_poet_1.code) `fromJSON(object: any): Message;`);
|
|
53
|
+
}
|
|
54
|
+
if (outputJsonMethods === true || outputJsonMethods === "to-only") {
|
|
44
55
|
chunks.push((0, ts_poet_1.code) `toJSON(message: Message): unknown;`);
|
|
45
56
|
}
|
|
46
57
|
if (ctx.options.outputPartialMethods) {
|
package/build/src/main.js
CHANGED
|
@@ -103,13 +103,18 @@ function generateFile(ctx, fileDesc) {
|
|
|
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") {
|
|
@@ -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(", ");
|
|
@@ -694,7 +702,7 @@ function makeObjectIdMethods() {
|
|
|
694
702
|
return { fromJsonObjectId, fromProtoObjectId, toProtoObjectId };
|
|
695
703
|
}
|
|
696
704
|
function makeTimestampMethods(options, longs, bytes) {
|
|
697
|
-
const Timestamp = (0, utils_1.impProto)(options, "google/protobuf/timestamp", (0, utils_1.wrapTypeName)(options, "Timestamp"));
|
|
705
|
+
const Timestamp = (0, utils_1.impProto)(options, "google/protobuf/timestamp", (0, utils_1.wrapTypeName)(options, "Timestamp"), options.outputStandaloneFunctions);
|
|
698
706
|
const NanoDate = (0, ts_poet_1.imp)("NanoDate=nano-date");
|
|
699
707
|
let seconds = "Math.trunc(date.getTime() / 1_000)";
|
|
700
708
|
let toNumberCode = "t.seconds";
|
|
@@ -800,6 +808,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
800
808
|
`);
|
|
801
809
|
// Declared once per file, so the regex isn't compiled on each fromJsonTimestamp call
|
|
802
810
|
const timestampFractionRegex = (0, ts_poet_1.conditionalOutput)("timestampFractionRegex", (0, ts_poet_1.code) `const timestampFractionRegex = /:\\d{2}\\.\\d+/;`);
|
|
811
|
+
const timestampMessageFromJson = (0, utils_1.impProtoMethod)(options, "google/protobuf/timestamp", (0, utils_1.wrapTypeName)(options, "Timestamp"), "fromJSON");
|
|
803
812
|
const fromJsonTimestamp = (0, ts_poet_1.conditionalOutput)("fromJsonTimestamp", options.useDate === options_1.DateOption.DATE
|
|
804
813
|
? (0, ts_poet_1.code) `
|
|
805
814
|
function fromJsonTimestamp(o: any): Date {
|
|
@@ -808,7 +817,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
808
817
|
} else if (typeof o === "string") {
|
|
809
818
|
return new ${bytes.globalThis}.Date(o);
|
|
810
819
|
} else {
|
|
811
|
-
return ${fromTimestamp}(${
|
|
820
|
+
return ${fromTimestamp}(${timestampMessageFromJson}(o));
|
|
812
821
|
}
|
|
813
822
|
}
|
|
814
823
|
`
|
|
@@ -820,7 +829,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
820
829
|
} else if (typeof o === "string") {
|
|
821
830
|
return ${bytes.globalThis}.Temporal.Instant.from(o);
|
|
822
831
|
} else {
|
|
823
|
-
return ${fromTimestamp}(${
|
|
832
|
+
return ${fromTimestamp}(${timestampMessageFromJson}(o));
|
|
824
833
|
}
|
|
825
834
|
}
|
|
826
835
|
`
|
|
@@ -842,7 +851,7 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
842
851
|
);
|
|
843
852
|
return { ...timestamp, nanos: (timestamp.nanos ?? 0) + (fractionNanos % 1_000_000) };
|
|
844
853
|
} else {
|
|
845
|
-
return ${
|
|
854
|
+
return ${timestampMessageFromJson}(o);
|
|
846
855
|
}
|
|
847
856
|
}
|
|
848
857
|
`);
|
|
@@ -1123,14 +1132,13 @@ function getDecodeReadSnippet(ctx, field) {
|
|
|
1123
1132
|
}
|
|
1124
1133
|
}
|
|
1125
1134
|
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
1126
|
-
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
1127
1135
|
const unwrap = (decodedValue) => {
|
|
1128
1136
|
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) `${
|
|
1137
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "unwrap")}(${decodedValue})`;
|
|
1130
1138
|
}
|
|
1131
1139
|
return (0, ts_poet_1.code) `${decodedValue}.value`;
|
|
1132
1140
|
};
|
|
1133
|
-
const decoder = (0, ts_poet_1.code) `${
|
|
1141
|
+
const decoder = (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "decode")}(reader, reader.uint32())`;
|
|
1134
1142
|
readSnippet = (0, ts_poet_1.code) `${unwrap(decoder)}`;
|
|
1135
1143
|
}
|
|
1136
1144
|
else if ((0, types_1.isTimestamp)(field) &&
|
|
@@ -1138,20 +1146,20 @@ function getDecodeReadSnippet(ctx, field) {
|
|
|
1138
1146
|
options.useDate === options_1.DateOption.STRING ||
|
|
1139
1147
|
options.useDate === options_1.DateOption.STRING_NANO ||
|
|
1140
1148
|
options.useDate === options_1.DateOption.TEMPORAL)) {
|
|
1141
|
-
const
|
|
1142
|
-
readSnippet = (0, ts_poet_1.code) `${utils.fromTimestamp}(${
|
|
1149
|
+
const decode = (0, types_1.getMessageMethod)(ctx, field.typeName, "decode");
|
|
1150
|
+
readSnippet = (0, ts_poet_1.code) `${utils.fromTimestamp}(${decode}(reader, reader.uint32()))`;
|
|
1143
1151
|
}
|
|
1144
1152
|
else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
|
|
1145
1153
|
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
1146
1154
|
readSnippet = (0, ts_poet_1.code) `${utils.fromProtoObjectId}(${type}.decode(reader, reader.uint32()))`;
|
|
1147
1155
|
}
|
|
1148
1156
|
else if ((0, types_1.isMessage)(field)) {
|
|
1149
|
-
const
|
|
1157
|
+
const decode = (0, types_1.getMessageMethod)(ctx, field.typeName, "decode");
|
|
1150
1158
|
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP) {
|
|
1151
|
-
readSnippet = (0, ts_poet_1.code) `${
|
|
1159
|
+
readSnippet = (0, ts_poet_1.code) `${decode}(reader)`;
|
|
1152
1160
|
}
|
|
1153
1161
|
else {
|
|
1154
|
-
readSnippet = (0, ts_poet_1.code) `${
|
|
1162
|
+
readSnippet = (0, ts_poet_1.code) `${decode}(reader, reader.uint32())`;
|
|
1155
1163
|
}
|
|
1156
1164
|
}
|
|
1157
1165
|
else {
|
|
@@ -1159,10 +1167,10 @@ function getDecodeReadSnippet(ctx, field) {
|
|
|
1159
1167
|
}
|
|
1160
1168
|
return readSnippet;
|
|
1161
1169
|
}
|
|
1162
|
-
function generateEmptyDecode(fullName) {
|
|
1170
|
+
function generateEmptyDecode(ctx, fullName) {
|
|
1163
1171
|
const BinaryReader = (0, ts_poet_1.imp)("t:BinaryReader@@bufbuild/protobuf/wire");
|
|
1164
1172
|
return (0, ts_poet_1.code) `
|
|
1165
|
-
decode(
|
|
1173
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "decode")}(
|
|
1166
1174
|
_: ${BinaryReader} | Uint8Array,
|
|
1167
1175
|
length?: number,
|
|
1168
1176
|
): ${fullName} {
|
|
@@ -1181,7 +1189,7 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
1181
1189
|
const BinaryReader = (0, ts_poet_1.imp)("BinaryReader@@bufbuild/protobuf/wire");
|
|
1182
1190
|
// create the basic function declaration
|
|
1183
1191
|
chunks.push((0, ts_poet_1.code) `
|
|
1184
|
-
decode(
|
|
1192
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "decode")}(
|
|
1185
1193
|
input: ${BinaryReader} | Uint8Array,
|
|
1186
1194
|
length?: number,
|
|
1187
1195
|
): ${fullName} {
|
|
@@ -1411,38 +1419,38 @@ function getEncodeWriteSnippet(ctx, field) {
|
|
|
1411
1419
|
options.useDate === options_1.DateOption.STRING_NANO ||
|
|
1412
1420
|
options.useDate === options_1.DateOption.TEMPORAL)) {
|
|
1413
1421
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
1414
|
-
const
|
|
1415
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1422
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1423
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${utils.toTimestamp}(${place}), writer.uint32(${tag}).fork()).join()`;
|
|
1416
1424
|
}
|
|
1417
1425
|
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
1418
1426
|
const maybeTypeField = (0, options_1.addTypeToMessages)(options) ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
1419
|
-
const
|
|
1427
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1420
1428
|
const wrappedValue = (place) => {
|
|
1421
1429
|
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) `${
|
|
1430
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "wrap")}(${place})`;
|
|
1423
1431
|
}
|
|
1424
1432
|
return (0, ts_poet_1.code) `{${maybeTypeField} value: ${place}!}`;
|
|
1425
1433
|
};
|
|
1426
1434
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
1427
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1435
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${wrappedValue(place)}, writer.uint32(${tag}).fork()).join()`;
|
|
1428
1436
|
}
|
|
1429
1437
|
else if ((0, types_1.isMessage)(field)) {
|
|
1430
|
-
const
|
|
1438
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1431
1439
|
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP) {
|
|
1432
1440
|
const startTag = ((field.number << 3) | 3) >>> 0, endTag = ((field.number << 3) | 4) >>> 0;
|
|
1433
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1441
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${place}, writer.uint32(${startTag})).uint32(${endTag})`;
|
|
1434
1442
|
}
|
|
1435
1443
|
const tag = ((field.number << 3) | 2) >>> 0;
|
|
1436
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1444
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${place}, writer.uint32(${tag}).fork()).join()`;
|
|
1437
1445
|
}
|
|
1438
1446
|
else {
|
|
1439
1447
|
throw new Error(`Unhandled field ${field}`);
|
|
1440
1448
|
}
|
|
1441
1449
|
}
|
|
1442
|
-
function generateEmptyEncode(fullName) {
|
|
1450
|
+
function generateEmptyEncode(ctx, fullName) {
|
|
1443
1451
|
const BinaryWriter = (0, ts_poet_1.imp)("BinaryWriter@@bufbuild/protobuf/wire");
|
|
1444
1452
|
return (0, ts_poet_1.code) `
|
|
1445
|
-
encode(
|
|
1453
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "encode")}(
|
|
1446
1454
|
_: ${fullName},
|
|
1447
1455
|
writer: ${BinaryWriter} = new ${BinaryWriter}(),
|
|
1448
1456
|
): ${BinaryWriter} {
|
|
@@ -1457,7 +1465,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1457
1465
|
const BinaryWriter = (0, ts_poet_1.imp)("BinaryWriter@@bufbuild/protobuf/wire");
|
|
1458
1466
|
// create the basic function declaration
|
|
1459
1467
|
chunks.push((0, ts_poet_1.code) `
|
|
1460
|
-
encode(
|
|
1468
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "encode")}(
|
|
1461
1469
|
${messageDesc.field.length > 0 || options.unknownFields ? "message" : "_"}: ${fullName},
|
|
1462
1470
|
writer: ${BinaryWriter} = new ${BinaryWriter}(),
|
|
1463
1471
|
): ${BinaryWriter} {
|
|
@@ -1673,7 +1681,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1673
1681
|
}
|
|
1674
1682
|
function generateSetExtension(ctx, fullName) {
|
|
1675
1683
|
return (0, ts_poet_1.code) `
|
|
1676
|
-
setExtension <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>, value: T): void {
|
|
1684
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "setExtension")} <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>, value: T): void {
|
|
1677
1685
|
const encoded = extension.encode!(value);
|
|
1678
1686
|
|
|
1679
1687
|
if (message._unknownFields !== undefined) {
|
|
@@ -1699,7 +1707,7 @@ function generateSetExtension(ctx, fullName) {
|
|
|
1699
1707
|
}
|
|
1700
1708
|
function generateGetExtension(ctx, fullName) {
|
|
1701
1709
|
return (0, ts_poet_1.code) `
|
|
1702
|
-
getExtension <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>): T | undefined {
|
|
1710
|
+
${(0, utils_1.messageMethodHead)(ctx.options, fullName, "getExtension")} <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>): T | undefined {
|
|
1703
1711
|
let results: T | undefined = undefined;
|
|
1704
1712
|
|
|
1705
1713
|
if (message._unknownFields === undefined) {
|
|
@@ -1787,27 +1795,27 @@ function generateExtension(ctx, message, extension) {
|
|
|
1787
1795
|
options.useDate === options_1.DateOption.STRING ||
|
|
1788
1796
|
options.useDate === options_1.DateOption.STRING_NANO ||
|
|
1789
1797
|
options.useDate === options_1.DateOption.TEMPORAL)) {
|
|
1790
|
-
const
|
|
1791
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1798
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1799
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${utils.toTimestamp}(${place}), writer.fork()).join()`;
|
|
1792
1800
|
}
|
|
1793
1801
|
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
1794
1802
|
const maybeTypeField = (0, options_1.addTypeToMessages)(options) ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
1795
|
-
const
|
|
1803
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1796
1804
|
const wrappedValue = (place) => {
|
|
1797
1805
|
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) `${
|
|
1806
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "wrap")}(${place})`;
|
|
1799
1807
|
}
|
|
1800
1808
|
return (0, ts_poet_1.code) `{${maybeTypeField} value: ${place}!}`;
|
|
1801
1809
|
};
|
|
1802
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1810
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${wrappedValue(place)}, writer.fork()).join()`;
|
|
1803
1811
|
}
|
|
1804
1812
|
else if ((0, types_1.isMessage)(field)) {
|
|
1805
|
-
const
|
|
1813
|
+
const encode = (0, types_1.getMessageMethod)(ctx, field.typeName, "encode");
|
|
1806
1814
|
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP) {
|
|
1807
1815
|
const endTag = ((field.number << 3) | 4) >>> 0;
|
|
1808
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1816
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${place}, writer).uint32(${endTag})`;
|
|
1809
1817
|
}
|
|
1810
|
-
return (place) => (0, ts_poet_1.code) `${
|
|
1818
|
+
return (place) => (0, ts_poet_1.code) `${encode}(${place}, writer.fork()).join()`;
|
|
1811
1819
|
}
|
|
1812
1820
|
else {
|
|
1813
1821
|
throw new Error(`Unhandled field ${field}`);
|
|
@@ -1962,7 +1970,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1962
1970
|
break;
|
|
1963
1971
|
}
|
|
1964
1972
|
return (0, ts_poet_1.code) `
|
|
1965
|
-
fromJSON(object: string): ${fullName} {
|
|
1973
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromJSON")}(object: string): ${fullName} {
|
|
1966
1974
|
if (!object.endsWith("s")) throw new Error("Invalid duration string");
|
|
1967
1975
|
const body = object.slice(0, -1);
|
|
1968
1976
|
const negative = body.startsWith("-");
|
|
@@ -1982,21 +1990,21 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1982
1990
|
if (fullTypeName === "google.protobuf.Timestamp") {
|
|
1983
1991
|
// The canonical JSON of a Timestamp is an RFC 3339 string; the object form is still accepted.
|
|
1984
1992
|
chunks.push((0, ts_poet_1.code) `
|
|
1985
|
-
fromJSON(object: any): ${fullName} {
|
|
1993
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromJSON")}(object: any): ${fullName} {
|
|
1986
1994
|
if (typeof object === "string") {
|
|
1987
|
-
return ${fullName}
|
|
1995
|
+
return ${(0, utils_1.localMessageMethod)(options, fullName, "fromJSON")}(${utils.timestampFromJson}(object));
|
|
1988
1996
|
}
|
|
1989
1997
|
return {
|
|
1990
1998
|
`);
|
|
1991
1999
|
}
|
|
1992
2000
|
else {
|
|
1993
2001
|
chunks.push((0, ts_poet_1.code) `
|
|
1994
|
-
fromJSON(${messageDesc.field.length > 0 ? "object" : "_"}: any): ${fullName} {
|
|
2002
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromJSON")}(${messageDesc.field.length > 0 ? "object" : "_"}: any): ${fullName} {
|
|
1995
2003
|
return {
|
|
1996
2004
|
`);
|
|
1997
2005
|
}
|
|
1998
2006
|
if ((0, options_1.addTypeToMessages)(options)) {
|
|
1999
|
-
chunks.push((0, ts_poet_1.code) `$type: ${fullName}.$type,`);
|
|
2007
|
+
chunks.push(options.outputStandaloneFunctions ? (0, ts_poet_1.code) `$type: '${fullTypeName}',` : (0, ts_poet_1.code) `$type: ${fullName}.$type,`);
|
|
2000
2008
|
}
|
|
2001
2009
|
const oneofFieldsCases = messageDesc.oneofDecl.map((oneof, oneofIndex) => messageDesc.field.filter(types_1.isWithinOneOf).filter((field) => field.oneofIndex === oneofIndex));
|
|
2002
2010
|
const canonicalFromJson = {
|
|
@@ -2065,8 +2073,9 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2065
2073
|
return (0, ts_poet_1.code) `${from}`;
|
|
2066
2074
|
}
|
|
2067
2075
|
else if ((0, types_1.isFieldMaskType)(field)) {
|
|
2068
|
-
const
|
|
2069
|
-
|
|
2076
|
+
const unwrap = (0, types_1.getMessageMethod)(ctx, field.typeName, "unwrap");
|
|
2077
|
+
const fromJson = (0, types_1.getMessageMethod)(ctx, field.typeName, "fromJSON");
|
|
2078
|
+
return (0, ts_poet_1.code) `${unwrap}(${fromJson}(${from}))`;
|
|
2070
2079
|
}
|
|
2071
2080
|
else if ((0, types_1.isListValueType)(field)) {
|
|
2072
2081
|
return (0, ts_poet_1.code) `[...${from}]`;
|
|
@@ -2125,12 +2134,11 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2125
2134
|
return (0, ts_poet_1.code) `${from}`;
|
|
2126
2135
|
}
|
|
2127
2136
|
else {
|
|
2128
|
-
return (0, ts_poet_1.code) `${
|
|
2137
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, valueField.typeName, "fromJSON")}(${from})`;
|
|
2129
2138
|
}
|
|
2130
2139
|
}
|
|
2131
2140
|
else {
|
|
2132
|
-
|
|
2133
|
-
return (0, ts_poet_1.code) `${type}.fromJSON(${from})`;
|
|
2141
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "fromJSON")}(${from})`;
|
|
2134
2142
|
}
|
|
2135
2143
|
}
|
|
2136
2144
|
else {
|
|
@@ -2300,12 +2308,13 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
2300
2308
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
2301
2309
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
2302
2310
|
}
|
|
2303
|
-
function generateCanonicalToJson(fullName, fullProtobufTypeName,
|
|
2311
|
+
function generateCanonicalToJson(fullName, fullProtobufTypeName, options, utils) {
|
|
2312
|
+
const { useOptionals, useNullAsOptional, useDuration, useJsonTimestamp, forceLong } = options;
|
|
2304
2313
|
if ((0, types_1.isFieldMaskTypeName)(fullProtobufTypeName)) {
|
|
2305
2314
|
const returnType = useOptionals === "all" ? `string | ${(0, utils_1.nullOrUndefined)({ useNullAsOptional })}` : "string";
|
|
2306
2315
|
const pathModifier = useOptionals === "all" ? "?" : "";
|
|
2307
2316
|
return (0, ts_poet_1.code) `
|
|
2308
|
-
toJSON(message: ${fullName}): ${returnType} {
|
|
2317
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(message: ${fullName}): ${returnType} {
|
|
2309
2318
|
return message.paths${pathModifier}.join(',');
|
|
2310
2319
|
}
|
|
2311
2320
|
`;
|
|
@@ -2334,7 +2343,7 @@ function generateCanonicalToJson(fullName, fullProtobufTypeName, { useOptionals,
|
|
|
2334
2343
|
break;
|
|
2335
2344
|
}
|
|
2336
2345
|
return (0, ts_poet_1.code) `
|
|
2337
|
-
toJSON(message: ${fullName}): string {
|
|
2346
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(message: ${fullName}): string {
|
|
2338
2347
|
const negative = ${isNegSeconds} || message.nanos < 0;
|
|
2339
2348
|
const sign = negative ? "-" : "";
|
|
2340
2349
|
const absSeconds = ${absSeconds};
|
|
@@ -2351,7 +2360,7 @@ function generateCanonicalToJson(fullName, fullProtobufTypeName, { useOptionals,
|
|
|
2351
2360
|
? (0, ts_poet_1.code) `message.seconds?.toNumber() ?? 0`
|
|
2352
2361
|
: (0, ts_poet_1.code) `${utils.globalThis}.Number(message.seconds ?? 0)`;
|
|
2353
2362
|
return (0, ts_poet_1.code) `
|
|
2354
|
-
toJSON(message: ${fullName}): string {
|
|
2363
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(message: ${fullName}): string {
|
|
2355
2364
|
return ${utils.timestampToJson}(${seconds}, message.nanos ?? 0);
|
|
2356
2365
|
}
|
|
2357
2366
|
`;
|
|
@@ -2381,7 +2390,7 @@ function generateCanonicalAnyToJson(ctx, fullName, messageDesc) {
|
|
|
2381
2390
|
const typeUrl = (0, utils_1.getPropertyAccessor)("message", (0, utils_1.getFieldName)(typeUrlField, options));
|
|
2382
2391
|
const value = (0, utils_1.getPropertyAccessor)("message", (0, utils_1.getFieldName)(valueField, options));
|
|
2383
2392
|
return (0, ts_poet_1.code) `
|
|
2384
|
-
toJSON(message: ${fullName}): unknown {
|
|
2393
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(message: ${fullName}): unknown {
|
|
2385
2394
|
const typeUrl = ${typeUrl} ?? "";
|
|
2386
2395
|
if (typeUrl === "") {
|
|
2387
2396
|
return {};
|
|
@@ -2408,7 +2417,7 @@ function generateCanonicalAnyFromJson(ctx, fullName, messageDesc) {
|
|
|
2408
2417
|
const typeField = (0, options_1.addTypeToMessages)(options) ? (0, ts_poet_1.code) `$type: ${fullName}.$type,` : "";
|
|
2409
2418
|
const bytes = options.env === options_1.EnvOption.NODE ? (0, ts_poet_1.code) `Buffer.from(bytes)` : (0, ts_poet_1.code) `bytes`;
|
|
2410
2419
|
return (0, ts_poet_1.code) `
|
|
2411
|
-
fromJSON(object: any): ${fullName} {
|
|
2420
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromJSON")}(object: any): ${fullName} {
|
|
2412
2421
|
const typeUrl = ${utils.isSet}(object?.["@type"]) ? ${utils.globalThis}.String(object["@type"]) : "";
|
|
2413
2422
|
if (typeUrl === "") {
|
|
2414
2423
|
return { ${typeField} ${typeUrlKey}: ${(0, types_1.defaultValue)(ctx, typeUrlField)}, ${valueKey}: ${(0, types_1.defaultValue)(ctx, valueField)} };
|
|
@@ -2442,7 +2451,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2442
2451
|
}
|
|
2443
2452
|
// create the basic function declaration
|
|
2444
2453
|
chunks.push((0, ts_poet_1.code) `
|
|
2445
|
-
toJSON(${messageDesc.field.length > 0 ? "message" : "_"}: ${fullName}): unknown {
|
|
2454
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "toJSON")}(${messageDesc.field.length > 0 ? "message" : "_"}: ${fullName}): unknown {
|
|
2446
2455
|
const obj: any = {};
|
|
2447
2456
|
`);
|
|
2448
2457
|
let currentIfTarget = "";
|
|
@@ -2528,20 +2537,19 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2528
2537
|
return (0, ts_poet_1.code) `${from}`;
|
|
2529
2538
|
}
|
|
2530
2539
|
else {
|
|
2531
|
-
|
|
2532
|
-
return (0, ts_poet_1.code) `${type}.toJSON(${from})`;
|
|
2540
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, valueType.typeName, "toJSON")}(${from})`;
|
|
2533
2541
|
}
|
|
2534
2542
|
}
|
|
2535
2543
|
else if ((0, types_1.isAnyValueType)(field)) {
|
|
2536
2544
|
return (0, ts_poet_1.code) `${from}`;
|
|
2537
2545
|
}
|
|
2538
2546
|
else if ((0, types_1.isFieldMaskType)(field)) {
|
|
2539
|
-
const
|
|
2540
|
-
|
|
2547
|
+
const toJson = (0, types_1.getMessageMethod)(ctx, field.typeName, "toJSON");
|
|
2548
|
+
const wrap = (0, types_1.getMessageMethod)(ctx, field.typeName, "wrap");
|
|
2549
|
+
return (0, ts_poet_1.code) `${toJson}(${wrap}(${from}))`;
|
|
2541
2550
|
}
|
|
2542
2551
|
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})`;
|
|
2552
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "toJSON")}(${from})`;
|
|
2545
2553
|
}
|
|
2546
2554
|
else if ((0, types_1.isBytes)(field)) {
|
|
2547
2555
|
return (0, ts_poet_1.code) `${utils.base64FromBytes}(${from})`;
|
|
@@ -2641,31 +2649,32 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
2641
2649
|
function generateFromPartial(ctx, fullName, messageDesc) {
|
|
2642
2650
|
const { options, utils } = ctx;
|
|
2643
2651
|
const chunks = [];
|
|
2652
|
+
const maybeComma = options.outputStandaloneFunctions ? "" : ",";
|
|
2644
2653
|
// create the create function definition
|
|
2645
2654
|
if (ctx.options.useExactTypes) {
|
|
2646
2655
|
chunks.push((0, ts_poet_1.code) `
|
|
2647
|
-
create<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(base?: I): ${fullName} {
|
|
2648
|
-
return ${fullName}
|
|
2649
|
-
}
|
|
2656
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "create")}<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(base?: I): ${fullName} {
|
|
2657
|
+
return ${(0, utils_1.localMessageMethod)(options, fullName, "fromPartial")}(base ?? ({} as any));
|
|
2658
|
+
}${maybeComma}
|
|
2650
2659
|
`);
|
|
2651
2660
|
}
|
|
2652
2661
|
else {
|
|
2653
2662
|
chunks.push((0, ts_poet_1.code) `
|
|
2654
|
-
create(base?: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
2655
|
-
return ${fullName}
|
|
2656
|
-
}
|
|
2663
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "create")}(base?: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
2664
|
+
return ${(0, utils_1.localMessageMethod)(options, fullName, "fromPartial")}(base ?? {});
|
|
2665
|
+
}${maybeComma}
|
|
2657
2666
|
`);
|
|
2658
2667
|
}
|
|
2659
2668
|
// create the fromPartial function declaration
|
|
2660
2669
|
const paramName = messageDesc.field.length > 0 ? "object" : "_";
|
|
2661
2670
|
if (ctx.options.useExactTypes) {
|
|
2662
2671
|
chunks.push((0, ts_poet_1.code) `
|
|
2663
|
-
fromPartial<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(${paramName}: I): ${fullName} {
|
|
2672
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromPartial")}<I extends ${utils.Exact}<${utils.DeepPartial}<${fullName}>, I>>(${paramName}: I): ${fullName} {
|
|
2664
2673
|
`);
|
|
2665
2674
|
}
|
|
2666
2675
|
else {
|
|
2667
2676
|
chunks.push((0, ts_poet_1.code) `
|
|
2668
|
-
fromPartial(${paramName}: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
2677
|
+
${(0, utils_1.messageMethodHead)(options, fullName, "fromPartial")}(${paramName}: ${utils.DeepPartial}<${fullName}>): ${fullName} {
|
|
2669
2678
|
`);
|
|
2670
2679
|
}
|
|
2671
2680
|
let createBase = (0, ts_poet_1.code) `createBase${fullName}()`;
|
|
@@ -2745,16 +2754,14 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
2745
2754
|
return (0, ts_poet_1.code) `${from}`;
|
|
2746
2755
|
}
|
|
2747
2756
|
else {
|
|
2748
|
-
|
|
2749
|
-
return (0, ts_poet_1.code) `${type}.fromPartial(${from})`;
|
|
2757
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, valueField.typeName, "fromPartial")}(${from})`;
|
|
2750
2758
|
}
|
|
2751
2759
|
}
|
|
2752
2760
|
else if ((0, types_1.isAnyValueType)(field)) {
|
|
2753
2761
|
return (0, ts_poet_1.code) `${from}`;
|
|
2754
2762
|
}
|
|
2755
2763
|
else {
|
|
2756
|
-
|
|
2757
|
-
return (0, ts_poet_1.code) `${type}.fromPartial(${from})`;
|
|
2764
|
+
return (0, ts_poet_1.code) `${(0, types_1.getMessageMethod)(ctx, field.typeName, "fromPartial")}(${from})`;
|
|
2758
2765
|
}
|
|
2759
2766
|
}
|
|
2760
2767
|
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;
|
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,
|
|
@@ -262,6 +263,14 @@ function optionsFromParameter(parameter) {
|
|
|
262
263
|
// Make sure to cast number options to an actual number
|
|
263
264
|
options.unrecognizedEnumValue = Number(options.unrecognizedEnumValue);
|
|
264
265
|
}
|
|
266
|
+
if (options.outputStandaloneFunctions &&
|
|
267
|
+
(options.outputTypeRegistry ||
|
|
268
|
+
options.outputTypeAnnotations === "static-only" ||
|
|
269
|
+
options.outputServices.includes(ServiceOption.GENERIC) ||
|
|
270
|
+
options.nestJs ||
|
|
271
|
+
options.useMongoObjectId)) {
|
|
272
|
+
throw new Error("outputStandaloneFunctions=true can't be used with outputTypeRegistry=true, outputTypeAnnotations=static-only, outputServices=generic-definitions, nestJs=true, or useMongoObjectId=true");
|
|
273
|
+
}
|
|
265
274
|
return options;
|
|
266
275
|
}
|
|
267
276
|
// 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}
|