ts-proto 1.128.0 → 1.129.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/CHANGELOG.md +7 -0
- package/README.markdown +4 -0
- package/build/main.js +84 -31
- package/build/options.js +1 -0
- package/build/types.js +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.129.0](https://github.com/stephenh/ts-proto/compare/v1.128.0...v1.129.0) (2022-10-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* support `useMapType` option ([#686](https://github.com/stephenh/ts-proto/issues/686)) ([f2e80ab](https://github.com/stephenh/ts-proto/commit/f2e80ab3ecc3a438ecbd88b2170b8119ebadfcd3))
|
|
7
|
+
|
|
1
8
|
# [1.128.0](https://github.com/stephenh/ts-proto/compare/v1.127.0...v1.128.0) (2022-10-13)
|
|
2
9
|
|
|
3
10
|
|
package/README.markdown
CHANGED
|
@@ -458,6 +458,10 @@ Generated code will be placed in the Gradle build directory.
|
|
|
458
458
|
- **Note**: Uses are accummulated, so multiple values are expected in the form of `--ts_proto_opt=M... --ts_proto_opt=M...` (one `ts_proto_opt` per mapping).
|
|
459
459
|
- **Note**: Proto files that match mapped imports **will not be generated**.
|
|
460
460
|
|
|
461
|
+
- With `--ts_proto_opt=useMapType=true`, the generated code for protobuf `map<key_type, value_type>` will become `Map<key_type, value_type>` that uses JavaScript Map type.
|
|
462
|
+
|
|
463
|
+
The default behavior is `useMapType=false`, which makes it generate the code for protobuf `map<key_type, value_type` with the key-value pair like `{[key: key_type]: value_type}`.
|
|
464
|
+
|
|
461
465
|
### NestJS Support
|
|
462
466
|
|
|
463
467
|
We have a great way of working together with [nestjs](https://docs.nestjs.com/microservices/grpc). `ts-proto` generates `interfaces` and `decorators` for you controller, client. For more information see the [nestjs readme](NESTJS.markdown).
|
package/build/main.js
CHANGED
|
@@ -589,7 +589,9 @@ function generateBaseInstanceFactory(ctx, fullName, messageDesc, fullTypeName) {
|
|
|
589
589
|
const val = (0, types_1.isWithinOneOf)(field)
|
|
590
590
|
? "undefined"
|
|
591
591
|
: (0, types_1.isMapType)(ctx, messageDesc, field)
|
|
592
|
-
?
|
|
592
|
+
? ctx.options.useMapType
|
|
593
|
+
? "new Map()"
|
|
594
|
+
: "{}"
|
|
593
595
|
: (0, types_1.isRepeated)(field)
|
|
594
596
|
? "[]"
|
|
595
597
|
: (0, types_1.defaultValue)(ctx, field);
|
|
@@ -698,10 +700,13 @@ function generateDecode(ctx, fullName, messageDesc) {
|
|
|
698
700
|
if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
|
|
699
701
|
// We need a unique const within the `cast` statement
|
|
700
702
|
const varName = `entry${field.number}`;
|
|
703
|
+
const valueSetterSnippet = ctx.options.useMapType
|
|
704
|
+
? `message.${fieldName}${maybeNonNullAssertion}.set(${varName}.key, ${varName}.value)`
|
|
705
|
+
: `message.${fieldName}${maybeNonNullAssertion}[${varName}.key] = ${varName}.value`;
|
|
701
706
|
chunks.push((0, ts_poet_1.code) `
|
|
702
707
|
const ${varName} = ${readSnippet};
|
|
703
708
|
if (${varName}.value !== undefined) {
|
|
704
|
-
|
|
709
|
+
${valueSetterSnippet};
|
|
705
710
|
}
|
|
706
711
|
`);
|
|
707
712
|
}
|
|
@@ -822,11 +827,20 @@ function generateEncode(ctx, fullName, messageDesc) {
|
|
|
822
827
|
`
|
|
823
828
|
: writeSnippet(`{ ${maybeTypeField} key: key as any, value }`);
|
|
824
829
|
const optionalAlternative = isOptional ? " || {}" : "";
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
${
|
|
828
|
-
|
|
829
|
-
|
|
830
|
+
if (ctx.options.useMapType) {
|
|
831
|
+
chunks.push((0, ts_poet_1.code) `
|
|
832
|
+
message.${fieldName}${optionalAlternative}.forEach((value, key) => {
|
|
833
|
+
${entryWriteSnippet}
|
|
834
|
+
});
|
|
835
|
+
`);
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
chunks.push((0, ts_poet_1.code) `
|
|
839
|
+
Object.entries(message.${fieldName}${optionalAlternative}).forEach(([key, value]) => {
|
|
840
|
+
${entryWriteSnippet}
|
|
841
|
+
});
|
|
842
|
+
`);
|
|
843
|
+
}
|
|
830
844
|
}
|
|
831
845
|
else if ((0, types_1.packedType)(field.type) === undefined) {
|
|
832
846
|
const listWriteSnippet = (0, ts_poet_1.code) `
|
|
@@ -1099,14 +1113,26 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
|
|
|
1099
1113
|
if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
|
|
1100
1114
|
const fieldType = (0, types_1.toTypeName)(ctx, messageDesc, field);
|
|
1101
1115
|
const i = maybeCastToNumber(ctx, messageDesc, field, "key");
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1116
|
+
if (ctx.options.useMapType) {
|
|
1117
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1118
|
+
${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1119
|
+
? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1120
|
+
acc.set(${i}, ${readSnippet("value")});
|
|
1121
|
+
return acc;
|
|
1122
|
+
}, new Map())
|
|
1123
|
+
: new Map(),
|
|
1124
|
+
`);
|
|
1125
|
+
}
|
|
1126
|
+
else {
|
|
1127
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1128
|
+
${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
|
|
1129
|
+
? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1130
|
+
acc[${i}] = ${readSnippet("value")};
|
|
1131
|
+
return acc;
|
|
1132
|
+
}, {})
|
|
1133
|
+
: {},
|
|
1134
|
+
`);
|
|
1135
|
+
}
|
|
1110
1136
|
}
|
|
1111
1137
|
else {
|
|
1112
1138
|
const readValueSnippet = readSnippet("e");
|
|
@@ -1286,14 +1312,26 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
|
|
|
1286
1312
|
};
|
|
1287
1313
|
if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
|
|
1288
1314
|
// Maps might need their values transformed, i.e. bytes --> base64
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1315
|
+
if (ctx.options.useMapType) {
|
|
1316
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1317
|
+
${jsonProperty} = {};
|
|
1318
|
+
if (message.${fieldName}) {
|
|
1319
|
+
message.${fieldName}.forEach((v, k) => {
|
|
1320
|
+
${jsonProperty}[k] = ${readSnippet("v")};
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
`);
|
|
1324
|
+
}
|
|
1325
|
+
else {
|
|
1326
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1327
|
+
${jsonProperty} = {};
|
|
1328
|
+
if (message.${fieldName}) {
|
|
1329
|
+
Object.entries(message.${fieldName}).forEach(([k, v]) => {
|
|
1330
|
+
${jsonProperty}[k] = ${readSnippet("v")};
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
`);
|
|
1334
|
+
}
|
|
1297
1335
|
}
|
|
1298
1336
|
else if ((0, types_1.isRepeated)(field)) {
|
|
1299
1337
|
// Arrays might need their elements transformed
|
|
@@ -1408,14 +1446,29 @@ function generateFromPartial(ctx, fullName, messageDesc) {
|
|
|
1408
1446
|
if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
|
|
1409
1447
|
const fieldType = (0, types_1.toTypeName)(ctx, messageDesc, field);
|
|
1410
1448
|
const i = maybeCastToNumber(ctx, messageDesc, field, "key");
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1449
|
+
if (ctx.options.useMapType) {
|
|
1450
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1451
|
+
message.${fieldName} = (() => {
|
|
1452
|
+
const m = new Map();
|
|
1453
|
+
(object.${fieldName} as ${fieldType} ?? new Map()).forEach((value, key) => {
|
|
1454
|
+
if (value !== undefined) {
|
|
1455
|
+
m.set(${i}, ${readSnippet("value")});
|
|
1456
|
+
}
|
|
1457
|
+
});
|
|
1458
|
+
return m;
|
|
1459
|
+
})();
|
|
1460
|
+
`);
|
|
1461
|
+
}
|
|
1462
|
+
else {
|
|
1463
|
+
chunks.push((0, ts_poet_1.code) `
|
|
1464
|
+
message.${fieldName} = Object.entries(object.${fieldName} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
|
|
1465
|
+
if (value !== undefined) {
|
|
1466
|
+
acc[${i}] = ${readSnippet("value")};
|
|
1467
|
+
}
|
|
1468
|
+
return acc;
|
|
1469
|
+
}, {});
|
|
1470
|
+
`);
|
|
1471
|
+
}
|
|
1419
1472
|
}
|
|
1420
1473
|
else {
|
|
1421
1474
|
chunks.push((0, ts_poet_1.code) `
|
package/build/options.js
CHANGED
package/build/types.js
CHANGED
|
@@ -557,6 +557,9 @@ function toTypeName(ctx, messageDesc, field) {
|
|
|
557
557
|
const mapType = detectMapType(ctx, messageDesc, field);
|
|
558
558
|
if (mapType) {
|
|
559
559
|
const { keyType, valueType } = mapType;
|
|
560
|
+
if (ctx.options.useMapType) {
|
|
561
|
+
return (0, ts_poet_1.code) `Map<${keyType}, ${valueType}>`;
|
|
562
|
+
}
|
|
560
563
|
return (0, ts_poet_1.code) `{ [key: ${keyType} ]: ${valueType} }`;
|
|
561
564
|
}
|
|
562
565
|
return (0, ts_poet_1.code) `${type}[]`;
|