ts-proto 1.161.1 → 1.162.1
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 +94 -78
- package/build/options.js +1 -0
- package/build/utils.js +25 -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 fieldKey = (0, utils_1.safeAccessor)((0, utils_1.getFieldName)(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)}${fieldKey}${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,15 +669,17 @@ 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 =
|
|
673
|
-
|
|
672
|
+
const name = options.useJsonName
|
|
673
|
+
? (0, utils_1.getFieldName)(field, options)
|
|
674
|
+
: (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[oneofIndex].name, ctx.options);
|
|
675
|
+
fields.push((0, ts_poet_1.code) `${(0, utils_1.safeAccessor)(name)}: undefined`);
|
|
674
676
|
}
|
|
675
677
|
continue;
|
|
676
678
|
}
|
|
677
679
|
if (!options.initializeFieldsAsUndefined && (0, types_1.isOptionalProperty)(field, messageDesc.options, options)) {
|
|
678
680
|
continue;
|
|
679
681
|
}
|
|
680
|
-
const
|
|
682
|
+
const fieldKey = (0, utils_1.safeAccessor)((0, utils_1.getFieldName)(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) `${fieldKey}: ${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 fieldName = (0,
|
|
800
|
+
const fieldName = (0, utils_1.getFieldName)(field, options);
|
|
801
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", fieldName);
|
|
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: '${fieldName}', ${fieldName}: ${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 fieldName = (0,
|
|
1028
|
+
const fieldName = (0, utils_1.getFieldName)(field, options);
|
|
1029
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", fieldName);
|
|
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,7 +1119,7 @@ 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
1124
|
throw new Error('a value provided in array field ${fieldName} of type ${fieldType} is too large');
|
|
1119
1125
|
}
|
|
@@ -1126,7 +1132,7 @@ 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
1137
|
throw new Error('a value provided in array field ${fieldName} of type ${fieldType} is too large');
|
|
1132
1138
|
}
|
|
@@ -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,8 @@ 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 fieldName = (0, utils_1.getFieldName)(field, options);
|
|
1473
|
+
const fieldKey = (0, utils_1.safeAccessor)(fieldName);
|
|
1465
1474
|
const jsonName = (0, utils_1.getFieldJsonName)(field, options);
|
|
1466
1475
|
const jsonProperty = (0, utils_1.getPropertyAccessor)("object", jsonName);
|
|
1467
1476
|
const jsonPropertyOptional = (0, utils_1.getPropertyAccessor)("object", jsonName, true);
|
|
@@ -1597,7 +1606,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1597
1606
|
if ((0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field)) {
|
|
1598
1607
|
const fallback = noDefaultValue ? "undefined" : "new Map()";
|
|
1599
1608
|
chunks.push((0, ts_poet_1.code) `
|
|
1600
|
-
${
|
|
1609
|
+
${fieldKey}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1601
1610
|
? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1602
1611
|
acc.set(${i}, ${readSnippet("value")});
|
|
1603
1612
|
return acc;
|
|
@@ -1608,7 +1617,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1608
1617
|
else {
|
|
1609
1618
|
const fallback = noDefaultValue ? "undefined" : "{}";
|
|
1610
1619
|
chunks.push((0, ts_poet_1.code) `
|
|
1611
|
-
${
|
|
1620
|
+
${fieldKey}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1612
1621
|
? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1613
1622
|
acc[${i}] = ${readSnippet("value")};
|
|
1614
1623
|
return acc;
|
|
@@ -1621,12 +1630,12 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1621
1630
|
const fallback = noDefaultValue ? "undefined" : "[]";
|
|
1622
1631
|
const readValueSnippet = readSnippet("e");
|
|
1623
1632
|
if (readValueSnippet.toString() === (0, ts_poet_1.code) `e`.toString()) {
|
|
1624
|
-
chunks.push((0, ts_poet_1.code) `${
|
|
1633
|
+
chunks.push((0, ts_poet_1.code) `${fieldKey}: ${ctx.utils.globalThis}.Array.isArray(${jsonPropertyOptional}) ? [...${jsonProperty}] : [],`);
|
|
1625
1634
|
}
|
|
1626
1635
|
else {
|
|
1627
1636
|
// Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
|
|
1628
1637
|
chunks.push((0, ts_poet_1.code) `
|
|
1629
|
-
${
|
|
1638
|
+
${fieldKey}: ${ctx.utils.globalThis}.Array.isArray(${jsonPropertyOptional}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): ${fallback},
|
|
1630
1639
|
`);
|
|
1631
1640
|
}
|
|
1632
1641
|
}
|
|
@@ -1640,26 +1649,26 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1640
1649
|
chunks.push((0, ts_poet_1.code) `${fieldName}: `);
|
|
1641
1650
|
}
|
|
1642
1651
|
const ternaryIf = (0, ts_poet_1.code) `${ctx.utils.isSet}(${jsonProperty})`;
|
|
1643
|
-
const ternaryThen = (0, ts_poet_1.code) `{ $case: '${fieldName}', ${
|
|
1652
|
+
const ternaryThen = (0, ts_poet_1.code) `{ $case: '${fieldName}', ${fieldKey}: ${readSnippet(`${jsonProperty}`)}`;
|
|
1644
1653
|
chunks.push((0, ts_poet_1.code) `${ternaryIf} ? ${ternaryThen}} : `);
|
|
1645
1654
|
if (field === lastCase) {
|
|
1646
1655
|
chunks.push((0, ts_poet_1.code) `undefined,`);
|
|
1647
1656
|
}
|
|
1648
1657
|
}
|
|
1649
1658
|
else if ((0, types_1.isAnyValueType)(field)) {
|
|
1650
|
-
chunks.push((0, ts_poet_1.code) `${
|
|
1659
|
+
chunks.push((0, ts_poet_1.code) `${fieldKey}: ${ctx.utils.isSet}(${jsonPropertyOptional})
|
|
1651
1660
|
? ${readSnippet(`${jsonProperty}`)}
|
|
1652
1661
|
: undefined,
|
|
1653
1662
|
`);
|
|
1654
1663
|
}
|
|
1655
1664
|
else if ((0, types_1.isStructType)(field)) {
|
|
1656
|
-
chunks.push((0, ts_poet_1.code) `${
|
|
1665
|
+
chunks.push((0, ts_poet_1.code) `${fieldKey}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1657
1666
|
? ${readSnippet(`${jsonProperty}`)}
|
|
1658
1667
|
: undefined,`);
|
|
1659
1668
|
}
|
|
1660
1669
|
else if ((0, types_1.isListValueType)(field)) {
|
|
1661
1670
|
chunks.push((0, ts_poet_1.code) `
|
|
1662
|
-
${
|
|
1671
|
+
${fieldKey}: ${ctx.utils.globalThis}.Array.isArray(${jsonProperty})
|
|
1663
1672
|
? ${readSnippet(`${jsonProperty}`)}
|
|
1664
1673
|
: undefined,
|
|
1665
1674
|
`);
|
|
@@ -1667,7 +1676,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1667
1676
|
else {
|
|
1668
1677
|
const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
|
|
1669
1678
|
chunks.push((0, ts_poet_1.code) `
|
|
1670
|
-
${
|
|
1679
|
+
${fieldKey}: ${ctx.utils.isSet}(${jsonProperty})
|
|
1671
1680
|
? ${readSnippet(`${jsonProperty}`)}
|
|
1672
1681
|
: ${fallback},
|
|
1673
1682
|
`);
|
|
@@ -1703,9 +1712,10 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1703
1712
|
`);
|
|
1704
1713
|
// then add a case for each field
|
|
1705
1714
|
messageDesc.field.forEach((field) => {
|
|
1706
|
-
const fieldName = (0,
|
|
1715
|
+
const fieldName = (0, utils_1.getFieldName)(field, options);
|
|
1707
1716
|
const jsonName = (0, utils_1.getFieldJsonName)(field, options);
|
|
1708
1717
|
const jsonProperty = (0, utils_1.getPropertyAccessor)("obj", jsonName);
|
|
1718
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", fieldName);
|
|
1709
1719
|
const readSnippet = (from) => {
|
|
1710
1720
|
if ((0, types_1.isEnum)(field)) {
|
|
1711
1721
|
const toJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToJSON");
|
|
@@ -1797,9 +1807,9 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1797
1807
|
const i = convertToObjectKey(ctx, messageDesc, field, "k");
|
|
1798
1808
|
if ((0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field)) {
|
|
1799
1809
|
chunks.push((0, ts_poet_1.code) `
|
|
1800
|
-
if (
|
|
1810
|
+
if (${messageProperty}?.size) {
|
|
1801
1811
|
${jsonProperty} = {};
|
|
1802
|
-
|
|
1812
|
+
${messageProperty}.forEach((v, k) => {
|
|
1803
1813
|
${jsonProperty}[${i}] = ${readSnippet("v")};
|
|
1804
1814
|
});
|
|
1805
1815
|
}
|
|
@@ -1807,8 +1817,8 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1807
1817
|
}
|
|
1808
1818
|
else {
|
|
1809
1819
|
chunks.push((0, ts_poet_1.code) `
|
|
1810
|
-
if (
|
|
1811
|
-
const entries = Object.entries(
|
|
1820
|
+
if (${messageProperty}) {
|
|
1821
|
+
const entries = Object.entries(${messageProperty});
|
|
1812
1822
|
if (entries.length > 0) {
|
|
1813
1823
|
${jsonProperty} = {};
|
|
1814
1824
|
entries.forEach(([k, v]) => {
|
|
@@ -1824,28 +1834,30 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1824
1834
|
const transformElement = readSnippet("e");
|
|
1825
1835
|
const maybeMap = transformElement.toCodeString([]) !== "e" ? (0, ts_poet_1.code) `.map(e => ${transformElement})` : "";
|
|
1826
1836
|
chunks.push((0, ts_poet_1.code) `
|
|
1827
|
-
if (
|
|
1828
|
-
${jsonProperty} =
|
|
1837
|
+
if (${messageProperty}?.length) {
|
|
1838
|
+
${jsonProperty} = ${messageProperty}${maybeMap};
|
|
1829
1839
|
}
|
|
1830
1840
|
`);
|
|
1831
1841
|
}
|
|
1832
1842
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
1833
1843
|
// oneofs in a union are only output as `oneof name = ...`
|
|
1834
|
-
const
|
|
1844
|
+
const oneofNameWithMessage = options.useJsonName
|
|
1845
|
+
? messageProperty
|
|
1846
|
+
: (0, utils_1.getPropertyAccessor)("message", (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options));
|
|
1835
1847
|
chunks.push((0, ts_poet_1.code) `
|
|
1836
|
-
if (
|
|
1837
|
-
${jsonProperty} = ${readSnippet(
|
|
1848
|
+
if (${oneofNameWithMessage}?.$case === '${fieldName}') {
|
|
1849
|
+
${jsonProperty} = ${readSnippet(`${oneofNameWithMessage}.${fieldName}`)};
|
|
1838
1850
|
}
|
|
1839
1851
|
`);
|
|
1840
1852
|
}
|
|
1841
1853
|
else {
|
|
1842
1854
|
let emitDefaultValuesForJson = ctx.options.emitDefaultValues.includes("json-methods");
|
|
1843
1855
|
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
|
-
:
|
|
1856
|
+
? (0, types_1.notDefaultCheck)(ctx, field, messageDesc.options, `${messageProperty}`)
|
|
1857
|
+
: `${messageProperty} !== undefined`;
|
|
1846
1858
|
chunks.push((0, ts_poet_1.code) `
|
|
1847
1859
|
if (${check}) {
|
|
1848
|
-
${jsonProperty} = ${readSnippet(
|
|
1860
|
+
${jsonProperty} = ${readSnippet(`${messageProperty}`)};
|
|
1849
1861
|
}
|
|
1850
1862
|
`);
|
|
1851
1863
|
}
|
|
@@ -1891,7 +1903,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1891
1903
|
chunks.push((0, ts_poet_1.code) `const message = ${createBase}${maybeAsAny(options)};`);
|
|
1892
1904
|
// add a check for each incoming field
|
|
1893
1905
|
messageDesc.field.forEach((field) => {
|
|
1894
|
-
const fieldName = (0,
|
|
1906
|
+
const fieldName = (0, utils_1.getFieldName)(field, options);
|
|
1907
|
+
const messageProperty = (0, utils_1.getPropertyAccessor)("message", fieldName);
|
|
1908
|
+
const objectProperty = (0, utils_1.getPropertyAccessor)("object", fieldName);
|
|
1895
1909
|
const readSnippet = (from) => {
|
|
1896
1910
|
if (((0, types_1.isLong)(field) || (0, types_1.isLongValueType)(field)) && options.forceLong === options_1.LongOption.LONG) {
|
|
1897
1911
|
return (0, ts_poet_1.code) `Long.fromValue(${from})`;
|
|
@@ -1962,13 +1976,13 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1962
1976
|
const fieldType = (0, types_1.toTypeName)(ctx, messageDesc, field);
|
|
1963
1977
|
const i = convertFromObjectKey(ctx, messageDesc, field, "key");
|
|
1964
1978
|
const noValueSnippet = noDefaultValue
|
|
1965
|
-
? `(
|
|
1979
|
+
? `(${objectProperty} === undefined || ${objectProperty} === null) ? undefined : `
|
|
1966
1980
|
: "";
|
|
1967
1981
|
if ((0, types_1.shouldGenerateJSMapType)(ctx, messageDesc, field)) {
|
|
1968
1982
|
chunks.push((0, ts_poet_1.code) `
|
|
1969
|
-
|
|
1983
|
+
${messageProperty} = ${noValueSnippet} (() => {
|
|
1970
1984
|
const m = new Map();
|
|
1971
|
-
(
|
|
1985
|
+
(${objectProperty} as ${fieldType} ?? new Map()).forEach((value, key) => {
|
|
1972
1986
|
if (value !== undefined) {
|
|
1973
1987
|
m.set(key, ${readSnippet("value")});
|
|
1974
1988
|
}
|
|
@@ -1979,7 +1993,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1979
1993
|
}
|
|
1980
1994
|
else {
|
|
1981
1995
|
chunks.push((0, ts_poet_1.code) `
|
|
1982
|
-
|
|
1996
|
+
${messageProperty} = ${noValueSnippet} Object.entries(${objectProperty} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1983
1997
|
if (value !== undefined) {
|
|
1984
1998
|
acc[${i}] = ${readSnippet("value")};
|
|
1985
1999
|
}
|
|
@@ -1991,33 +2005,35 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1991
2005
|
else {
|
|
1992
2006
|
const fallback = noDefaultValue ? "undefined" : "[]";
|
|
1993
2007
|
chunks.push((0, ts_poet_1.code) `
|
|
1994
|
-
|
|
2008
|
+
${messageProperty} = ${objectProperty}?.map((e) => ${readSnippet("e")}) || ${fallback};
|
|
1995
2009
|
`);
|
|
1996
2010
|
}
|
|
1997
2011
|
}
|
|
1998
2012
|
else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
|
|
1999
|
-
|
|
2000
|
-
const
|
|
2013
|
+
const oneofName = (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options);
|
|
2014
|
+
const oneofNameWithMessage = (0, utils_1.getPropertyAccessor)("message", oneofName);
|
|
2015
|
+
const oneofNameWithObject = (0, utils_1.getPropertyAccessor)("object", oneofName);
|
|
2016
|
+
const v = readSnippet(`${oneofNameWithObject}.${fieldName}`);
|
|
2001
2017
|
chunks.push((0, ts_poet_1.code) `
|
|
2002
2018
|
if (
|
|
2003
|
-
|
|
2004
|
-
&&
|
|
2005
|
-
&&
|
|
2019
|
+
${oneofNameWithObject}?.$case === '${fieldName}'
|
|
2020
|
+
&& ${oneofNameWithObject}?.${fieldName} !== undefined
|
|
2021
|
+
&& ${oneofNameWithObject}?.${fieldName} !== null
|
|
2006
2022
|
) {
|
|
2007
|
-
|
|
2023
|
+
${oneofNameWithMessage} = { $case: '${fieldName}', ${fieldName}: ${v} };
|
|
2008
2024
|
}
|
|
2009
2025
|
`);
|
|
2010
2026
|
}
|
|
2011
2027
|
else if (readSnippet(`x`).toCodeString([]) == "x") {
|
|
2012
2028
|
// An optimized case of the else below that works when `readSnippet` returns the plain input
|
|
2013
2029
|
const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
|
|
2014
|
-
chunks.push((0, ts_poet_1.code)
|
|
2030
|
+
chunks.push((0, ts_poet_1.code) `${messageProperty} = ${objectProperty} ?? ${fallback};`);
|
|
2015
2031
|
}
|
|
2016
2032
|
else {
|
|
2017
2033
|
const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
|
|
2018
2034
|
chunks.push((0, ts_poet_1.code) `
|
|
2019
|
-
|
|
2020
|
-
? ${readSnippet(
|
|
2035
|
+
${messageProperty} = (${objectProperty} !== undefined && ${objectProperty} !== null)
|
|
2036
|
+
? ${readSnippet(`${objectProperty}`)}
|
|
2021
2037
|
: ${fallback};
|
|
2022
2038
|
`);
|
|
2023
2039
|
}
|
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.safeAccessor = exports.getFieldName = 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,24 @@ function getFieldJsonName(field, options) {
|
|
|
195
199
|
}
|
|
196
200
|
}
|
|
197
201
|
exports.getFieldJsonName = getFieldJsonName;
|
|
202
|
+
function getFieldName(field, options) {
|
|
203
|
+
if (options.useJsonName) {
|
|
204
|
+
return field.jsonName;
|
|
205
|
+
}
|
|
206
|
+
return (0, case_1.maybeSnakeToCamel)(field.name, options);
|
|
207
|
+
}
|
|
208
|
+
exports.getFieldName = getFieldName;
|
|
209
|
+
/**
|
|
210
|
+
* https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/the-dangers-of-square-bracket-notation.md
|
|
211
|
+
*/
|
|
212
|
+
function isValidIdentifier(propertyName) {
|
|
213
|
+
return /^[a-zA-Z_$][\w$]*$/.test(propertyName);
|
|
214
|
+
}
|
|
215
|
+
/** Returns `bar` or `"bar"` if `propertyName` isn't a safe property name. */
|
|
216
|
+
function safeAccessor(propertyName) {
|
|
217
|
+
return isValidIdentifier(propertyName) ? propertyName : JSON.stringify(propertyName);
|
|
218
|
+
}
|
|
219
|
+
exports.safeAccessor = safeAccessor;
|
|
198
220
|
/**
|
|
199
221
|
* Returns a snippet for reading an object's property, such as `foo.bar`, or `foo['bar']` if the property name contains unusual characters.
|
|
200
222
|
* For simplicity, we don't match the ECMA 5/6 rules for valid identifiers exactly, and return array syntax liberally.
|
|
@@ -203,10 +225,9 @@ exports.getFieldJsonName = getFieldJsonName;
|
|
|
203
225
|
* @param optional
|
|
204
226
|
*/
|
|
205
227
|
function getPropertyAccessor(objectName, propertyName, optional = false) {
|
|
206
|
-
|
|
207
|
-
return validIdentifier.test(propertyName)
|
|
228
|
+
return isValidIdentifier(propertyName)
|
|
208
229
|
? `${objectName}${optional ? "?" : ""}.${propertyName}`
|
|
209
|
-
: `${objectName}${optional ? "?." : ""}[${
|
|
230
|
+
: `${objectName}${optional ? "?." : ""}[${safeAccessor(propertyName)}]`;
|
|
210
231
|
}
|
|
211
232
|
exports.getPropertyAccessor = getPropertyAccessor;
|
|
212
233
|
function impFile(options, spec) {
|