ts-proto 1.145.0 → 1.147.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 +11 -4
- package/build/case.js +8 -8
- package/build/enums.js +3 -3
- package/build/generate-generic-service-definition.js +3 -3
- package/build/generate-nice-grpc.js +8 -8
- package/build/main.js +357 -83
- package/build/options.js +2 -0
- package/build/types.js +2 -2
- package/build/utils.js +2 -1
- package/package.json +2 -2
package/README.markdown
CHANGED
|
@@ -220,7 +220,7 @@ creating a class and calling the right getters/setters.
|
|
|
220
220
|
|
|
221
221
|
- ObjectIds can be mapped as `mongodb.ObjectId`
|
|
222
222
|
|
|
223
|
-
(Configurable with the `
|
|
223
|
+
(Configurable with the `useMongoObjectId` parameter.)
|
|
224
224
|
|
|
225
225
|
# Auto-Batching / N+1 Prevention
|
|
226
226
|
|
|
@@ -410,11 +410,13 @@ Generated code will be placed in the Gradle build directory.
|
|
|
410
410
|
|
|
411
411
|
- 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.
|
|
412
412
|
|
|
413
|
-
- With `--ts_proto_opt=
|
|
413
|
+
- 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.
|
|
414
414
|
|
|
415
415
|
- With `--ts_proto_opt=outputSchema=true`, meta typings will be generated that can later be used in other code generators.
|
|
416
416
|
|
|
417
|
-
- With `--ts_proto_opt=
|
|
417
|
+
- With `--ts_proto_opt=outputTypeAnnotations=true`, each message will be given a `$type` field containing its fully-qualified name.
|
|
418
|
+
|
|
419
|
+
- 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.
|
|
418
420
|
|
|
419
421
|
- 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.
|
|
420
422
|
|
|
@@ -461,7 +463,7 @@ Generated code will be placed in the Gradle build directory.
|
|
|
461
463
|
|
|
462
464
|
- With `--ts_proto_opt=useJsonWireFormat=true`, the generated code will reflect the JSON representation of Protobuf messages.
|
|
463
465
|
|
|
464
|
-
Requires `onlyTypes=true`. Implies `useDate=string` and `stringEnums=true`. This option is to generate types that can be directly used with marshalling/unmarshalling Protobuf messages serialized as JSON.
|
|
466
|
+
Requires `onlyTypes=true`. Implies `useDate=string` and `stringEnums=true`. This option is to generate types that can be directly used with marshalling/unmarshalling Protobuf messages serialized as JSON.
|
|
465
467
|
You may also want to set `useOptionals=all`, as gRPC gateways are not required to send default value for scalar values.
|
|
466
468
|
|
|
467
469
|
- With `--ts_proto_opt=useNumericEnumForJson=true`, the JSON converter (`toJSON`) will encode enum values as int, rather than a string literal.
|
|
@@ -502,6 +504,11 @@ Generated code will be placed in the Gradle build directory.
|
|
|
502
504
|
|
|
503
505
|
by default this is enabled which would generate a type of `Box_Element_Image_Alignment`. By disabling this option the type that is generated would be `BoxElementImageAlignment`.
|
|
504
506
|
|
|
507
|
+
- With `--ts_proto_opt=outputExtensions=true`, the generated code will include proto2 extensions
|
|
508
|
+
|
|
509
|
+
Extension encode/decode methods are compliant with the `outputEncodeMethods` option, and if `unknownFields=true`,
|
|
510
|
+
the `setExtension` and `getExtension` methods will be created for extendable messages, also compliant with `outputEncodeMethods` (setExtension = encode, getExtension = decode).
|
|
511
|
+
|
|
505
512
|
### NestJS Support
|
|
506
513
|
|
|
507
514
|
We have a great way of working together with [nestjs](https://docs.nestjs.com/microservices/grpc). `ts-proto` generates `interfaces` and `decorators` for you controller, client. For more information see the [nestjs readme](NESTJS.markdown).
|
package/build/case.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.camelCaseGrpc = exports.
|
|
3
|
+
exports.camelCaseGrpc = exports.uncapitalize = exports.capitalize = exports.camelToSnake = exports.snakeToCamel = exports.maybeSnakeToCamel = void 0;
|
|
4
4
|
const case_anything_1 = require("case-anything");
|
|
5
5
|
/** Converts `key` to TS/JS camel-case idiom, unless overridden not to. */
|
|
6
6
|
function maybeSnakeToCamel(key, options) {
|
|
@@ -32,16 +32,16 @@ function capitalize(s) {
|
|
|
32
32
|
return s.substring(0, 1).toUpperCase() + s.substring(1);
|
|
33
33
|
}
|
|
34
34
|
exports.capitalize = capitalize;
|
|
35
|
-
function
|
|
35
|
+
function uncapitalize(s) {
|
|
36
36
|
return s.substring(0, 1).toLowerCase() + s.substring(1);
|
|
37
37
|
}
|
|
38
|
-
exports.
|
|
38
|
+
exports.uncapitalize = uncapitalize;
|
|
39
|
+
/* This function uses the exact same semantics found inside the grpc
|
|
40
|
+
* nodejs library. Camel case splitting must be done by word i.e
|
|
41
|
+
* GetAPIValue must become getApiValue (notice the API becomes Api).
|
|
42
|
+
* This needs to be followed otherwise it will not succeed in the grpc nodejs module.
|
|
43
|
+
*/
|
|
39
44
|
function camelCaseGrpc(s) {
|
|
40
|
-
/* This function uses the exact same semantics found inside the grpc
|
|
41
|
-
* nodejs library. Camel case splitting must be done by word i.e
|
|
42
|
-
* GetAPIValue must become getApiValue (notice the API becomes Api).
|
|
43
|
-
* This needs to be followed otherwise it will not succeed in the grpc nodejs module.
|
|
44
|
-
*/
|
|
45
45
|
return (0, case_anything_1.camelCase)(s);
|
|
46
46
|
}
|
|
47
47
|
exports.camelCaseGrpc = camelCaseGrpc;
|
package/build/enums.js
CHANGED
|
@@ -58,7 +58,7 @@ exports.generateEnum = generateEnum;
|
|
|
58
58
|
function generateEnumFromJson(ctx, fullName, enumDesc) {
|
|
59
59
|
const { options, utils } = ctx;
|
|
60
60
|
const chunks = [];
|
|
61
|
-
const functionName = (0, case_1.
|
|
61
|
+
const functionName = (0, case_1.uncapitalize)(fullName) + "FromJSON";
|
|
62
62
|
chunks.push((0, ts_poet_1.code) `export function ${(0, ts_poet_1.def)(functionName)}(object: any): ${fullName} {`);
|
|
63
63
|
chunks.push((0, ts_poet_1.code) `switch (object) {`);
|
|
64
64
|
for (const valueDesc of enumDesc.value) {
|
|
@@ -94,7 +94,7 @@ exports.generateEnumFromJson = generateEnumFromJson;
|
|
|
94
94
|
function generateEnumToJson(ctx, fullName, enumDesc) {
|
|
95
95
|
const { options, utils } = ctx;
|
|
96
96
|
const chunks = [];
|
|
97
|
-
const functionName = (0, case_1.
|
|
97
|
+
const functionName = (0, case_1.uncapitalize)(fullName) + "ToJSON";
|
|
98
98
|
chunks.push((0, ts_poet_1.code) `export function ${(0, ts_poet_1.def)(functionName)}(object: ${fullName}): ${ctx.options.useNumericEnumForJson ? "number" : "string"} {`);
|
|
99
99
|
chunks.push((0, ts_poet_1.code) `switch (object) {`);
|
|
100
100
|
for (const valueDesc of enumDesc.value) {
|
|
@@ -140,7 +140,7 @@ exports.generateEnumToJson = generateEnumToJson;
|
|
|
140
140
|
function generateEnumToNumber(ctx, fullName, enumDesc) {
|
|
141
141
|
const { options, utils } = ctx;
|
|
142
142
|
const chunks = [];
|
|
143
|
-
const functionName = (0, case_1.
|
|
143
|
+
const functionName = (0, case_1.uncapitalize)(fullName) + "ToNumber";
|
|
144
144
|
chunks.push((0, ts_poet_1.code) `export function ${(0, ts_poet_1.def)(functionName)}(object: ${fullName}): number {`);
|
|
145
145
|
chunks.push((0, ts_poet_1.code) `switch (object) {`);
|
|
146
146
|
for (const valueDesc of enumDesc.value) {
|
|
@@ -33,7 +33,7 @@ function generateGenericServiceDefinition(ctx, fileDesc, sourceInfo, serviceDesc
|
|
|
33
33
|
const info = sourceInfo.lookup(sourceInfo_1.Fields.service.method, index);
|
|
34
34
|
(0, utils_1.maybeAddComment)(info, chunks, (_c = methodDesc.options) === null || _c === void 0 ? void 0 : _c.deprecated);
|
|
35
35
|
chunks.push((0, ts_poet_1.code) `
|
|
36
|
-
${(0, case_1.
|
|
36
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}: ${generateMethodDefinition(ctx, methodDesc)},
|
|
37
37
|
`);
|
|
38
38
|
}
|
|
39
39
|
chunks.push((0, ts_poet_1.code) `
|
|
@@ -76,10 +76,10 @@ function generateMethodOptions(ctx, options) {
|
|
|
76
76
|
for (const value of values) {
|
|
77
77
|
valuesChunks.push((0, ts_poet_1.code) `${ctx.options.env == "node" ? "Buffer.from" : "new Uint8Array"}([${value.join(", ")}])`);
|
|
78
78
|
}
|
|
79
|
-
unknownFieldsChunks.push((0, ts_poet_1.code) `${key}: [\n${(0, ts_poet_1.joinCode)(valuesChunks, { on: "," })
|
|
79
|
+
unknownFieldsChunks.push((0, ts_poet_1.code) `${key}: [\n${(0, ts_poet_1.joinCode)(valuesChunks, { on: "," })}\n],`);
|
|
80
80
|
}
|
|
81
81
|
unknownFieldsChunks.push((0, ts_poet_1.code) `}`);
|
|
82
|
-
chunks.push((0, ts_poet_1.code) `_unknownFields: ${(0, ts_poet_1.joinCode)(unknownFieldsChunks, { on: "\n" })
|
|
82
|
+
chunks.push((0, ts_poet_1.code) `_unknownFields: ${(0, ts_poet_1.joinCode)(unknownFieldsChunks, { on: "\n" })}`);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
@@ -37,7 +37,7 @@ function generateServerStub(ctx, sourceInfo, serviceDesc) {
|
|
|
37
37
|
if (methodDesc.serverStreaming) {
|
|
38
38
|
// bidi streaming
|
|
39
39
|
chunks.push((0, ts_poet_1.code) `
|
|
40
|
-
${(0, case_1.
|
|
40
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}(
|
|
41
41
|
request: AsyncIterable<${inputType}>,
|
|
42
42
|
context: ${CallContext} & CallContextExt,
|
|
43
43
|
): ${ServerStreamingMethodResult}<${outputType}>;
|
|
@@ -46,7 +46,7 @@ function generateServerStub(ctx, sourceInfo, serviceDesc) {
|
|
|
46
46
|
else {
|
|
47
47
|
// client streaming
|
|
48
48
|
chunks.push((0, ts_poet_1.code) `
|
|
49
|
-
${(0, case_1.
|
|
49
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}(
|
|
50
50
|
request: AsyncIterable<${inputType}>,
|
|
51
51
|
context: ${CallContext} & CallContextExt,
|
|
52
52
|
): Promise<${outputType}>;
|
|
@@ -57,7 +57,7 @@ function generateServerStub(ctx, sourceInfo, serviceDesc) {
|
|
|
57
57
|
if (methodDesc.serverStreaming) {
|
|
58
58
|
// server streaming
|
|
59
59
|
chunks.push((0, ts_poet_1.code) `
|
|
60
|
-
${(0, case_1.
|
|
60
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}(
|
|
61
61
|
request: ${inputType},
|
|
62
62
|
context: ${CallContext} & CallContextExt,
|
|
63
63
|
): ${ServerStreamingMethodResult}<${outputType}>;
|
|
@@ -66,7 +66,7 @@ function generateServerStub(ctx, sourceInfo, serviceDesc) {
|
|
|
66
66
|
else {
|
|
67
67
|
// unary
|
|
68
68
|
chunks.push((0, ts_poet_1.code) `
|
|
69
|
-
${(0, case_1.
|
|
69
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}(
|
|
70
70
|
request: ${inputType},
|
|
71
71
|
context: ${CallContext} & CallContextExt,
|
|
72
72
|
): Promise<${outputType}>;
|
|
@@ -94,7 +94,7 @@ function generateClientStub(ctx, sourceInfo, serviceDesc) {
|
|
|
94
94
|
if (methodDesc.serverStreaming) {
|
|
95
95
|
// bidi streaming
|
|
96
96
|
chunks.push((0, ts_poet_1.code) `
|
|
97
|
-
${(0, case_1.
|
|
97
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}(
|
|
98
98
|
request: AsyncIterable<${inputType}>,
|
|
99
99
|
options?: ${CallOptions} & CallOptionsExt,
|
|
100
100
|
): AsyncIterable<${outputType}>;
|
|
@@ -103,7 +103,7 @@ function generateClientStub(ctx, sourceInfo, serviceDesc) {
|
|
|
103
103
|
else {
|
|
104
104
|
// client streaming
|
|
105
105
|
chunks.push((0, ts_poet_1.code) `
|
|
106
|
-
${(0, case_1.
|
|
106
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}(
|
|
107
107
|
request: AsyncIterable<${inputType}>,
|
|
108
108
|
options?: ${CallOptions} & CallOptionsExt,
|
|
109
109
|
): Promise<${outputType}>;
|
|
@@ -114,7 +114,7 @@ function generateClientStub(ctx, sourceInfo, serviceDesc) {
|
|
|
114
114
|
if (methodDesc.serverStreaming) {
|
|
115
115
|
// server streaming
|
|
116
116
|
chunks.push((0, ts_poet_1.code) `
|
|
117
|
-
${(0, case_1.
|
|
117
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}(
|
|
118
118
|
request: ${inputType},
|
|
119
119
|
options?: ${CallOptions} & CallOptionsExt,
|
|
120
120
|
): AsyncIterable<${outputType}>;
|
|
@@ -123,7 +123,7 @@ function generateClientStub(ctx, sourceInfo, serviceDesc) {
|
|
|
123
123
|
else {
|
|
124
124
|
// unary
|
|
125
125
|
chunks.push((0, ts_poet_1.code) `
|
|
126
|
-
${(0, case_1.
|
|
126
|
+
${(0, case_1.uncapitalize)(methodDesc.name)}(
|
|
127
127
|
request: ${inputType},
|
|
128
128
|
options?: ${CallOptions} & CallOptionsExt,
|
|
129
129
|
): Promise<${outputType}>;
|
package/build/main.js
CHANGED
|
@@ -77,7 +77,11 @@ function generateFile(ctx, fileDesc) {
|
|
|
77
77
|
// We add `nestJs` here because enough though it doesn't use our encode/decode methods
|
|
78
78
|
// for most/vanilla messages, we do generate static wrap/unwrap methods for the special
|
|
79
79
|
// Struct/Value/wrapper types and use the `wrappers[...]` to have NestJS know about them.
|
|
80
|
-
if (options.outputEncodeMethods ||
|
|
80
|
+
if (options.outputEncodeMethods ||
|
|
81
|
+
options.outputJsonMethods ||
|
|
82
|
+
options.outputTypeAnnotations ||
|
|
83
|
+
options.outputTypeRegistry ||
|
|
84
|
+
options.nestJs) {
|
|
81
85
|
// then add the encoder/decoder/base instance
|
|
82
86
|
(0, visit_1.visit)(fileDesc, sourceInfo, (fullName, message, _sInfo, fullProtoTypeName) => {
|
|
83
87
|
const fullTypeName = (0, utils_1.maybePrefixPackage)(fileDesc, fullProtoTypeName);
|
|
@@ -89,17 +93,29 @@ function generateFile(ctx, fileDesc) {
|
|
|
89
93
|
chunks.push(generateBaseInstanceFactory(ctx, fullName, message, fullTypeName));
|
|
90
94
|
}
|
|
91
95
|
const staticMembers = [];
|
|
92
|
-
if (options.outputTypeRegistry) {
|
|
96
|
+
if (options.outputTypeAnnotations || options.outputTypeRegistry) {
|
|
93
97
|
staticMembers.push((0, ts_poet_1.code) `$type: '${fullTypeName}' as const`);
|
|
94
98
|
}
|
|
99
|
+
if (options.outputExtensions) {
|
|
100
|
+
for (const extension of message.extension) {
|
|
101
|
+
const { name, type, extensionInfo } = generateExtension(ctx, message, extension);
|
|
102
|
+
staticMembers.push((0, ts_poet_1.code) `${name}: <${ctx.utils.Extension}<${type}>> ${extensionInfo}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
95
105
|
if (options.outputEncodeMethods) {
|
|
96
106
|
if (options.outputEncodeMethods === true ||
|
|
97
107
|
options.outputEncodeMethods === "encode-only" ||
|
|
98
108
|
options.outputEncodeMethods === "encode-no-creation") {
|
|
99
109
|
staticMembers.push(generateEncode(ctx, fullName, message));
|
|
110
|
+
if (options.outputExtensions && options.unknownFields && message.extensionRange.length) {
|
|
111
|
+
staticMembers.push(generateSetExtension(ctx, fullName));
|
|
112
|
+
}
|
|
100
113
|
}
|
|
101
114
|
if (options.outputEncodeMethods === true || options.outputEncodeMethods === "decode-only") {
|
|
102
115
|
staticMembers.push(generateDecode(ctx, fullName, message));
|
|
116
|
+
if (options.outputExtensions && options.unknownFields && message.extensionRange.length) {
|
|
117
|
+
staticMembers.push(generateGetExtension(ctx, fullName));
|
|
118
|
+
}
|
|
103
119
|
}
|
|
104
120
|
}
|
|
105
121
|
if (options.useAsyncIterable) {
|
|
@@ -144,6 +160,12 @@ function generateFile(ctx, fileDesc) {
|
|
|
144
160
|
}
|
|
145
161
|
}, options);
|
|
146
162
|
}
|
|
163
|
+
if (options.outputExtensions) {
|
|
164
|
+
for (const extension of fileDesc.extension) {
|
|
165
|
+
const { name, type, extensionInfo } = generateExtension(ctx, undefined, extension);
|
|
166
|
+
chunks.push((0, ts_poet_1.code) `export const ${name}: ${ctx.utils.Extension}<${type}> = ${extensionInfo};`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
147
169
|
if (options.nestJs) {
|
|
148
170
|
if (fileDesc.messageType.find((message) => message.field.find(types_1.isStructType))) {
|
|
149
171
|
chunks.push(makeProtobufStructWrapper(options));
|
|
@@ -256,6 +278,7 @@ function makeUtils(options) {
|
|
|
256
278
|
...makeComparisonUtils(),
|
|
257
279
|
...makeNiceGrpcServerStreamingMethodResult(),
|
|
258
280
|
...makeGrpcWebErrorClass(bytes),
|
|
281
|
+
...makeExtensionClass(options),
|
|
259
282
|
};
|
|
260
283
|
}
|
|
261
284
|
exports.makeUtils = makeUtils;
|
|
@@ -395,7 +418,7 @@ function makeDeepPartial(options, longs) {
|
|
|
395
418
|
const maybeLong = options.forceLong === options_1.LongOption.LONG ? (0, ts_poet_1.code) ` : T extends ${longs.Long} ? string | number | Long ` : "";
|
|
396
419
|
const Builtin = (0, ts_poet_1.conditionalOutput)("Builtin", (0, ts_poet_1.code) `type Builtin = Date | Function | Uint8Array | string | number | boolean |${options.forceLong === options_1.LongOption.BIGINT ? " bigint |" : ""} undefined;`);
|
|
397
420
|
// Based on https://github.com/sindresorhus/type-fest/pull/259
|
|
398
|
-
const maybeExcludeType = options.outputTypeRegistry ? `| '$type'` : "";
|
|
421
|
+
const maybeExcludeType = options.outputTypeAnnotations || options.outputTypeRegistry ? `| '$type'` : "";
|
|
399
422
|
const Exact = (0, ts_poet_1.conditionalOutput)("Exact", (0, ts_poet_1.code) `
|
|
400
423
|
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|
401
424
|
${maybeExport} type Exact<P, I extends P> = P extends ${Builtin}
|
|
@@ -404,7 +427,7 @@ function makeDeepPartial(options, longs) {
|
|
|
404
427
|
{ [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P> ${maybeExcludeType}>]: never };
|
|
405
428
|
`);
|
|
406
429
|
// Based on the type from ts-essentials
|
|
407
|
-
const keys = options.outputTypeRegistry ? (0, ts_poet_1.code) `Exclude<keyof T, '$type'>` : (0, ts_poet_1.code) `keyof T`;
|
|
430
|
+
const keys = options.outputTypeAnnotations || options.outputTypeRegistry ? (0, ts_poet_1.code) `Exclude<keyof T, '$type'>` : (0, ts_poet_1.code) `keyof T`;
|
|
408
431
|
const DeepPartial = (0, ts_poet_1.conditionalOutput)("DeepPartial", (0, ts_poet_1.code) `
|
|
409
432
|
${maybeExport} type DeepPartial<T> = T extends ${Builtin}
|
|
410
433
|
? T
|
|
@@ -464,7 +487,7 @@ function makeTimestampMethods(options, longs) {
|
|
|
464
487
|
// (note this only occurs when the string is > 8 characters)
|
|
465
488
|
seconds = "Math.trunc(date.getTime() / 1_000).toString()";
|
|
466
489
|
}
|
|
467
|
-
const maybeTypeField = options.outputTypeRegistry ? `$type: 'google.protobuf.Timestamp',` : "";
|
|
490
|
+
const maybeTypeField = options.outputTypeAnnotations || options.outputTypeRegistry ? `$type: 'google.protobuf.Timestamp',` : "";
|
|
468
491
|
const toTimestamp = (0, ts_poet_1.conditionalOutput)("toTimestamp", options.useDate === options_1.DateOption.STRING
|
|
469
492
|
? (0, ts_poet_1.code) `
|
|
470
493
|
function toTimestamp(dateStr: string): ${Timestamp} {
|
|
@@ -550,6 +573,22 @@ function makeGrpcWebErrorClass(bytes) {
|
|
|
550
573
|
`);
|
|
551
574
|
return { GrpcWebError };
|
|
552
575
|
}
|
|
576
|
+
function makeExtensionClass(options) {
|
|
577
|
+
const Reader = (0, utils_1.impFile)(options, "Reader@protobufjs/minimal");
|
|
578
|
+
const Writer = (0, utils_1.impFile)(options, "Writer@protobufjs/minimal");
|
|
579
|
+
const Extension = (0, ts_poet_1.conditionalOutput)("Extension", (0, ts_poet_1.code) `
|
|
580
|
+
export interface Extension <T> {
|
|
581
|
+
number: number;
|
|
582
|
+
tag: number;
|
|
583
|
+
singularTag?: number;
|
|
584
|
+
encode?: (message: T) => Uint8Array[];
|
|
585
|
+
decode?: (tag: number, input: Uint8Array[]) => T;
|
|
586
|
+
repeated: boolean;
|
|
587
|
+
packed: boolean;
|
|
588
|
+
}
|
|
589
|
+
`);
|
|
590
|
+
return { Extension };
|
|
591
|
+
}
|
|
553
592
|
// Create the interface with properties
|
|
554
593
|
function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fullTypeName) {
|
|
555
594
|
var _a;
|
|
@@ -558,7 +597,7 @@ function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fu
|
|
|
558
597
|
(0, utils_1.maybeAddComment)(sourceInfo, chunks, (_a = messageDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
|
|
559
598
|
// interface name should be defined to avoid import collisions
|
|
560
599
|
chunks.push((0, ts_poet_1.code) `export interface ${(0, ts_poet_1.def)(fullName)} {`);
|
|
561
|
-
if (ctx.options.outputTypeRegistry) {
|
|
600
|
+
if (ctx.options.outputTypeAnnotations || ctx.options.outputTypeRegistry) {
|
|
562
601
|
chunks.push((0, ts_poet_1.code) `$type: '${fullTypeName}',`);
|
|
563
602
|
}
|
|
564
603
|
// When oneof=unions, we generate a single property with an ADT per `oneof` clause.
|
|
@@ -649,7 +688,7 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
649
688
|
: (0, types_1.defaultValue)(ctx, field);
|
|
650
689
|
fields.push((0, ts_poet_1.code) `${name}: ${val}`);
|
|
651
690
|
}
|
|
652
|
-
if (ctx.options.outputTypeRegistry) {
|
|
691
|
+
if (ctx.options.outputTypeAnnotations || ctx.options.outputTypeRegistry) {
|
|
653
692
|
fields.unshift((0, ts_poet_1.code) `$type: '${fullTypeName}'`);
|
|
654
693
|
}
|
|
655
694
|
if (ctx.options.unknownFields && ctx.options.initializeFieldsAsUndefined) {
|
|
@@ -661,6 +700,73 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
661
700
|
}
|
|
662
701
|
`;
|
|
663
702
|
}
|
|
703
|
+
function getDecodeReadSnippet(ctx, field) {
|
|
704
|
+
const { options, utils } = ctx;
|
|
705
|
+
let readSnippet;
|
|
706
|
+
if ((0, types_1.isPrimitive)(field)) {
|
|
707
|
+
readSnippet = (0, ts_poet_1.code) `reader.${(0, types_1.toReaderCall)(field)}()`;
|
|
708
|
+
if ((0, types_1.isBytes)(field)) {
|
|
709
|
+
if (options.env === options_1.EnvOption.NODE) {
|
|
710
|
+
readSnippet = (0, ts_poet_1.code) `${readSnippet} as Buffer`;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
else if ((0, types_1.basicLongWireType)(field.type) !== undefined) {
|
|
714
|
+
if (options.forceLong === options_1.LongOption.LONG) {
|
|
715
|
+
readSnippet = (0, ts_poet_1.code) `${readSnippet} as Long`;
|
|
716
|
+
}
|
|
717
|
+
else if (options.forceLong === options_1.LongOption.STRING) {
|
|
718
|
+
readSnippet = (0, ts_poet_1.code) `${utils.longToString}(${readSnippet} as Long)`;
|
|
719
|
+
}
|
|
720
|
+
else if (options.forceLong === options_1.LongOption.BIGINT) {
|
|
721
|
+
readSnippet = (0, ts_poet_1.code) `${utils.longToBigint}(${readSnippet} as Long)`;
|
|
722
|
+
}
|
|
723
|
+
else {
|
|
724
|
+
readSnippet = (0, ts_poet_1.code) `${utils.longToNumber}(${readSnippet} as Long)`;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
else if ((0, types_1.isEnum)(field)) {
|
|
728
|
+
if (options.stringEnums) {
|
|
729
|
+
const fromJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "FromJSON");
|
|
730
|
+
readSnippet = (0, ts_poet_1.code) `${fromJson}(${readSnippet})`;
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
readSnippet = (0, ts_poet_1.code) `${readSnippet} as any`;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
738
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
739
|
+
const unwrap = (decodedValue) => {
|
|
740
|
+
if ((0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isAnyValueType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
741
|
+
return (0, ts_poet_1.code) `${type}.unwrap(${decodedValue})`;
|
|
742
|
+
}
|
|
743
|
+
return (0, ts_poet_1.code) `${decodedValue}.value`;
|
|
744
|
+
};
|
|
745
|
+
const decoder = (0, ts_poet_1.code) `${type}.decode(reader, reader.uint32())`;
|
|
746
|
+
readSnippet = (0, ts_poet_1.code) `${unwrap(decoder)}`;
|
|
747
|
+
}
|
|
748
|
+
else if ((0, types_1.isTimestamp)(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
749
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
750
|
+
readSnippet = (0, ts_poet_1.code) `${utils.fromTimestamp}(${type}.decode(reader, reader.uint32()))`;
|
|
751
|
+
}
|
|
752
|
+
else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
|
|
753
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
754
|
+
readSnippet = (0, ts_poet_1.code) `${utils.fromProtoObjectId}(${type}.decode(reader, reader.uint32()))`;
|
|
755
|
+
}
|
|
756
|
+
else if ((0, types_1.isMessage)(field)) {
|
|
757
|
+
const type = (0, types_1.basicTypeName)(ctx, field);
|
|
758
|
+
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP) {
|
|
759
|
+
readSnippet = (0, ts_poet_1.code) `${type}.decode(reader)`;
|
|
760
|
+
}
|
|
761
|
+
else {
|
|
762
|
+
readSnippet = (0, ts_poet_1.code) `${type}.decode(reader, reader.uint32())`;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
throw new Error(`Unhandled field ${field}`);
|
|
767
|
+
}
|
|
768
|
+
return readSnippet;
|
|
769
|
+
}
|
|
664
770
|
/** Creates a function to decode a message by loop overing the tags. */
|
|
665
771
|
function generateDecode(ctx, fullName, messageDesc) {
|
|
666
772
|
const { options, utils, typeMap } = ctx;
|
|
@@ -692,71 +798,12 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
692
798
|
chunks.push((0, ts_poet_1.code) `case ${field.number}:`);
|
|
693
799
|
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
694
800
|
const tagCheck = (0, ts_poet_1.code) `
|
|
695
|
-
if(tag
|
|
801
|
+
if (tag !== ${tag}) {
|
|
696
802
|
break;
|
|
803
|
+
}
|
|
697
804
|
`;
|
|
698
805
|
// get a generic 'reader.doSomething' bit that is specific to the basic type
|
|
699
|
-
|
|
700
|
-
if ((0, types_1.isPrimitive)(field)) {
|
|
701
|
-
readSnippet = (0, ts_poet_1.code) `reader.${(0, types_1.toReaderCall)(field)}()`;
|
|
702
|
-
if ((0, types_1.isBytes)(field)) {
|
|
703
|
-
if (options.env === options_1.EnvOption.NODE) {
|
|
704
|
-
readSnippet = (0, ts_poet_1.code) `${readSnippet} as Buffer`;
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
else if ((0, types_1.basicLongWireType)(field.type) !== undefined) {
|
|
708
|
-
if (options.forceLong === options_1.LongOption.LONG) {
|
|
709
|
-
readSnippet = (0, ts_poet_1.code) `${readSnippet} as Long`;
|
|
710
|
-
}
|
|
711
|
-
else if (options.forceLong === options_1.LongOption.STRING) {
|
|
712
|
-
readSnippet = (0, ts_poet_1.code) `${utils.longToString}(${readSnippet} as Long)`;
|
|
713
|
-
}
|
|
714
|
-
else if (options.forceLong === options_1.LongOption.BIGINT) {
|
|
715
|
-
readSnippet = (0, ts_poet_1.code) `${utils.longToBigint}(${readSnippet} as Long)`;
|
|
716
|
-
}
|
|
717
|
-
else {
|
|
718
|
-
readSnippet = (0, ts_poet_1.code) `${utils.longToNumber}(${readSnippet} as Long)`;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
else if ((0, types_1.isEnum)(field)) {
|
|
722
|
-
if (options.stringEnums) {
|
|
723
|
-
const fromJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "FromJSON");
|
|
724
|
-
readSnippet = (0, ts_poet_1.code) `${fromJson}(${readSnippet})`;
|
|
725
|
-
}
|
|
726
|
-
else {
|
|
727
|
-
readSnippet = (0, ts_poet_1.code) `${readSnippet} as any`;
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
732
|
-
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
733
|
-
const unwrap = (decodedValue) => {
|
|
734
|
-
if ((0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isAnyValueType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
735
|
-
return (0, ts_poet_1.code) `${type}.unwrap(${decodedValue})`;
|
|
736
|
-
}
|
|
737
|
-
return (0, ts_poet_1.code) `${decodedValue}.value`;
|
|
738
|
-
};
|
|
739
|
-
const decoder = (0, ts_poet_1.code) `${type}.decode(reader, reader.uint32())`;
|
|
740
|
-
readSnippet = (0, ts_poet_1.code) `${unwrap(decoder)}`;
|
|
741
|
-
}
|
|
742
|
-
else if ((0, types_1.isTimestamp)(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
743
|
-
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
744
|
-
readSnippet = (0, ts_poet_1.code) `${utils.fromTimestamp}(${type}.decode(reader, reader.uint32()))`;
|
|
745
|
-
}
|
|
746
|
-
else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
|
|
747
|
-
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
748
|
-
readSnippet = (0, ts_poet_1.code) `${utils.fromProtoObjectId}(${type}.decode(reader, reader.uint32()))`;
|
|
749
|
-
}
|
|
750
|
-
else if ((0, types_1.isMessage)(field)) {
|
|
751
|
-
const type = (0, types_1.basicTypeName)(ctx, field);
|
|
752
|
-
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP)
|
|
753
|
-
readSnippet = (0, ts_poet_1.code) `${type}.decode(reader)`;
|
|
754
|
-
else
|
|
755
|
-
readSnippet = (0, ts_poet_1.code) `${type}.decode(reader, reader.uint32())`;
|
|
756
|
-
}
|
|
757
|
-
else {
|
|
758
|
-
throw new Error(`Unhandled field ${field}`);
|
|
759
|
-
}
|
|
806
|
+
const readSnippet = getDecodeReadSnippet(ctx, field);
|
|
760
807
|
// and then use the snippet to handle repeated fields if necessary
|
|
761
808
|
const initializerNecessary = !options.initializeFieldsAsUndefined && (0, types_1.isOptionalProperty)(field, messageDesc.options, options);
|
|
762
809
|
if ((0, types_1.isRepeated)(field)) {
|
|
@@ -769,9 +816,9 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
769
816
|
: `message.${fieldName}${maybeNonNullAssertion}[${varName}.key] = ${varName}.value`;
|
|
770
817
|
const initializerSnippet = initializerNecessary
|
|
771
818
|
? `
|
|
772
|
-
if(message.${fieldName} === undefined)
|
|
819
|
+
if (message.${fieldName} === undefined) {
|
|
773
820
|
message.${fieldName} = ${ctx.options.useMapType ? "new Map()" : "{}"};
|
|
774
|
-
`
|
|
821
|
+
}`
|
|
775
822
|
: "";
|
|
776
823
|
chunks.push((0, ts_poet_1.code) `
|
|
777
824
|
${tagCheck}
|
|
@@ -784,8 +831,10 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
784
831
|
}
|
|
785
832
|
else {
|
|
786
833
|
const initializerSnippet = initializerNecessary
|
|
787
|
-
? `
|
|
788
|
-
|
|
834
|
+
? `
|
|
835
|
+
if (message.${fieldName} === undefined) {
|
|
836
|
+
message.${fieldName} = [];
|
|
837
|
+
}`
|
|
789
838
|
: "";
|
|
790
839
|
if ((0, types_1.packedType)(field.type) === undefined) {
|
|
791
840
|
chunks.push((0, ts_poet_1.code) `
|
|
@@ -797,13 +846,14 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
797
846
|
else {
|
|
798
847
|
const packedTag = ((field.number << 3) | 2) >>> 0;
|
|
799
848
|
chunks.push((0, ts_poet_1.code) `
|
|
800
|
-
if(tag
|
|
849
|
+
if (tag === ${tag}) {
|
|
801
850
|
${initializerSnippet}
|
|
802
851
|
message.${fieldName}${maybeNonNullAssertion}.push(${readSnippet});
|
|
852
|
+
|
|
803
853
|
continue;
|
|
804
854
|
}
|
|
805
855
|
|
|
806
|
-
if(tag
|
|
856
|
+
if (tag === ${packedTag}) {
|
|
807
857
|
${initializerSnippet}
|
|
808
858
|
const end2 = reader.uint32() + reader.pos;
|
|
809
859
|
while (reader.pos < end2) {
|
|
@@ -831,21 +881,24 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
831
881
|
message.${fieldName} = ${readSnippet};
|
|
832
882
|
`);
|
|
833
883
|
}
|
|
834
|
-
if (!(0, types_1.isRepeated)(field) || (0, types_1.packedType)(field.type) === undefined)
|
|
884
|
+
if (!(0, types_1.isRepeated)(field) || (0, types_1.packedType)(field.type) === undefined) {
|
|
835
885
|
chunks.push((0, ts_poet_1.code) `continue;`);
|
|
886
|
+
}
|
|
836
887
|
});
|
|
837
888
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
838
889
|
chunks.push((0, ts_poet_1.code) `
|
|
839
|
-
if((tag & 7)
|
|
890
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
840
891
|
break;
|
|
892
|
+
}
|
|
841
893
|
`);
|
|
842
894
|
if (options.unknownFields) {
|
|
843
895
|
let unknownFieldsInitializerSnippet = "";
|
|
844
896
|
let maybeNonNullAssertion = options.initializeFieldsAsUndefined ? "!" : "";
|
|
845
897
|
if (!options.initializeFieldsAsUndefined) {
|
|
846
898
|
unknownFieldsInitializerSnippet = `
|
|
847
|
-
if(message._unknownFields === undefined)
|
|
899
|
+
if (message._unknownFields === undefined) {
|
|
848
900
|
message._unknownFields = {};
|
|
901
|
+
}
|
|
849
902
|
`;
|
|
850
903
|
}
|
|
851
904
|
chunks.push((0, ts_poet_1.code) `
|
|
@@ -856,10 +909,11 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
856
909
|
${unknownFieldsInitializerSnippet}
|
|
857
910
|
const list = message._unknownFields${maybeNonNullAssertion}[tag];
|
|
858
911
|
|
|
859
|
-
if(list === undefined)
|
|
912
|
+
if (list === undefined) {
|
|
860
913
|
message._unknownFields${maybeNonNullAssertion}[tag] = [buf];
|
|
861
|
-
else
|
|
914
|
+
} else {
|
|
862
915
|
list.push(buf);
|
|
916
|
+
}
|
|
863
917
|
`);
|
|
864
918
|
}
|
|
865
919
|
else {
|
|
@@ -900,7 +954,7 @@ function getEncodeWriteSnippet(ctx, field) {
|
|
|
900
954
|
return (place) => (0, ts_poet_1.code) `${type}.encode(${utils.toTimestamp}(${place}), writer.uint32(${tag}).fork()).ldelim()`;
|
|
901
955
|
}
|
|
902
956
|
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
903
|
-
const maybeTypeField = options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
957
|
+
const maybeTypeField = options.outputTypeAnnotations || options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
904
958
|
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
905
959
|
const wrappedValue = (place) => {
|
|
906
960
|
if ((0, types_1.isAnyValueType)(field) || (0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
@@ -949,7 +1003,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
949
1003
|
if ((0, types_1.isRepeated)(field)) {
|
|
950
1004
|
if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
|
|
951
1005
|
const valueType = typeMap.get(field.typeName)[2].field[1];
|
|
952
|
-
const maybeTypeField = options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
1006
|
+
const maybeTypeField = options.outputTypeAnnotations || options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
953
1007
|
const entryWriteSnippet = (0, types_1.isValueType)(ctx, valueType)
|
|
954
1008
|
? (0, ts_poet_1.code) `
|
|
955
1009
|
if (value !== undefined) {
|
|
@@ -1099,6 +1153,226 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1099
1153
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
1100
1154
|
return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
|
|
1101
1155
|
}
|
|
1156
|
+
function generateSetExtension(ctx, fullName) {
|
|
1157
|
+
return (0, ts_poet_1.code) `
|
|
1158
|
+
setExtension <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>, value: T): void {
|
|
1159
|
+
const encoded = extension.encode!(value);
|
|
1160
|
+
|
|
1161
|
+
if (message._unknownFields !== undefined) {
|
|
1162
|
+
delete message._unknownFields[extension.tag];
|
|
1163
|
+
|
|
1164
|
+
if (extension.singularTag !== undefined) {
|
|
1165
|
+
delete message._unknownFields[extension.singularTag];
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
if (encoded.length !== 0) {
|
|
1170
|
+
if (message._unknownFields === undefined) {
|
|
1171
|
+
message._unknownFields = {};
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
message._unknownFields[extension.tag] = encoded;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
`;
|
|
1178
|
+
}
|
|
1179
|
+
function generateGetExtension(ctx, fullName) {
|
|
1180
|
+
return (0, ts_poet_1.code) `
|
|
1181
|
+
getExtension <T> (message: ${fullName}, extension: ${ctx.utils.Extension}<T>): T | undefined {
|
|
1182
|
+
let results: T | undefined = undefined;
|
|
1183
|
+
|
|
1184
|
+
if (message._unknownFields === undefined) {
|
|
1185
|
+
return undefined;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
let list = message._unknownFields[extension.tag];
|
|
1189
|
+
|
|
1190
|
+
if (list !== undefined) {
|
|
1191
|
+
results = extension.decode!(extension.tag, list);
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
if (extension.singularTag === undefined) {
|
|
1195
|
+
return results;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
list = message._unknownFields[extension.singularTag];
|
|
1199
|
+
|
|
1200
|
+
if (list !== undefined) {
|
|
1201
|
+
const results2 = extension.decode!(extension.singularTag, list);
|
|
1202
|
+
|
|
1203
|
+
if (results !== undefined && (results as any).length !== 0) {
|
|
1204
|
+
results = (results as any).concat(results2);
|
|
1205
|
+
} else {
|
|
1206
|
+
results = results2;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
return results;
|
|
1211
|
+
}
|
|
1212
|
+
`;
|
|
1213
|
+
}
|
|
1214
|
+
function generateExtension(ctx, message, extension) {
|
|
1215
|
+
var _a;
|
|
1216
|
+
const type = (0, types_1.toTypeName)(ctx, message, extension);
|
|
1217
|
+
const packedTag = (0, types_1.isRepeated)(extension) && (0, types_1.packedType)(extension.type) !== undefined ? ((extension.number << 3) | 2) >>> 0 : undefined;
|
|
1218
|
+
const singularTag = ((extension.number << 3) | (0, types_1.basicWireType)(extension.type)) >>> 0;
|
|
1219
|
+
const tag = packedTag !== null && packedTag !== void 0 ? packedTag : singularTag;
|
|
1220
|
+
const chunks = [];
|
|
1221
|
+
chunks.push((0, ts_poet_1.code) `{`);
|
|
1222
|
+
chunks.push((0, ts_poet_1.code) `number: ${extension.number},`);
|
|
1223
|
+
chunks.push((0, ts_poet_1.code) `tag: ${tag},`);
|
|
1224
|
+
if (packedTag !== undefined)
|
|
1225
|
+
chunks.push((0, ts_poet_1.code) `singularTag: ${singularTag},`);
|
|
1226
|
+
chunks.push((0, ts_poet_1.code) `repeated: ${extension.label == ts_proto_descriptors_1.FieldDescriptorProto_Label.LABEL_REPEATED},`);
|
|
1227
|
+
chunks.push((0, ts_poet_1.code) `packed: ${((_a = extension.options) === null || _a === void 0 ? void 0 : _a.packed) ? true : false},`);
|
|
1228
|
+
const Reader = (0, utils_1.impFile)(ctx.options, "Reader@protobufjs/minimal");
|
|
1229
|
+
const Writer = (0, utils_1.impFile)(ctx.options, "Writer@protobufjs/minimal");
|
|
1230
|
+
if (ctx.options.outputEncodeMethods === true ||
|
|
1231
|
+
ctx.options.outputEncodeMethods === "encode-only" ||
|
|
1232
|
+
ctx.options.outputEncodeMethods === "encode-no-creation") {
|
|
1233
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1234
|
+
encode: (value: ${type}): Uint8Array[] => {
|
|
1235
|
+
const encoded: Uint8Array[] = [];
|
|
1236
|
+
`);
|
|
1237
|
+
function getEncodeSnippet(ctx, field) {
|
|
1238
|
+
const { options, utils } = ctx;
|
|
1239
|
+
if ((0, types_1.isEnum)(field) && options.stringEnums) {
|
|
1240
|
+
const toNumber = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToNumber");
|
|
1241
|
+
return (place) => (0, ts_poet_1.code) `writer.${(0, types_1.toReaderCall)(field)}(${toNumber}(${place}))`;
|
|
1242
|
+
}
|
|
1243
|
+
else if ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT) {
|
|
1244
|
+
return (place) => (0, ts_poet_1.code) `writer.${(0, types_1.toReaderCall)(field)}(${place}.toString())`;
|
|
1245
|
+
}
|
|
1246
|
+
else if ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) {
|
|
1247
|
+
return (place) => (0, ts_poet_1.code) `writer.${(0, types_1.toReaderCall)(field)}(${place})`;
|
|
1248
|
+
}
|
|
1249
|
+
else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
|
|
1250
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
1251
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${utils.toProtoObjectId}(${place}), writer.fork()).ldelim()`;
|
|
1252
|
+
}
|
|
1253
|
+
else if ((0, types_1.isTimestamp)(field) && (options.useDate === options_1.DateOption.DATE || options.useDate === options_1.DateOption.STRING)) {
|
|
1254
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
1255
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${utils.toTimestamp}(${place}), writer.fork()).ldelim()`;
|
|
1256
|
+
}
|
|
1257
|
+
else if ((0, types_1.isValueType)(ctx, field)) {
|
|
1258
|
+
const maybeTypeField = options.outputTypeAnnotations || options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : "";
|
|
1259
|
+
const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
|
|
1260
|
+
const wrappedValue = (place) => {
|
|
1261
|
+
if ((0, types_1.isAnyValueType)(field) || (0, types_1.isListValueType)(field) || (0, types_1.isStructType)(field) || (0, types_1.isFieldMaskType)(field)) {
|
|
1262
|
+
return (0, ts_poet_1.code) `${type}.wrap(${place})`;
|
|
1263
|
+
}
|
|
1264
|
+
return (0, ts_poet_1.code) `{${maybeTypeField} value: ${place}!}`;
|
|
1265
|
+
};
|
|
1266
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${wrappedValue(place)}, writer.fork()).ldelim()`;
|
|
1267
|
+
}
|
|
1268
|
+
else if ((0, types_1.isMessage)(field)) {
|
|
1269
|
+
const type = (0, types_1.basicTypeName)(ctx, field);
|
|
1270
|
+
if (field.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_GROUP) {
|
|
1271
|
+
const endTag = ((field.number << 3) | 4) >>> 0;
|
|
1272
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${place}, writer).uint32(${endTag})`;
|
|
1273
|
+
}
|
|
1274
|
+
return (place) => (0, ts_poet_1.code) `${type}.encode(${place}, writer.fork()).ldelim()`;
|
|
1275
|
+
}
|
|
1276
|
+
else {
|
|
1277
|
+
throw new Error(`Unhandled field ${field}`);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
const writeSnippet = getEncodeSnippet(ctx, extension);
|
|
1281
|
+
if ((0, types_1.isRepeated)(extension)) {
|
|
1282
|
+
if (packedTag === undefined) {
|
|
1283
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1284
|
+
for (const v of value) {
|
|
1285
|
+
const writer = ${Writer}.create();
|
|
1286
|
+
${writeSnippet("v")};
|
|
1287
|
+
encoded.push(writer.finish());
|
|
1288
|
+
}
|
|
1289
|
+
`);
|
|
1290
|
+
}
|
|
1291
|
+
else {
|
|
1292
|
+
const rhs = (x) => (0, types_1.isLong)(extension) && ctx.options.forceLong === options_1.LongOption.BIGINT ? `${x}.toString()` : x;
|
|
1293
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1294
|
+
const writer = ${Writer}.create();
|
|
1295
|
+
writer.fork();
|
|
1296
|
+
for (const v of value) {
|
|
1297
|
+
${writeSnippet(rhs("v"))};
|
|
1298
|
+
}
|
|
1299
|
+
writer.ldelim();
|
|
1300
|
+
encoded.push(writer.finish());
|
|
1301
|
+
`);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
else if ((0, types_1.isScalar)(extension) || (0, types_1.isEnum)(extension)) {
|
|
1305
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1306
|
+
if (${(0, types_1.notDefaultCheck)(ctx, extension, message === null || message === void 0 ? void 0 : message.options, "value")}) {
|
|
1307
|
+
const writer = ${Writer}.create();
|
|
1308
|
+
${writeSnippet("value")};
|
|
1309
|
+
encoded.push(writer.finish());
|
|
1310
|
+
}
|
|
1311
|
+
`);
|
|
1312
|
+
}
|
|
1313
|
+
else {
|
|
1314
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1315
|
+
const writer = ${Writer}.create();
|
|
1316
|
+
${writeSnippet("value")};
|
|
1317
|
+
encoded.push(writer.finish());
|
|
1318
|
+
`);
|
|
1319
|
+
}
|
|
1320
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1321
|
+
return encoded;
|
|
1322
|
+
},
|
|
1323
|
+
`);
|
|
1324
|
+
}
|
|
1325
|
+
if (ctx.options.outputEncodeMethods === true || ctx.options.outputEncodeMethods === "decode-only") {
|
|
1326
|
+
chunks.push((0, ts_poet_1.code) `decode: (tag: number, input: Uint8Array[]): ${type} => {`);
|
|
1327
|
+
// get a generic 'reader.doSomething' bit that is specific to the basic type
|
|
1328
|
+
const readSnippet = getDecodeReadSnippet(ctx, extension);
|
|
1329
|
+
if ((0, types_1.isRepeated)(extension)) {
|
|
1330
|
+
chunks.push((0, ts_poet_1.code) `const values: ${type} = [];`);
|
|
1331
|
+
// start loop over all buffers
|
|
1332
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1333
|
+
for (var buffer of input) {
|
|
1334
|
+
const reader = ${Reader}.create(buffer);
|
|
1335
|
+
`);
|
|
1336
|
+
if ((0, types_1.packedType)(extension.type) === undefined) {
|
|
1337
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1338
|
+
values.push(${readSnippet});
|
|
1339
|
+
`);
|
|
1340
|
+
}
|
|
1341
|
+
else {
|
|
1342
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1343
|
+
if (tag == ${packedTag}) {
|
|
1344
|
+
const end2 = reader.uint32() + reader.pos;
|
|
1345
|
+
while (reader.pos < end2) {
|
|
1346
|
+
values.push(${readSnippet});
|
|
1347
|
+
}
|
|
1348
|
+
} else {
|
|
1349
|
+
values.push(${readSnippet});
|
|
1350
|
+
}
|
|
1351
|
+
`);
|
|
1352
|
+
}
|
|
1353
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
return values;
|
|
1357
|
+
},
|
|
1358
|
+
`);
|
|
1359
|
+
}
|
|
1360
|
+
else {
|
|
1361
|
+
// pick the last entry, since it overrides all previous entries if not repeated
|
|
1362
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1363
|
+
const reader = ${Reader}.create(input[input.length -1]);
|
|
1364
|
+
return ${readSnippet};
|
|
1365
|
+
},
|
|
1366
|
+
`);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
chunks.push((0, ts_poet_1.code) `}`);
|
|
1370
|
+
return {
|
|
1371
|
+
name: (0, case_1.maybeSnakeToCamel)(extension.name, ctx.options),
|
|
1372
|
+
type,
|
|
1373
|
+
extensionInfo: (0, ts_poet_1.joinCode)(chunks, { on: "\n" }),
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1102
1376
|
/**
|
|
1103
1377
|
* Creates a function to decode a message from JSON.
|
|
1104
1378
|
*
|
|
@@ -1113,7 +1387,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1113
1387
|
fromJSON(${messageDesc.field.length > 0 ? "object" : "_"}: any): ${fullName} {
|
|
1114
1388
|
return {
|
|
1115
1389
|
`);
|
|
1116
|
-
if (ctx.options.outputTypeRegistry) {
|
|
1390
|
+
if (ctx.options.outputTypeAnnotations || ctx.options.outputTypeRegistry) {
|
|
1117
1391
|
chunks.push((0, ts_poet_1.code) `$type: ${fullName}.$type,`);
|
|
1118
1392
|
}
|
|
1119
1393
|
const oneofFieldsCases = messageDesc.oneofDecl.map((oneof, oneofIndex) => messageDesc.field.filter(types_1.isWithinOneOf).filter((field) => field.oneofIndex === oneofIndex));
|
package/build/options.js
CHANGED
|
@@ -49,6 +49,7 @@ function defaultOptions() {
|
|
|
49
49
|
outputEncodeMethods: true,
|
|
50
50
|
outputJsonMethods: true,
|
|
51
51
|
outputPartialMethods: true,
|
|
52
|
+
outputTypeAnnotations: false,
|
|
52
53
|
outputTypeRegistry: false,
|
|
53
54
|
stringEnums: false,
|
|
54
55
|
constEnums: false,
|
|
@@ -78,6 +79,7 @@ function defaultOptions() {
|
|
|
78
79
|
useMapType: false,
|
|
79
80
|
useReadonlyTypes: false,
|
|
80
81
|
useSnakeTypeName: true,
|
|
82
|
+
outputExtensions: false,
|
|
81
83
|
M: {},
|
|
82
84
|
};
|
|
83
85
|
}
|
package/build/types.js
CHANGED
|
@@ -571,14 +571,14 @@ function toModuleAndType(typeMap, protoType) {
|
|
|
571
571
|
}
|
|
572
572
|
function getEnumMethod(ctx, enumProtoType, methodSuffix) {
|
|
573
573
|
const [module, type] = toModuleAndType(ctx.typeMap, enumProtoType);
|
|
574
|
-
return (0, utils_1.impProto)(ctx.options, module, `${(0, case_1.
|
|
574
|
+
return (0, utils_1.impProto)(ctx.options, module, `${(0, case_1.uncapitalize)(type)}${methodSuffix}`);
|
|
575
575
|
}
|
|
576
576
|
exports.getEnumMethod = getEnumMethod;
|
|
577
577
|
/** Return the TypeName for any field (primitive/message/etc.) as exposed in the interface. */
|
|
578
578
|
function toTypeName(ctx, messageDesc, field) {
|
|
579
579
|
let type = basicTypeName(ctx, field, { keepValueType: false });
|
|
580
580
|
if (isRepeated(field)) {
|
|
581
|
-
const mapType = detectMapType(ctx, messageDesc, field);
|
|
581
|
+
const mapType = messageDesc ? detectMapType(ctx, messageDesc, field) : false;
|
|
582
582
|
if (mapType) {
|
|
583
583
|
const { keyType, valueType } = mapType;
|
|
584
584
|
if (ctx.options.useMapType) {
|
package/build/utils.js
CHANGED
|
@@ -138,7 +138,8 @@ class FormattedMethodDescriptor {
|
|
|
138
138
|
static formatName(methodName, options) {
|
|
139
139
|
let result = methodName;
|
|
140
140
|
if (options.lowerCaseServiceMethods || options.outputServices.includes(options_1.ServiceOption.GRPC)) {
|
|
141
|
-
|
|
141
|
+
if (options.snakeToCamel)
|
|
142
|
+
result = (0, case_1.camelCaseGrpc)(result);
|
|
142
143
|
}
|
|
143
144
|
return result;
|
|
144
145
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-proto",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.147.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/plugin.js",
|
|
6
6
|
"repository": "github:stephenh/ts-proto",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"object-hash": "^1.3.1",
|
|
66
66
|
"protobufjs": "^6.11.3",
|
|
67
67
|
"ts-poet": "^6.4.1",
|
|
68
|
-
"ts-proto-descriptors": "1.
|
|
68
|
+
"ts-proto-descriptors": "1.9.0"
|
|
69
69
|
},
|
|
70
70
|
"packageManager": "yarn@3.3.0"
|
|
71
71
|
}
|