ts-proto 1.161.1 → 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 +87 -70
- 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
|
@@ -615,10 +615,10 @@ function generateInterfaceDeclaration(ctx, fullName, messageDesc, sourceInfo, fu
|
|
|
615
615
|
}
|
|
616
616
|
const info = sourceInfo.lookup(sourceInfo_1.Fields.message.field, index);
|
|
617
617
|
(0, utils_1.maybeAddComment)(info, chunks, (_a = fieldDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
|
|
618
|
-
const
|
|
618
|
+
const { validatedPropertyName } = (0, utils_1.propertyNameComposition)(fieldDesc, options);
|
|
619
619
|
const isOptional = (0, types_1.isOptionalProperty)(fieldDesc, messageDesc.options, options);
|
|
620
620
|
const type = (0, types_1.toTypeName)(ctx, messageDesc, fieldDesc, isOptional);
|
|
621
|
-
chunks.push((0, ts_poet_1.code) `${maybeReadonly(options)}${
|
|
621
|
+
chunks.push((0, ts_poet_1.code) `${maybeReadonly(options)}${validatedPropertyName}${isOptional ? "?" : ""}: ${type}, `);
|
|
622
622
|
});
|
|
623
623
|
if (ctx.options.unknownFields) {
|
|
624
624
|
chunks.push((0, ts_poet_1.code) `_unknownFields?: {[key: number]: Uint8Array[]} | undefined,`);
|
|
@@ -669,7 +669,9 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
669
669
|
const { oneofIndex } = field;
|
|
670
670
|
if (!processedOneofs.has(oneofIndex)) {
|
|
671
671
|
processedOneofs.add(oneofIndex);
|
|
672
|
-
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);
|
|
673
675
|
fields.push((0, ts_poet_1.code) `${name}: undefined`);
|
|
674
676
|
}
|
|
675
677
|
continue;
|
|
@@ -677,7 +679,7 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
677
679
|
if (!options.initializeFieldsAsUndefined && (0, types_1.isOptionalProperty)(field, messageDesc.options, options)) {
|
|
678
680
|
continue;
|
|
679
681
|
}
|
|
680
|
-
const
|
|
682
|
+
const { validatedPropertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
681
683
|
const val = (0, types_1.isWithinOneOf)(field)
|
|
682
684
|
? "undefined"
|
|
683
685
|
: (0, types_1.isMapType)(ctx, messageDesc, field)
|
|
@@ -687,7 +689,7 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
687
689
|
: (0, types_1.isRepeated)(field)
|
|
688
690
|
? "[]"
|
|
689
691
|
: (0, types_1.defaultValue)(ctx, field);
|
|
690
|
-
fields.push((0, ts_poet_1.code) `${
|
|
692
|
+
fields.push((0, ts_poet_1.code) `${validatedPropertyName}: ${val}`);
|
|
691
693
|
}
|
|
692
694
|
if ((0, options_1.addTypeToMessages)(options)) {
|
|
693
695
|
fields.unshift((0, ts_poet_1.code) `$type: '${fullTypeName}'`);
|
|
@@ -795,7 +797,8 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
795
797
|
`);
|
|
796
798
|
// add a case for each incoming field
|
|
797
799
|
messageDesc.field.forEach((field) => {
|
|
798
|
-
const
|
|
800
|
+
const { propertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
801
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", propertyName);
|
|
799
802
|
chunks.push((0, ts_poet_1.code) `case ${field.number}:`);
|
|
800
803
|
const tag = ((field.number << 3) | (0, types_1.basicWireType)(field.type)) >>> 0;
|
|
801
804
|
const tagCheck = (0, ts_poet_1.code) `
|
|
@@ -816,15 +819,15 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
816
819
|
const generateMapType = (0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field);
|
|
817
820
|
let valueSetterSnippet;
|
|
818
821
|
if (generateMapType) {
|
|
819
|
-
valueSetterSnippet =
|
|
822
|
+
valueSetterSnippet = `${messageProperty}${maybeNonNullAssertion}.set(${varName}.key, ${varName}.value)`;
|
|
820
823
|
}
|
|
821
824
|
else {
|
|
822
|
-
valueSetterSnippet =
|
|
825
|
+
valueSetterSnippet = `${messageProperty}${maybeNonNullAssertion}[${varName}.key] = ${varName}.value`;
|
|
823
826
|
}
|
|
824
827
|
const initializerSnippet = initializerNecessary
|
|
825
828
|
? `
|
|
826
|
-
if (
|
|
827
|
-
|
|
829
|
+
if (${messageProperty} === undefined) {
|
|
830
|
+
${messageProperty} = ${generateMapType ? "new Map()" : "{}"};
|
|
828
831
|
}`
|
|
829
832
|
: "";
|
|
830
833
|
chunks.push((0, ts_poet_1.code) `
|
|
@@ -839,15 +842,15 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
839
842
|
else {
|
|
840
843
|
const initializerSnippet = initializerNecessary
|
|
841
844
|
? `
|
|
842
|
-
if (
|
|
843
|
-
|
|
845
|
+
if (${messageProperty} === undefined) {
|
|
846
|
+
${messageProperty} = [];
|
|
844
847
|
}`
|
|
845
848
|
: "";
|
|
846
849
|
if ((0, types_1.packedType)(field.type) === undefined) {
|
|
847
850
|
chunks.push((0, ts_poet_1.code) `
|
|
848
851
|
${tagCheck}
|
|
849
852
|
${initializerSnippet}
|
|
850
|
-
|
|
853
|
+
${messageProperty}${maybeNonNullAssertion}.push(${readSnippet});
|
|
851
854
|
`);
|
|
852
855
|
}
|
|
853
856
|
else {
|
|
@@ -855,7 +858,7 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
855
858
|
chunks.push((0, ts_poet_1.code) `
|
|
856
859
|
if (tag === ${tag}) {
|
|
857
860
|
${initializerSnippet}
|
|
858
|
-
|
|
861
|
+
${messageProperty}${maybeNonNullAssertion}.push(${readSnippet});
|
|
859
862
|
|
|
860
863
|
continue;
|
|
861
864
|
}
|
|
@@ -864,7 +867,7 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
864
867
|
${initializerSnippet}
|
|
865
868
|
const end2 = reader.uint32() + reader.pos;
|
|
866
869
|
while (reader.pos < end2) {
|
|
867
|
-
|
|
870
|
+
${messageProperty}${maybeNonNullAssertion}.push(${readSnippet});
|
|
868
871
|
}
|
|
869
872
|
|
|
870
873
|
continue;
|
|
@@ -876,16 +879,18 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
876
879
|
}
|
|
877
880
|
}
|
|
878
881
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
879
|
-
|
|
882
|
+
const oneofNameWithMessage = options.useJsonName
|
|
883
|
+
? messageProperty
|
|
884
|
+
: (0, utils_1.getPropertyAccessor)("message", (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options));
|
|
880
885
|
chunks.push((0, ts_poet_1.code) `
|
|
881
886
|
${tagCheck}
|
|
882
|
-
|
|
887
|
+
${oneofNameWithMessage} = { $case: '${propertyName}', ${propertyName}: ${readSnippet} };
|
|
883
888
|
`);
|
|
884
889
|
}
|
|
885
890
|
else {
|
|
886
891
|
chunks.push((0, ts_poet_1.code) `
|
|
887
892
|
${tagCheck}
|
|
888
|
-
|
|
893
|
+
${messageProperty} = ${readSnippet};
|
|
889
894
|
`);
|
|
890
895
|
}
|
|
891
896
|
if (!(0, types_1.isRepeated)(field) || (0, types_1.packedType)(field.type) === undefined) {
|
|
@@ -1020,7 +1025,8 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1020
1025
|
.reduce((result, field) => ((result[field.oneofIndex] || (result[field.oneofIndex] = [])).push(field), result), {});
|
|
1021
1026
|
// then add a case for each field
|
|
1022
1027
|
messageDesc.field.forEach((field) => {
|
|
1023
|
-
const
|
|
1028
|
+
const { propertyName, validatedPropertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
1029
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", propertyName);
|
|
1024
1030
|
// get a generic writer.doSomething based on the basic type
|
|
1025
1031
|
const writeSnippet = getEncodeWriteSnippet(ctx, field);
|
|
1026
1032
|
const isOptional = (0, types_1.isOptionalProperty)(field, messageDesc.options, options);
|
|
@@ -1039,14 +1045,14 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1039
1045
|
const optionalAlternative = isOptional ? (useMapType ? " || new Map()" : " || {}") : "";
|
|
1040
1046
|
if (useMapType) {
|
|
1041
1047
|
chunks.push((0, ts_poet_1.code) `
|
|
1042
|
-
(
|
|
1048
|
+
(${messageProperty}${optionalAlternative}).forEach((value, key) => {
|
|
1043
1049
|
${entryWriteSnippet}
|
|
1044
1050
|
});
|
|
1045
1051
|
`);
|
|
1046
1052
|
}
|
|
1047
1053
|
else {
|
|
1048
1054
|
chunks.push((0, ts_poet_1.code) `
|
|
1049
|
-
Object.entries(
|
|
1055
|
+
Object.entries(${messageProperty}${optionalAlternative}).forEach(([key, value]) => {
|
|
1050
1056
|
${entryWriteSnippet}
|
|
1051
1057
|
});
|
|
1052
1058
|
`);
|
|
@@ -1054,13 +1060,13 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1054
1060
|
}
|
|
1055
1061
|
else if ((0, types_1.packedType)(field.type) === undefined) {
|
|
1056
1062
|
const listWriteSnippet = (0, ts_poet_1.code) `
|
|
1057
|
-
for (const v of
|
|
1063
|
+
for (const v of ${messageProperty}) {
|
|
1058
1064
|
${writeSnippet("v!")};
|
|
1059
1065
|
}
|
|
1060
1066
|
`;
|
|
1061
1067
|
if (isOptional) {
|
|
1062
1068
|
chunks.push((0, ts_poet_1.code) `
|
|
1063
|
-
if (
|
|
1069
|
+
if (${messageProperty} !== undefined && ${messageProperty}.length !== 0) {
|
|
1064
1070
|
${listWriteSnippet}
|
|
1065
1071
|
}
|
|
1066
1072
|
`);
|
|
@@ -1078,14 +1084,14 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1078
1084
|
const toNumber = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToNumber");
|
|
1079
1085
|
const listWriteSnippet = (0, ts_poet_1.code) `
|
|
1080
1086
|
writer.uint32(${tag}).fork();
|
|
1081
|
-
for (const v of
|
|
1087
|
+
for (const v of ${messageProperty}) {
|
|
1082
1088
|
writer.${(0, types_1.toReaderCall)(field)}(${toNumber}(v));
|
|
1083
1089
|
}
|
|
1084
1090
|
writer.ldelim();
|
|
1085
1091
|
`;
|
|
1086
1092
|
if (isOptional) {
|
|
1087
1093
|
chunks.push((0, ts_poet_1.code) `
|
|
1088
|
-
if (
|
|
1094
|
+
if (${messageProperty} !== undefined && ${messageProperty}.length !== 0) {
|
|
1089
1095
|
${listWriteSnippet}
|
|
1090
1096
|
}
|
|
1091
1097
|
`);
|
|
@@ -1100,7 +1106,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1100
1106
|
const rhs = (x) => ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT ? `${x}.toString()` : x);
|
|
1101
1107
|
let listWriteSnippet = (0, ts_poet_1.code) `
|
|
1102
1108
|
writer.uint32(${tag}).fork();
|
|
1103
|
-
for (const v of
|
|
1109
|
+
for (const v of ${messageProperty}) {
|
|
1104
1110
|
writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
|
|
1105
1111
|
}
|
|
1106
1112
|
writer.ldelim();
|
|
@@ -1113,9 +1119,9 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1113
1119
|
case "sfixed64":
|
|
1114
1120
|
listWriteSnippet = (0, ts_poet_1.code) `
|
|
1115
1121
|
writer.uint32(${tag}).fork();
|
|
1116
|
-
for (const v of
|
|
1122
|
+
for (const v of ${messageProperty}) {
|
|
1117
1123
|
if (BigInt.asIntN(64, v) !== v) {
|
|
1118
|
-
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');
|
|
1119
1125
|
}
|
|
1120
1126
|
writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
|
|
1121
1127
|
}
|
|
@@ -1126,9 +1132,9 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1126
1132
|
case "fixed64":
|
|
1127
1133
|
listWriteSnippet = (0, ts_poet_1.code) `
|
|
1128
1134
|
writer.uint32(${tag}).fork();
|
|
1129
|
-
for (const v of
|
|
1135
|
+
for (const v of ${messageProperty}) {
|
|
1130
1136
|
if (BigInt.asUintN(64, v) !== v) {
|
|
1131
|
-
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');
|
|
1132
1138
|
}
|
|
1133
1139
|
writer.${(0, types_1.toReaderCall)(field)}(${rhs("v")});
|
|
1134
1140
|
}
|
|
@@ -1141,7 +1147,7 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1141
1147
|
}
|
|
1142
1148
|
if (isOptional) {
|
|
1143
1149
|
chunks.push((0, ts_poet_1.code) `
|
|
1144
|
-
if (
|
|
1150
|
+
if (${messageProperty} !== undefined && ${messageProperty}.length !== 0) {
|
|
1145
1151
|
${listWriteSnippet}
|
|
1146
1152
|
}
|
|
1147
1153
|
`);
|
|
@@ -1154,13 +1160,15 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1154
1160
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
1155
1161
|
if (!processedOneofs.has(field.oneofIndex)) {
|
|
1156
1162
|
processedOneofs.add(field.oneofIndex);
|
|
1157
|
-
const
|
|
1158
|
-
|
|
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) {`);
|
|
1159
1167
|
for (const oneOfField of oneOfFieldsDict[field.oneofIndex]) {
|
|
1160
1168
|
const writeSnippet = getEncodeWriteSnippet(ctx, oneOfField);
|
|
1161
1169
|
const oneOfFieldName = (0, case_1.maybeSnakeToCamel)(oneOfField.name, ctx.options);
|
|
1162
1170
|
chunks.push((0, ts_poet_1.code) `case "${oneOfFieldName}":
|
|
1163
|
-
${writeSnippet(
|
|
1171
|
+
${writeSnippet(`${oneofNameWithMessage}.${oneOfFieldName}`)};
|
|
1164
1172
|
break;`);
|
|
1165
1173
|
}
|
|
1166
1174
|
chunks.push((0, ts_poet_1.code) `}`);
|
|
@@ -1169,27 +1177,27 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
1169
1177
|
else if ((0, types_1.isWithinOneOf)(field)) {
|
|
1170
1178
|
// Oneofs don't have a default value check b/c they need to denote which-oneof presence
|
|
1171
1179
|
chunks.push((0, ts_poet_1.code) `
|
|
1172
|
-
if (
|
|
1173
|
-
${writeSnippet(
|
|
1180
|
+
if (${messageProperty} !== undefined) {
|
|
1181
|
+
${writeSnippet(`${messageProperty}`)};
|
|
1174
1182
|
}
|
|
1175
1183
|
`);
|
|
1176
1184
|
}
|
|
1177
1185
|
else if ((0, types_1.isMessage)(field)) {
|
|
1178
1186
|
chunks.push((0, ts_poet_1.code) `
|
|
1179
|
-
if (
|
|
1180
|
-
${writeSnippet(
|
|
1187
|
+
if (${messageProperty} !== undefined) {
|
|
1188
|
+
${writeSnippet(`${messageProperty}`)};
|
|
1181
1189
|
}
|
|
1182
1190
|
`);
|
|
1183
1191
|
}
|
|
1184
1192
|
else if ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) {
|
|
1185
1193
|
chunks.push((0, ts_poet_1.code) `
|
|
1186
|
-
if (${(0, types_1.notDefaultCheck)(ctx, field, messageDesc.options,
|
|
1187
|
-
${writeSnippet(
|
|
1194
|
+
if (${(0, types_1.notDefaultCheck)(ctx, field, messageDesc.options, `${messageProperty}`)}) {
|
|
1195
|
+
${writeSnippet(`${messageProperty}`)};
|
|
1188
1196
|
}
|
|
1189
1197
|
`);
|
|
1190
1198
|
}
|
|
1191
1199
|
else {
|
|
1192
|
-
chunks.push((0, ts_poet_1.code) `${writeSnippet(
|
|
1200
|
+
chunks.push((0, ts_poet_1.code) `${writeSnippet(`${messageProperty}`)};`);
|
|
1193
1201
|
}
|
|
1194
1202
|
});
|
|
1195
1203
|
if (options.unknownFields) {
|
|
@@ -1461,7 +1469,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1461
1469
|
// add a check for each incoming field
|
|
1462
1470
|
messageDesc.field.forEach((field) => {
|
|
1463
1471
|
var _a;
|
|
1464
|
-
const fieldName = (0,
|
|
1472
|
+
const { validatedPropertyName: fieldName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
1465
1473
|
const jsonName = (0, utils_1.getFieldJsonName)(field, options);
|
|
1466
1474
|
const jsonProperty = (0, utils_1.getPropertyAccessor)("object", jsonName);
|
|
1467
1475
|
const jsonPropertyOptional = (0, utils_1.getPropertyAccessor)("object", jsonName, true);
|
|
@@ -1703,9 +1711,10 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1703
1711
|
`);
|
|
1704
1712
|
// then add a case for each field
|
|
1705
1713
|
messageDesc.field.forEach((field) => {
|
|
1706
|
-
const fieldName = (0,
|
|
1714
|
+
const { validatedPropertyName: fieldName, propertyName } = (0, utils_1.propertyNameComposition)(field, options);
|
|
1707
1715
|
const jsonName = (0, utils_1.getFieldJsonName)(field, options);
|
|
1708
1716
|
const jsonProperty = (0, utils_1.getPropertyAccessor)("obj", jsonName);
|
|
1717
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", propertyName);
|
|
1709
1718
|
const readSnippet = (from) => {
|
|
1710
1719
|
if ((0, types_1.isEnum)(field)) {
|
|
1711
1720
|
const toJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToJSON");
|
|
@@ -1797,9 +1806,9 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1797
1806
|
const i = convertToObjectKey(ctx, messageDesc, field, "k");
|
|
1798
1807
|
if ((0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field)) {
|
|
1799
1808
|
chunks.push((0, ts_poet_1.code) `
|
|
1800
|
-
if (
|
|
1809
|
+
if (${messageProperty}?.size) {
|
|
1801
1810
|
${jsonProperty} = {};
|
|
1802
|
-
|
|
1811
|
+
${messageProperty}.forEach((v, k) => {
|
|
1803
1812
|
${jsonProperty}[${i}] = ${readSnippet("v")};
|
|
1804
1813
|
});
|
|
1805
1814
|
}
|
|
@@ -1807,8 +1816,8 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1807
1816
|
}
|
|
1808
1817
|
else {
|
|
1809
1818
|
chunks.push((0, ts_poet_1.code) `
|
|
1810
|
-
if (
|
|
1811
|
-
const entries = Object.entries(
|
|
1819
|
+
if (${messageProperty}) {
|
|
1820
|
+
const entries = Object.entries(${messageProperty});
|
|
1812
1821
|
if (entries.length > 0) {
|
|
1813
1822
|
${jsonProperty} = {};
|
|
1814
1823
|
entries.forEach(([k, v]) => {
|
|
@@ -1824,28 +1833,30 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1824
1833
|
const transformElement = readSnippet("e");
|
|
1825
1834
|
const maybeMap = transformElement.toCodeString([]) !== "e" ? (0, ts_poet_1.code) `.map(e => ${transformElement})` : "";
|
|
1826
1835
|
chunks.push((0, ts_poet_1.code) `
|
|
1827
|
-
if (
|
|
1828
|
-
${jsonProperty} =
|
|
1836
|
+
if (${messageProperty}?.length) {
|
|
1837
|
+
${jsonProperty} = ${messageProperty}${maybeMap};
|
|
1829
1838
|
}
|
|
1830
1839
|
`);
|
|
1831
1840
|
}
|
|
1832
1841
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
1833
1842
|
// oneofs in a union are only output as `oneof name = ...`
|
|
1834
|
-
const
|
|
1843
|
+
const oneofNameWithMessage = options.useJsonName
|
|
1844
|
+
? messageProperty
|
|
1845
|
+
: (0, utils_1.getPropertyAccessor)("message", (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options));
|
|
1835
1846
|
chunks.push((0, ts_poet_1.code) `
|
|
1836
|
-
if (
|
|
1837
|
-
${jsonProperty} = ${readSnippet(
|
|
1847
|
+
if (${oneofNameWithMessage}?.$case === '${fieldName}') {
|
|
1848
|
+
${jsonProperty} = ${readSnippet(`${oneofNameWithMessage}.${fieldName}`)};
|
|
1838
1849
|
}
|
|
1839
1850
|
`);
|
|
1840
1851
|
}
|
|
1841
1852
|
else {
|
|
1842
1853
|
let emitDefaultValuesForJson = ctx.options.emitDefaultValues.includes("json-methods");
|
|
1843
1854
|
const check = ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) && !((0, types_1.isWithinOneOf)(field) || emitDefaultValuesForJson)
|
|
1844
|
-
? (0, types_1.notDefaultCheck)(ctx, field, messageDesc.options,
|
|
1845
|
-
:
|
|
1855
|
+
? (0, types_1.notDefaultCheck)(ctx, field, messageDesc.options, `${messageProperty}`)
|
|
1856
|
+
: `${messageProperty} !== undefined`;
|
|
1846
1857
|
chunks.push((0, ts_poet_1.code) `
|
|
1847
1858
|
if (${check}) {
|
|
1848
|
-
${jsonProperty} = ${readSnippet(
|
|
1859
|
+
${jsonProperty} = ${readSnippet(`${messageProperty}`)};
|
|
1849
1860
|
}
|
|
1850
1861
|
`);
|
|
1851
1862
|
}
|
|
@@ -1891,7 +1902,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1891
1902
|
chunks.push((0, ts_poet_1.code) `const message = ${createBase}${maybeAsAny(options)};`);
|
|
1892
1903
|
// add a check for each incoming field
|
|
1893
1904
|
messageDesc.field.forEach((field) => {
|
|
1894
|
-
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);
|
|
1895
1908
|
const readSnippet = (from) => {
|
|
1896
1909
|
if (((0, types_1.isLong)(field) || (0, types_1.isLongValueType)(field)) && options.forceLong === options_1.LongOption.LONG) {
|
|
1897
1910
|
return (0, ts_poet_1.code) `Long.fromValue(${from})`;
|
|
@@ -1962,13 +1975,13 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1962
1975
|
const fieldType = (0, types_1.toTypeName)(ctx, messageDesc, field);
|
|
1963
1976
|
const i = convertFromObjectKey(ctx, messageDesc, field, "key");
|
|
1964
1977
|
const noValueSnippet = noDefaultValue
|
|
1965
|
-
? `(
|
|
1978
|
+
? `(${objectProperty} === undefined || ${objectProperty} === null) ? undefined : `
|
|
1966
1979
|
: "";
|
|
1967
1980
|
if ((0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field)) {
|
|
1968
1981
|
chunks.push((0, ts_poet_1.code) `
|
|
1969
|
-
|
|
1982
|
+
${messageProperty} = ${noValueSnippet} (() => {
|
|
1970
1983
|
const m = new Map();
|
|
1971
|
-
(
|
|
1984
|
+
(${objectProperty} as ${fieldType} ?? new Map()).forEach((value, key) => {
|
|
1972
1985
|
if (value !== undefined) {
|
|
1973
1986
|
m.set(key, ${readSnippet("value")});
|
|
1974
1987
|
}
|
|
@@ -1979,7 +1992,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1979
1992
|
}
|
|
1980
1993
|
else {
|
|
1981
1994
|
chunks.push((0, ts_poet_1.code) `
|
|
1982
|
-
|
|
1995
|
+
${messageProperty} = ${noValueSnippet} Object.entries(${objectProperty} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1983
1996
|
if (value !== undefined) {
|
|
1984
1997
|
acc[${i}] = ${readSnippet("value")};
|
|
1985
1998
|
}
|
|
@@ -1991,33 +2004,37 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1991
2004
|
else {
|
|
1992
2005
|
const fallback = noDefaultValue ? "undefined" : "[]";
|
|
1993
2006
|
chunks.push((0, ts_poet_1.code) `
|
|
1994
|
-
|
|
2007
|
+
${messageProperty} = ${objectProperty}?.map((e) => ${readSnippet("e")}) || ${fallback};
|
|
1995
2008
|
`);
|
|
1996
2009
|
}
|
|
1997
2010
|
}
|
|
1998
2011
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
1999
|
-
|
|
2000
|
-
|
|
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}`);
|
|
2001
2018
|
chunks.push((0, ts_poet_1.code) `
|
|
2002
2019
|
if (
|
|
2003
|
-
|
|
2004
|
-
&&
|
|
2005
|
-
&&
|
|
2020
|
+
${oneofNameWithObject}?.$case === '${propertyName}'
|
|
2021
|
+
&& ${oneofNameWithObject}?.${propertyName} !== undefined
|
|
2022
|
+
&& ${oneofNameWithObject}?.${propertyName} !== null
|
|
2006
2023
|
) {
|
|
2007
|
-
|
|
2024
|
+
${oneofNameWithMessage} = { $case: '${propertyName}', ${propertyName}: ${v} };
|
|
2008
2025
|
}
|
|
2009
2026
|
`);
|
|
2010
2027
|
}
|
|
2011
2028
|
else if (readSnippet(`x`).toCodeString([]) == "x") {
|
|
2012
2029
|
// An optimized case of the else below that works when `readSnippet` returns the plain input
|
|
2013
2030
|
const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
|
|
2014
|
-
chunks.push((0, ts_poet_1.code)
|
|
2031
|
+
chunks.push((0, ts_poet_1.code) `${messageProperty} = ${objectProperty} ?? ${fallback};`);
|
|
2015
2032
|
}
|
|
2016
2033
|
else {
|
|
2017
2034
|
const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
|
|
2018
2035
|
chunks.push((0, ts_poet_1.code) `
|
|
2019
|
-
|
|
2020
|
-
? ${readSnippet(
|
|
2036
|
+
${messageProperty} = (${objectProperty} !== undefined && ${objectProperty} !== null)
|
|
2037
|
+
? ${readSnippet(`${objectProperty}`)}
|
|
2021
2038
|
: ${fallback};
|
|
2022
2039
|
`);
|
|
2023
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) {
|