ts-proto 1.161.0 → 1.162.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 +2 -0
- package/build/main.js +90 -72
- package/build/options.js +1 -0
- package/build/utils.js +31 -4
- package/package.json +1 -1
package/README.markdown
CHANGED
|
@@ -477,6 +477,8 @@ Generated code will be placed in the Gradle build directory.
|
|
|
477
477
|
|
|
478
478
|
Note that, as indicated, this means Object.keys will not include set-by-default fields, so if you have code that iterates over messages keys in a generic fashion, it will have to also iterate over keys inherited from the prototype.
|
|
479
479
|
|
|
480
|
+
- With `--ts_proto_opt=useJsonName=true`, `json_name` defined in protofiles will be used instead of message field names.
|
|
481
|
+
|
|
480
482
|
- With `--ts_proto_opt=useJsonWireFormat=true`, the generated code will reflect the JSON representation of Protobuf messages.
|
|
481
483
|
|
|
482
484
|
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.
|
package/build/main.js
CHANGED
|
@@ -464,12 +464,13 @@ function makeTimestampMethods(options, longs, bytes) {
|
|
|
464
464
|
const Timestamp = (0, utils_1.impProto)(options, "google/protobuf/timestamp", "Timestamp");
|
|
465
465
|
let seconds = "date.getTime() / 1_000";
|
|
466
466
|
let toNumberCode = "t.seconds";
|
|
467
|
+
const makeToNumberCode = (methodCall) => `t.seconds${options.useOptionals === "all" ? "?" : ""}.${methodCall}`;
|
|
467
468
|
if (options.forceLong === options_1.LongOption.LONG) {
|
|
468
|
-
toNumberCode = "
|
|
469
|
+
toNumberCode = makeToNumberCode("toNumber()");
|
|
469
470
|
seconds = (0, ts_poet_1.code) `${longs.numberToLong}(date.getTime() / 1_000)`;
|
|
470
471
|
}
|
|
471
472
|
else if (options.forceLong === options_1.LongOption.BIGINT) {
|
|
472
|
-
toNumberCode = (0, ts_poet_1.code) `${bytes.globalThis}.Number(
|
|
473
|
+
toNumberCode = (0, ts_poet_1.code) `${bytes.globalThis}.Number(${makeToNumberCode("toString()")})`;
|
|
473
474
|
seconds = (0, ts_poet_1.code) `BigInt(Math.trunc(date.getTime() / 1_000))`;
|
|
474
475
|
}
|
|
475
476
|
else if (options.forceLong === options_1.LongOption.STRING) {
|
|
@@ -614,10 +615,10 @@ function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fu
|
|
|
614
615
|
}
|
|
615
616
|
const info = sourceInfo.lookup(sourceInfo_1.Fields.message.field, index);
|
|
616
617
|
(0, utils_1.maybeAddComment)(info, chunks, (_a = fieldDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
|
|
617
|
-
const
|
|
618
|
+
const { validatedPropertyName } = (0, utils_1.propertyNameComposition)(fieldDesc, options);
|
|
618
619
|
const isOptional = (0, types_1.isOptionalProperty)(fieldDesc, messageDesc.options, options);
|
|
619
620
|
const type = (0, types_1.toTypeName)(ctx, messageDesc, fieldDesc, isOptional);
|
|
620
|
-
chunks.push((0, ts_poet_1.code) `${maybeReadonly(options)}${
|
|
621
|
+
chunks.push((0, ts_poet_1.code) `${maybeReadonly(options)}${validatedPropertyName}${isOptional ? "?" : ""}: ${type}, `);
|
|
621
622
|
});
|
|
622
623
|
if (ctx.options.unknownFields) {
|
|
623
624
|
chunks.push((0, ts_poet_1.code) `_unknownFields?: {[key: number]: Uint8Array[]} | undefined,`);
|
|
@@ -668,7 +669,9 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
668
669
|
const { oneofIndex } = field;
|
|
669
670
|
if (!processedOneofs.has(oneofIndex)) {
|
|
670
671
|
processedOneofs.add(oneofIndex);
|
|
671
|
-
const name =
|
|
672
|
+
const name = options.useJsonName
|
|
673
|
+
? (0, utils_1.propertyNameComposition)(field, options).validatedPropertyName
|
|
674
|
+
: (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[oneofIndex].name, ctx.options);
|
|
672
675
|
fields.push((0, ts_poet_1.code) `${name}: undefined`);
|
|
673
676
|
}
|
|
674
677
|
continue;
|
|
@@ -676,7 +679,7 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
676
679
|
if (!options.initializeFieldsAsUndefined && (0, types_1.isOptionalProperty)(field, messageDesc.options, options)) {
|
|
677
680
|
continue;
|
|
678
681
|
}
|
|
679
|
-
const
|
|
682
|
+
const { validatedPropertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
680
683
|
const val = (0, types_1.isWithinOneOf)(field)
|
|
681
684
|
? "undefined"
|
|
682
685
|
: (0, types_1.isMapType)(ctx, messageDesc, field)
|
|
@@ -686,7 +689,7 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
686
689
|
: (0, types_1.isRepeated)(field)
|
|
687
690
|
? "[]"
|
|
688
691
|
: (0, types_1.defaultValue)(ctx, field);
|
|
689
|
-
fields.push((0, ts_poet_1.code) `${
|
|
692
|
+
fields.push((0, ts_poet_1.code) `${validatedPropertyName}: ${val}`);
|
|
690
693
|
}
|
|
691
694
|
if ((0, options_1.addTypeToMessages)(options)) {
|
|
692
695
|
fields.unshift((0, ts_poet_1.code) `$type: '${fullTypeName}'`);
|
|
@@ -794,7 +797,8 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
794
797
|
`);
|
|
795
798
|
// add a case for each incoming field
|
|
796
799
|
messageDesc.field.forEach((field) => {
|
|
797
|
-
const
|
|
800
|
+
const { propertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
801
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", propertyName);
|
|
798
802
|
chunks.push((0, ts_poet_1.code) `case ${field.number}:`);
|
|
799
803
|
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
800
804
|
const tagCheck = (0, ts_poet_1.code) `
|
|
@@ -815,15 +819,15 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
815
819
|
const generateMapType = (0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field);
|
|
816
820
|
let valueSetterSnippet;
|
|
817
821
|
if (generateMapType) {
|
|
818
|
-
valueSetterSnippet =
|
|
822
|
+
valueSetterSnippet = `${messageProperty}${maybeNonNullAssertion}.set(${varName}.key, ${varName}.value)`;
|
|
819
823
|
}
|
|
820
824
|
else {
|
|
821
|
-
valueSetterSnippet =
|
|
825
|
+
valueSetterSnippet = `${messageProperty}${maybeNonNullAssertion}[${varName}.key] = ${varName}.value`;
|
|
822
826
|
}
|
|
823
827
|
const initializerSnippet = initializerNecessary
|
|
824
828
|
? `
|
|
825
|
-
if (
|
|
826
|
-
|
|
829
|
+
if (${messageProperty} === undefined) {
|
|
830
|
+
${messageProperty} = ${generateMapType ? "new Map()" : "{}"};
|
|
827
831
|
}`
|
|
828
832
|
: "";
|
|
829
833
|
chunks.push((0, ts_poet_1.code) `
|
|
@@ -838,15 +842,15 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
838
842
|
else {
|
|
839
843
|
const initializerSnippet = initializerNecessary
|
|
840
844
|
? `
|
|
841
|
-
if (
|
|
842
|
-
|
|
845
|
+
if (${messageProperty} === undefined) {
|
|
846
|
+
${messageProperty} = [];
|
|
843
847
|
}`
|
|
844
848
|
: "";
|
|
845
849
|
if ((0, types_1.packedType)(field.type) === undefined) {
|
|
846
850
|
chunks.push((0, ts_poet_1.code) `
|
|
847
851
|
${tagCheck}
|
|
848
852
|
${initializerSnippet}
|
|
849
|
-
|
|
853
|
+
${messageProperty}${maybeNonNullAssertion}.push(${readSnippet});
|
|
850
854
|
`);
|
|
851
855
|
}
|
|
852
856
|
else {
|
|
@@ -854,7 +858,7 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
854
858
|
chunks.push((0, ts_poet_1.code) `
|
|
855
859
|
if (tag === ${tag}) {
|
|
856
860
|
${initializerSnippet}
|
|
857
|
-
|
|
861
|
+
${messageProperty}${maybeNonNullAssertion}.push(${readSnippet});
|
|
858
862
|
|
|
859
863
|
continue;
|
|
860
864
|
}
|
|
@@ -863,7 +867,7 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
863
867
|
${initializerSnippet}
|
|
864
868
|
const end2 = reader.uint32() + reader.pos;
|
|
865
869
|
while (reader.pos < end2) {
|
|
866
|
-
|
|
870
|
+
${messageProperty}${maybeNonNullAssertion}.push(${readSnippet});
|
|
867
871
|
}
|
|
868
872
|
|
|
869
873
|
continue;
|
|
@@ -875,16 +879,18 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
875
879
|
}
|
|
876
880
|
}
|
|
877
881
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
878
|
-
|
|
882
|
+
const oneofNameWithMessage = options.useJsonName
|
|
883
|
+
? messageProperty
|
|
884
|
+
: (0, utils_1.getPropertyAccessor)("message", (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options));
|
|
879
885
|
chunks.push((0, ts_poet_1.code) `
|
|
880
886
|
${tagCheck}
|
|
881
|
-
|
|
887
|
+
${oneofNameWithMessage} = { $case: '${propertyName}', ${propertyName}: ${readSnippet} };
|
|
882
888
|
`);
|
|
883
889
|
}
|
|
884
890
|
else {
|
|
885
891
|
chunks.push((0, ts_poet_1.code) `
|
|
886
892
|
${tagCheck}
|
|
887
|
-
|
|
893
|
+
${messageProperty} = ${readSnippet};
|
|
888
894
|
`);
|
|
889
895
|
}
|
|
890
896
|
if (!(0, types_1.isRepeated)(field) || (0, types_1.packedType)(field.type) === undefined) {
|
|
@@ -1019,7 +1025,8 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1019
1025
|
.reduce((result, field) => ((result[field.oneofIndex] || (result[field.oneofIndex] = [])).push(field), result), {});
|
|
1020
1026
|
// then add a case for each field
|
|
1021
1027
|
messageDesc.field.forEach((field) => {
|
|
1022
|
-
const
|
|
1028
|
+
const { propertyName, validatedPropertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
1029
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", propertyName);
|
|
1023
1030
|
// get a generic writer.doSomething based on the basic type
|
|
1024
1031
|
const writeSnippet = getEncodeWriteSnippet(ctx, field);
|
|
1025
1032
|
const isOptional = (0, types_1.isOptionalProperty)(field, messageDesc.options, options);
|
|
@@ -1038,14 +1045,14 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1038
1045
|
const optionalAlternative = isOptional ? (useMapType ? " || new Map()" : " || {}") : "";
|
|
1039
1046
|
if (useMapType) {
|
|
1040
1047
|
chunks.push((0, ts_poet_1.code) `
|
|
1041
|
-
(
|
|
1048
|
+
(${messageProperty}${optionalAlternative}).forEach((value, key) => {
|
|
1042
1049
|
${entryWriteSnippet}
|
|
1043
1050
|
});
|
|
1044
1051
|
`);
|
|
1045
1052
|
}
|
|
1046
1053
|
else {
|
|
1047
1054
|
chunks.push((0, ts_poet_1.code) `
|
|
1048
|
-
Object.entries(
|
|
1055
|
+
Object.entries(${messageProperty}${optionalAlternative}).forEach(([key, value]) => {
|
|
1049
1056
|
${entryWriteSnippet}
|
|
1050
1057
|
});
|
|
1051
1058
|
`);
|
|
@@ -1053,13 +1060,13 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1053
1060
|
}
|
|
1054
1061
|
else if ((0, types_1.packedType)(field.type) === undefined) {
|
|
1055
1062
|
const listWriteSnippet = (0, ts_poet_1.code) `
|
|
1056
|
-
for (const v of
|
|
1063
|
+
for (const v of ${messageProperty}) {
|
|
1057
1064
|
${writeSnippet("v!")};
|
|
1058
1065
|
}
|
|
1059
1066
|
`;
|
|
1060
1067
|
if (isOptional) {
|
|
1061
1068
|
chunks.push((0, ts_poet_1.code) `
|
|
1062
|
-
if (
|
|
1069
|
+
if (${messageProperty} !== undefined && ${messageProperty}.length !== 0) {
|
|
1063
1070
|
${listWriteSnippet}
|
|
1064
1071
|
}
|
|
1065
1072
|
`);
|
|
@@ -1077,14 +1084,14 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1077
1084
|
const toNumber = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToNumber");
|
|
1078
1085
|
const listWriteSnippet = (0, ts_poet_1.code) `
|
|
1079
1086
|
writer.uint32(${tag}).fork();
|
|
1080
|
-
for (const v of
|
|
1087
|
+
for (const v of ${messageProperty}) {
|
|
1081
1088
|
writer.${(0, types_1.toReaderCall)(field)}(${toNumber}(v));
|
|
1082
1089
|
}
|
|
1083
1090
|
writer.ldelim();
|
|
1084
1091
|
`;
|
|
1085
1092
|
if (isOptional) {
|
|
1086
1093
|
chunks.push((0, ts_poet_1.code) `
|
|
1087
|
-
if (
|
|
1094
|
+
if (${messageProperty} !== undefined && ${messageProperty}.length !== 0) {
|
|
1088
1095
|
${listWriteSnippet}
|
|
1089
1096
|
}
|
|
1090
1097
|
`);
|
|
@@ -1099,7 +1106,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1099
1106
|
const rhs = (x) => ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT ? `${x}.toString()` : x);
|
|
1100
1107
|
let listWriteSnippet = (0, ts_poet_1.code) `
|
|
1101
1108
|
writer.uint32(${tag}).fork();
|
|
1102
|
-
for (const v of
|
|
1109
|
+
for (const v of ${messageProperty}) {
|
|
1103
1110
|
writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
|
|
1104
1111
|
}
|
|
1105
1112
|
writer.ldelim();
|
|
@@ -1112,9 +1119,9 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1112
1119
|
case "sfixed64":
|
|
1113
1120
|
listWriteSnippet = (0, ts_poet_1.code) `
|
|
1114
1121
|
writer.uint32(${tag}).fork();
|
|
1115
|
-
for (const v of
|
|
1122
|
+
for (const v of ${messageProperty}) {
|
|
1116
1123
|
if (BigInt.asIntN(64, v) !== v) {
|
|
1117
|
-
throw new Error('a value provided in array field ${
|
|
1124
|
+
throw new Error('a value provided in array field ${propertyName} of type ${fieldType} is too large');
|
|
1118
1125
|
}
|
|
1119
1126
|
writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
|
|
1120
1127
|
}
|
|
@@ -1125,9 +1132,9 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1125
1132
|
case "fixed64":
|
|
1126
1133
|
listWriteSnippet = (0, ts_poet_1.code) `
|
|
1127
1134
|
writer.uint32(${tag}).fork();
|
|
1128
|
-
for (const v of
|
|
1135
|
+
for (const v of ${messageProperty}) {
|
|
1129
1136
|
if (BigInt.asUintN(64, v) !== v) {
|
|
1130
|
-
throw new Error('a value provided in array field ${
|
|
1137
|
+
throw new Error('a value provided in array field ${propertyName} of type ${fieldType} is too large');
|
|
1131
1138
|
}
|
|
1132
1139
|
writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
|
|
1133
1140
|
}
|
|
@@ -1140,7 +1147,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1140
1147
|
}
|
|
1141
1148
|
if (isOptional) {
|
|
1142
1149
|
chunks.push((0, ts_poet_1.code) `
|
|
1143
|
-
if (
|
|
1150
|
+
if (${messageProperty} !== undefined && ${messageProperty}.length !== 0) {
|
|
1144
1151
|
${listWriteSnippet}
|
|
1145
1152
|
}
|
|
1146
1153
|
`);
|
|
@@ -1153,13 +1160,15 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1153
1160
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
1154
1161
|
if (!processedOneofs.has(field.oneofIndex)) {
|
|
1155
1162
|
processedOneofs.add(field.oneofIndex);
|
|
1156
|
-
const
|
|
1157
|
-
|
|
1163
|
+
const oneofNameWithMessage = options.useJsonName
|
|
1164
|
+
? messageProperty
|
|
1165
|
+
: (0, utils_1.getPropertyAccessor)("message", (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options));
|
|
1166
|
+
chunks.push((0, ts_poet_1.code) `switch (${oneofNameWithMessage}?.$case) {`);
|
|
1158
1167
|
for (const oneOfField of oneOfFieldsDict[field.oneofIndex]) {
|
|
1159
1168
|
const writeSnippet = getEncodeWriteSnippet(ctx, oneOfField);
|
|
1160
1169
|
const oneOfFieldName = (0, case_1.maybeSnakeToCamel)(oneOfField.name, ctx.options);
|
|
1161
1170
|
chunks.push((0, ts_poet_1.code) `case "${oneOfFieldName}":
|
|
1162
|
-
${writeSnippet(
|
|
1171
|
+
${writeSnippet(`${oneofNameWithMessage}.${oneOfFieldName}`)};
|
|
1163
1172
|
break;`);
|
|
1164
1173
|
}
|
|
1165
1174
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
@@ -1168,27 +1177,27 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1168
1177
|
else if ((0, types_1.isWithinOneOf)(field)) {
|
|
1169
1178
|
// Oneofs don't have a default value check b/c they need to denote which-oneof presence
|
|
1170
1179
|
chunks.push((0, ts_poet_1.code) `
|
|
1171
|
-
if (
|
|
1172
|
-
${writeSnippet(
|
|
1180
|
+
if (${messageProperty} !== undefined) {
|
|
1181
|
+
${writeSnippet(`${messageProperty}`)};
|
|
1173
1182
|
}
|
|
1174
1183
|
`);
|
|
1175
1184
|
}
|
|
1176
1185
|
else if ((0, types_1.isMessage)(field)) {
|
|
1177
1186
|
chunks.push((0, ts_poet_1.code) `
|
|
1178
|
-
if (
|
|
1179
|
-
${writeSnippet(
|
|
1187
|
+
if (${messageProperty} !== undefined) {
|
|
1188
|
+
${writeSnippet(`${messageProperty}`)};
|
|
1180
1189
|
}
|
|
1181
1190
|
`);
|
|
1182
1191
|
}
|
|
1183
1192
|
else if ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) {
|
|
1184
1193
|
chunks.push((0, ts_poet_1.code) `
|
|
1185
|
-
if (${(0, types_1.notDefaultCheck)(ctx, field, messageDesc.options,
|
|
1186
|
-
${writeSnippet(
|
|
1194
|
+
if (${(0, types_1.notDefaultCheck)(ctx, field, messageDesc.options, `${messageProperty}`)}) {
|
|
1195
|
+
${writeSnippet(`${messageProperty}`)};
|
|
1187
1196
|
}
|
|
1188
1197
|
`);
|
|
1189
1198
|
}
|
|
1190
1199
|
else {
|
|
1191
|
-
chunks.push((0, ts_poet_1.code) `${writeSnippet(
|
|
1200
|
+
chunks.push((0, ts_poet_1.code) `${writeSnippet(`${messageProperty}`)};`);
|
|
1192
1201
|
}
|
|
1193
1202
|
});
|
|
1194
1203
|
if (options.unknownFields) {
|
|
@@ -1460,7 +1469,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1460
1469
|
// add a check for each incoming field
|
|
1461
1470
|
messageDesc.field.forEach((field) => {
|
|
1462
1471
|
var _a;
|
|
1463
|
-
const fieldName = (0,
|
|
1472
|
+
const { validatedPropertyName: fieldName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
1464
1473
|
const jsonName = (0, utils_1.getFieldJsonName)(field, options);
|
|
1465
1474
|
const jsonProperty = (0, utils_1.getPropertyAccessor)("object", jsonName);
|
|
1466
1475
|
const jsonPropertyOptional = (0, utils_1.getPropertyAccessor)("object", jsonName, true);
|
|
@@ -1702,9 +1711,10 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1702
1711
|
`);
|
|
1703
1712
|
// then add a case for each field
|
|
1704
1713
|
messageDesc.field.forEach((field) => {
|
|
1705
|
-
const fieldName = (0,
|
|
1714
|
+
const { validatedPropertyName: fieldName, propertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
1706
1715
|
const jsonName = (0, utils_1.getFieldJsonName)(field, options);
|
|
1707
1716
|
const jsonProperty = (0, utils_1.getPropertyAccessor)("obj", jsonName);
|
|
1717
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", propertyName);
|
|
1708
1718
|
const readSnippet = (from) => {
|
|
1709
1719
|
if ((0, types_1.isEnum)(field)) {
|
|
1710
1720
|
const toJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToJSON");
|
|
@@ -1796,9 +1806,9 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1796
1806
|
const i = convertToObjectKey(ctx, messageDesc, field, "k");
|
|
1797
1807
|
if ((0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field)) {
|
|
1798
1808
|
chunks.push((0, ts_poet_1.code) `
|
|
1799
|
-
if (
|
|
1809
|
+
if (${messageProperty}?.size) {
|
|
1800
1810
|
${jsonProperty} = {};
|
|
1801
|
-
|
|
1811
|
+
${messageProperty}.forEach((v, k) => {
|
|
1802
1812
|
${jsonProperty}[${i}] = ${readSnippet("v")};
|
|
1803
1813
|
});
|
|
1804
1814
|
}
|
|
@@ -1806,8 +1816,8 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1806
1816
|
}
|
|
1807
1817
|
else {
|
|
1808
1818
|
chunks.push((0, ts_poet_1.code) `
|
|
1809
|
-
if (
|
|
1810
|
-
const entries = Object.entries(
|
|
1819
|
+
if (${messageProperty}) {
|
|
1820
|
+
const entries = Object.entries(${messageProperty});
|
|
1811
1821
|
if (entries.length > 0) {
|
|
1812
1822
|
${jsonProperty} = {};
|
|
1813
1823
|
entries.forEach(([k, v]) => {
|
|
@@ -1823,28 +1833,30 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1823
1833
|
const transformElement = readSnippet("e");
|
|
1824
1834
|
const maybeMap = transformElement.toCodeString([]) !== "e" ? (0, ts_poet_1.code) `.map(e => ${transformElement})` : "";
|
|
1825
1835
|
chunks.push((0, ts_poet_1.code) `
|
|
1826
|
-
if (
|
|
1827
|
-
${jsonProperty} =
|
|
1836
|
+
if (${messageProperty}?.length) {
|
|
1837
|
+
${jsonProperty} = ${messageProperty}${maybeMap};
|
|
1828
1838
|
}
|
|
1829
1839
|
`);
|
|
1830
1840
|
}
|
|
1831
1841
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
1832
1842
|
// oneofs in a union are only output as `oneof name = ...`
|
|
1833
|
-
const
|
|
1843
|
+
const oneofNameWithMessage = options.useJsonName
|
|
1844
|
+
? messageProperty
|
|
1845
|
+
: (0, utils_1.getPropertyAccessor)("message", (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options));
|
|
1834
1846
|
chunks.push((0, ts_poet_1.code) `
|
|
1835
|
-
if (
|
|
1836
|
-
${jsonProperty} = ${readSnippet(
|
|
1847
|
+
if (${oneofNameWithMessage}?.$case === '${fieldName}') {
|
|
1848
|
+
${jsonProperty} = ${readSnippet(`${oneofNameWithMessage}.${fieldName}`)};
|
|
1837
1849
|
}
|
|
1838
1850
|
`);
|
|
1839
1851
|
}
|
|
1840
1852
|
else {
|
|
1841
1853
|
let emitDefaultValuesForJson = ctx.options.emitDefaultValues.includes("json-methods");
|
|
1842
1854
|
const check = ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) && !((0, types_1.isWithinOneOf)(field) || emitDefaultValuesForJson)
|
|
1843
|
-
? (0, types_1.notDefaultCheck)(ctx, field, messageDesc.options,
|
|
1844
|
-
:
|
|
1855
|
+
? (0, types_1.notDefaultCheck)(ctx, field, messageDesc.options, `${messageProperty}`)
|
|
1856
|
+
: `${messageProperty} !== undefined`;
|
|
1845
1857
|
chunks.push((0, ts_poet_1.code) `
|
|
1846
1858
|
if (${check}) {
|
|
1847
|
-
${jsonProperty} = ${readSnippet(
|
|
1859
|
+
${jsonProperty} = ${readSnippet(`${messageProperty}`)};
|
|
1848
1860
|
}
|
|
1849
1861
|
`);
|
|
1850
1862
|
}
|
|
@@ -1890,7 +1902,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1890
1902
|
chunks.push((0, ts_poet_1.code) `const message = ${createBase}${maybeAsAny(options)};`);
|
|
1891
1903
|
// add a check for each incoming field
|
|
1892
1904
|
messageDesc.field.forEach((field) => {
|
|
1893
|
-
const
|
|
1905
|
+
const { propertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
1906
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", propertyName);
|
|
1907
|
+
const objectProperty = (0, utils_1.getPropertyAccessor)("object", propertyName);
|
|
1894
1908
|
const readSnippet = (from) => {
|
|
1895
1909
|
if (((0, types_1.isLong)(field) || (0, types_1.isLongValueType)(field)) && options.forceLong === options_1.LongOption.LONG) {
|
|
1896
1910
|
return (0, ts_poet_1.code) `Long.fromValue(${from})`;
|
|
@@ -1961,13 +1975,13 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1961
1975
|
const fieldType = (0, types_1.toTypeName)(ctx, messageDesc, field);
|
|
1962
1976
|
const i = convertFromObjectKey(ctx, messageDesc, field, "key");
|
|
1963
1977
|
const noValueSnippet = noDefaultValue
|
|
1964
|
-
? `(
|
|
1978
|
+
? `(${objectProperty} === undefined || ${objectProperty} === null) ? undefined : `
|
|
1965
1979
|
: "";
|
|
1966
1980
|
if ((0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field)) {
|
|
1967
1981
|
chunks.push((0, ts_poet_1.code) `
|
|
1968
|
-
|
|
1982
|
+
${messageProperty} = ${noValueSnippet} (() => {
|
|
1969
1983
|
const m = new Map();
|
|
1970
|
-
(
|
|
1984
|
+
(${objectProperty} as ${fieldType} ?? new Map()).forEach((value, key) => {
|
|
1971
1985
|
if (value !== undefined) {
|
|
1972
1986
|
m.set(key, ${readSnippet("value")});
|
|
1973
1987
|
}
|
|
@@ -1978,7 +1992,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1978
1992
|
}
|
|
1979
1993
|
else {
|
|
1980
1994
|
chunks.push((0, ts_poet_1.code) `
|
|
1981
|
-
|
|
1995
|
+
${messageProperty} = ${noValueSnippet} Object.entries(${objectProperty} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1982
1996
|
if (value !== undefined) {
|
|
1983
1997
|
acc[${i}] = ${readSnippet("value")};
|
|
1984
1998
|
}
|
|
@@ -1990,33 +2004,37 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1990
2004
|
else {
|
|
1991
2005
|
const fallback = noDefaultValue ? "undefined" : "[]";
|
|
1992
2006
|
chunks.push((0, ts_poet_1.code) `
|
|
1993
|
-
|
|
2007
|
+
${messageProperty} = ${objectProperty}?.map((e) => ${readSnippet("e")}) || ${fallback};
|
|
1994
2008
|
`);
|
|
1995
2009
|
}
|
|
1996
2010
|
}
|
|
1997
2011
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
1998
|
-
|
|
1999
|
-
|
|
2012
|
+
const oneofName = options.useJsonName
|
|
2013
|
+
? propertyName
|
|
2014
|
+
: (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
2015
|
+
const oneofNameWithMessage = (0, utils_1.getPropertyAccessor)("message", oneofName);
|
|
2016
|
+
const oneofNameWithObject = (0, utils_1.getPropertyAccessor)("object", oneofName);
|
|
2017
|
+
const v = readSnippet(`${oneofNameWithObject}.${propertyName}`);
|
|
2000
2018
|
chunks.push((0, ts_poet_1.code) `
|
|
2001
2019
|
if (
|
|
2002
|
-
|
|
2003
|
-
&&
|
|
2004
|
-
&&
|
|
2020
|
+
${oneofNameWithObject}?.$case === '${propertyName}'
|
|
2021
|
+
&& ${oneofNameWithObject}?.${propertyName} !== undefined
|
|
2022
|
+
&& ${oneofNameWithObject}?.${propertyName} !== null
|
|
2005
2023
|
) {
|
|
2006
|
-
|
|
2024
|
+
${oneofNameWithMessage} = { $case: '${propertyName}', ${propertyName}: ${v} };
|
|
2007
2025
|
}
|
|
2008
2026
|
`);
|
|
2009
2027
|
}
|
|
2010
2028
|
else if (readSnippet(`x`).toCodeString([]) == "x") {
|
|
2011
2029
|
// An optimized case of the else below that works when `readSnippet` returns the plain input
|
|
2012
2030
|
const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
|
|
2013
|
-
chunks.push((0, ts_poet_1.code)
|
|
2031
|
+
chunks.push((0, ts_poet_1.code) `${messageProperty} = ${objectProperty} ?? ${fallback};`);
|
|
2014
2032
|
}
|
|
2015
2033
|
else {
|
|
2016
2034
|
const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
|
|
2017
2035
|
chunks.push((0, ts_poet_1.code) `
|
|
2018
|
-
|
|
2019
|
-
? ${readSnippet(
|
|
2036
|
+
${messageProperty} = (${objectProperty} !== undefined && ${objectProperty} !== null)
|
|
2037
|
+
? ${readSnippet(`${objectProperty}`)}
|
|
2020
2038
|
: ${fallback};
|
|
2021
2039
|
`);
|
|
2022
2040
|
}
|
package/build/options.js
CHANGED
package/build/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.impProto = exports.impFile = exports.getPropertyAccessor = exports.getFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.prefixDisableLinter = exports.maybeAddComment = exports.upperFirst = exports.lowerFirst = exports.singular = exports.fail = exports.readToBuffer = exports.generateIndexFiles = exports.protoFilesToGenerate = void 0;
|
|
3
|
+
exports.impProto = exports.impFile = exports.getPropertyAccessor = exports.propertyNameComposition = exports.getFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.prefixDisableLinter = exports.maybeAddComment = exports.upperFirst = exports.lowerFirst = exports.singular = exports.fail = exports.readToBuffer = exports.generateIndexFiles = exports.protoFilesToGenerate = void 0;
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const ts_poet_1 = require("ts-poet");
|
|
6
6
|
const options_1 = require("./options");
|
|
@@ -181,6 +181,10 @@ class FormattedMethodDescriptor {
|
|
|
181
181
|
}
|
|
182
182
|
exports.FormattedMethodDescriptor = FormattedMethodDescriptor;
|
|
183
183
|
function getFieldJsonName(field, options) {
|
|
184
|
+
// use "json_name" defined in a proto file
|
|
185
|
+
if (options.useJsonName) {
|
|
186
|
+
return field.jsonName;
|
|
187
|
+
}
|
|
184
188
|
// jsonName will be camelCased by the protocol compiler, plus can be overridden by the user,
|
|
185
189
|
// so just use that instead of our own maybeSnakeToCamel
|
|
186
190
|
if (options.snakeToCamel.includes("json")) {
|
|
@@ -195,6 +199,30 @@ function getFieldJsonName(field, options) {
|
|
|
195
199
|
}
|
|
196
200
|
}
|
|
197
201
|
exports.getFieldJsonName = getFieldJsonName;
|
|
202
|
+
function propertyNameComposition(field, options) {
|
|
203
|
+
if (options.useJsonName) {
|
|
204
|
+
const jsonName = field.jsonName;
|
|
205
|
+
return {
|
|
206
|
+
propertyName: jsonName,
|
|
207
|
+
validatedPropertyName: validateObjectProperty(jsonName),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
const propertyName = (0, case_1.maybeSnakeToCamel)(field.name, options);
|
|
211
|
+
return {
|
|
212
|
+
propertyName,
|
|
213
|
+
validatedPropertyName: propertyName,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
exports.propertyNameComposition = propertyNameComposition;
|
|
217
|
+
/**
|
|
218
|
+
* https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/the-dangers-of-square-bracket-notation.md
|
|
219
|
+
*/
|
|
220
|
+
function isValidateObjectProperty(propertyName) {
|
|
221
|
+
return /^[a-zA-Z_$][\w$]*$/.test(propertyName);
|
|
222
|
+
}
|
|
223
|
+
function validateObjectProperty(propertyName) {
|
|
224
|
+
return isValidateObjectProperty(propertyName) ? propertyName : JSON.stringify(propertyName);
|
|
225
|
+
}
|
|
198
226
|
/**
|
|
199
227
|
* Returns a snippet for reading an object's property, such as `foo.bar`, or `foo['bar']` if the property name contains unusual characters.
|
|
200
228
|
* For simplicity, we don't match the ECMA 5/6 rules for valid identifiers exactly, and return array syntax liberally.
|
|
@@ -203,10 +231,9 @@ exports.getFieldJsonName = getFieldJsonName;
|
|
|
203
231
|
* @param optional
|
|
204
232
|
*/
|
|
205
233
|
function getPropertyAccessor(objectName, propertyName, optional = false) {
|
|
206
|
-
|
|
207
|
-
return validIdentifier.test(propertyName)
|
|
234
|
+
return isValidateObjectProperty(propertyName)
|
|
208
235
|
? `${objectName}${optional ? "?" : ""}.${propertyName}`
|
|
209
|
-
: `${objectName}${optional ? "?." : ""}[${
|
|
236
|
+
: `${objectName}${optional ? "?." : ""}[${validateObjectProperty(propertyName)}]`;
|
|
210
237
|
}
|
|
211
238
|
exports.getPropertyAccessor = getPropertyAccessor;
|
|
212
239
|
function impFile(options, spec) {
|