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 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
- message.${fieldName}${maybeNonNullAssertion}[${varName}.key] = ${varName}.value;
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
- chunks.push((0, ts_poet_1.code) `
826
- Object.entries(message.${fieldName}${optionalAlternative}).forEach(([key, value]) => {
827
- ${entryWriteSnippet}
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
- chunks.push((0, ts_poet_1.code) `
1103
- ${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
1104
- ? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
1105
- acc[${i}] = ${readSnippet("value")};
1106
- return acc;
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
- chunks.push((0, ts_poet_1.code) `
1290
- ${jsonProperty} = {};
1291
- if (message.${fieldName}) {
1292
- Object.entries(message.${fieldName}).forEach(([k, v]) => {
1293
- ${jsonProperty}[k] = ${readSnippet("v")};
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
- chunks.push((0, ts_poet_1.code) `
1412
- message.${fieldName} = Object.entries(object.${fieldName} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
1413
- if (value !== undefined) {
1414
- acc[${i}] = ${readSnippet("value")};
1415
- }
1416
- return acc;
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
@@ -72,6 +72,7 @@ function defaultOptions() {
72
72
  useJsonWireFormat: false,
73
73
  useNumericEnumForJson: false,
74
74
  initializeFieldsAsUndefined: true,
75
+ useMapType: false,
75
76
  M: {},
76
77
  };
77
78
  }
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}[]`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.128.0",
3
+ "version": "1.129.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",