ts-proto 1.144.1 → 1.145.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.
Files changed (2) hide show
  1. package/build/main.js +70 -20
  2. package/package.json +1 -1
package/build/main.js CHANGED
@@ -957,10 +957,10 @@ function generateEncode(ctx, fullName, messageDesc) {
957
957
  }
958
958
  `
959
959
  : writeSnippet(`{ ${maybeTypeField} key: key as any, value }`);
960
- const optionalAlternative = isOptional ? " || {}" : "";
960
+ const optionalAlternative = isOptional ? (ctx.options.useMapType ? " || new Map()" : " || {}") : "";
961
961
  if (ctx.options.useMapType) {
962
962
  chunks.push((0, ts_poet_1.code) `
963
- message.${fieldName}${optionalAlternative}.forEach((value, key) => {
963
+ (message.${fieldName}${optionalAlternative}).forEach((value, key) => {
964
964
  ${entryWriteSnippet}
965
965
  });
966
966
  `);
@@ -1212,6 +1212,9 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1212
1212
  else if ((0, types_1.isLong)(valueField) && options.forceLong === options_1.LongOption.LONG) {
1213
1213
  return (0, ts_poet_1.code) `Long.fromValue(${from} as Long | string)`;
1214
1214
  }
1215
+ else if ((0, types_1.isLong)(valueField) && options.forceLong === options_1.LongOption.BIGINT) {
1216
+ return (0, ts_poet_1.code) `BigInt(${from} as string | number | bigint | boolean)`;
1217
+ }
1215
1218
  else if ((0, types_1.isEnum)(valueField)) {
1216
1219
  const fromJson = (0, types_1.getEnumMethod)(ctx, valueField.typeName, "FromJSON");
1217
1220
  return (0, ts_poet_1.code) `${fromJson}(${from})`;
@@ -1250,6 +1253,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1250
1253
  throw new Error(`Unhandled field ${field}`);
1251
1254
  }
1252
1255
  };
1256
+ const noDefaultValue = !options.initializeFieldsAsUndefined && (0, types_1.isOptionalProperty)(field, messageDesc.options, options);
1253
1257
  // and then use the snippet to handle repeated fields if necessary
1254
1258
  if ((_a = canonicalFromJson[fullTypeName]) === null || _a === void 0 ? void 0 : _a[fieldName]) {
1255
1259
  chunks.push((0, ts_poet_1.code) `${fieldName}: ${canonicalFromJson[fullTypeName][fieldName]("object")},`);
@@ -1257,29 +1261,32 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1257
1261
  else if ((0, types_1.isRepeated)(field)) {
1258
1262
  if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
1259
1263
  const fieldType = (0, types_1.toTypeName)(ctx, messageDesc, field);
1260
- const i = maybeCastToNumber(ctx, messageDesc, field, "key");
1264
+ const i = convertFromObjectKey(ctx, messageDesc, field, "key");
1261
1265
  if (ctx.options.useMapType) {
1266
+ const fallback = noDefaultValue ? "undefined" : "new Map()";
1262
1267
  chunks.push((0, ts_poet_1.code) `
1263
1268
  ${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
1264
1269
  ? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
1265
1270
  acc.set(${i}, ${readSnippet("value")});
1266
1271
  return acc;
1267
1272
  }, new Map())
1268
- : new Map(),
1273
+ : ${fallback},
1269
1274
  `);
1270
1275
  }
1271
1276
  else {
1277
+ const fallback = noDefaultValue ? "undefined" : "{}";
1272
1278
  chunks.push((0, ts_poet_1.code) `
1273
1279
  ${fieldName}: ${ctx.utils.isObject}(${jsonProperty})
1274
1280
  ? Object.entries(${jsonProperty}).reduce<${fieldType}>((acc, [key, value]) => {
1275
1281
  acc[${i}] = ${readSnippet("value")};
1276
1282
  return acc;
1277
1283
  }, {})
1278
- : {},
1284
+ : ${fallback},
1279
1285
  `);
1280
1286
  }
1281
1287
  }
1282
1288
  else {
1289
+ const fallback = noDefaultValue ? "undefined" : "[]";
1283
1290
  const readValueSnippet = readSnippet("e");
1284
1291
  if (readValueSnippet.toString() === (0, ts_poet_1.code) `e`.toString()) {
1285
1292
  chunks.push((0, ts_poet_1.code) `${fieldName}: Array.isArray(${jsonPropertyOptional}) ? [...${jsonProperty}] : [],`);
@@ -1287,7 +1294,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1287
1294
  else {
1288
1295
  // Explicit `any` type required to make TS with noImplicitAny happy. `object` is also `any` here.
1289
1296
  chunks.push((0, ts_poet_1.code) `
1290
- ${fieldName}: Array.isArray(${jsonPropertyOptional}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): [],
1297
+ ${fieldName}: Array.isArray(${jsonPropertyOptional}) ? ${jsonProperty}.map((e: any) => ${readValueSnippet}): ${fallback},
1291
1298
  `);
1292
1299
  }
1293
1300
  }
@@ -1326,7 +1333,7 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1326
1333
  `);
1327
1334
  }
1328
1335
  else {
1329
- const fallback = (0, types_1.isWithinOneOf)(field) ? "undefined" : (0, types_1.defaultValue)(ctx, field);
1336
+ const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
1330
1337
  chunks.push((0, ts_poet_1.code) `
1331
1338
  ${fieldName}: ${ctx.utils.isSet}(${jsonProperty})
1332
1339
  ? ${readSnippet(`${jsonProperty}`)}
@@ -1463,12 +1470,13 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1463
1470
  };
1464
1471
  if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
1465
1472
  // Maps might need their values transformed, i.e. bytes --> base64
1473
+ const i = convertToObjectKey(ctx, messageDesc, field, "k");
1466
1474
  if (ctx.options.useMapType) {
1467
1475
  chunks.push((0, ts_poet_1.code) `
1468
1476
  ${jsonProperty} = {};
1469
1477
  if (message.${fieldName}) {
1470
1478
  message.${fieldName}.forEach((v, k) => {
1471
- ${jsonProperty}[k] = ${readSnippet("v")};
1479
+ ${jsonProperty}[${i}] = ${readSnippet("v")};
1472
1480
  });
1473
1481
  }
1474
1482
  `);
@@ -1478,7 +1486,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1478
1486
  ${jsonProperty} = {};
1479
1487
  if (message.${fieldName}) {
1480
1488
  Object.entries(message.${fieldName}).forEach(([k, v]) => {
1481
- ${jsonProperty}[k] = ${readSnippet("v")};
1489
+ ${jsonProperty}[${i}] = ${readSnippet("v")};
1482
1490
  });
1483
1491
  }
1484
1492
  `);
@@ -1572,6 +1580,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1572
1580
  else if ((0, types_1.isLong)(valueField) && options.forceLong === options_1.LongOption.LONG) {
1573
1581
  return (0, ts_poet_1.code) `Long.fromValue(${from})`;
1574
1582
  }
1583
+ else if ((0, types_1.isLong)(valueField) && options.forceLong === options_1.LongOption.BIGINT) {
1584
+ return (0, ts_poet_1.code) `BigInt(${from} as string | number | bigint | boolean)`;
1585
+ }
1575
1586
  else {
1576
1587
  const cstr = (0, case_1.capitalize)(valueType.toCodeString([]));
1577
1588
  return (0, ts_poet_1.code) `${cstr}(${from})`;
@@ -1607,18 +1618,22 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1607
1618
  throw new Error(`Unhandled field ${field}`);
1608
1619
  }
1609
1620
  };
1621
+ const noDefaultValue = !options.initializeFieldsAsUndefined && (0, types_1.isOptionalProperty)(field, messageDesc.options, options);
1610
1622
  // and then use the snippet to handle repeated fields if necessary
1611
1623
  if ((0, types_1.isRepeated)(field)) {
1612
1624
  if ((0, types_1.isMapType)(ctx, messageDesc, field)) {
1613
1625
  const fieldType = (0, types_1.toTypeName)(ctx, messageDesc, field);
1614
- const i = maybeCastToNumber(ctx, messageDesc, field, "key");
1626
+ const i = convertFromObjectKey(ctx, messageDesc, field, "key");
1627
+ const noValueSnippet = noDefaultValue
1628
+ ? `(object.${fieldName} === undefined || object.${fieldName} === null) ? undefined : `
1629
+ : "";
1615
1630
  if (ctx.options.useMapType) {
1616
1631
  chunks.push((0, ts_poet_1.code) `
1617
- message.${fieldName} = (() => {
1632
+ message.${fieldName} = ${noValueSnippet} (() => {
1618
1633
  const m = new Map();
1619
1634
  (object.${fieldName} as ${fieldType} ?? new Map()).forEach((value, key) => {
1620
1635
  if (value !== undefined) {
1621
- m.set(${i}, ${readSnippet("value")});
1636
+ m.set(key, ${readSnippet("value")});
1622
1637
  }
1623
1638
  });
1624
1639
  return m;
@@ -1627,7 +1642,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1627
1642
  }
1628
1643
  else {
1629
1644
  chunks.push((0, ts_poet_1.code) `
1630
- message.${fieldName} = Object.entries(object.${fieldName} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
1645
+ message.${fieldName} = ${noValueSnippet} Object.entries(object.${fieldName} ?? {}).reduce<${fieldType}>((acc, [key, value]) => {
1631
1646
  if (value !== undefined) {
1632
1647
  acc[${i}] = ${readSnippet("value")};
1633
1648
  }
@@ -1637,8 +1652,9 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1637
1652
  }
1638
1653
  }
1639
1654
  else {
1655
+ const fallback = noDefaultValue ? "undefined" : "[]";
1640
1656
  chunks.push((0, ts_poet_1.code) `
1641
- message.${fieldName} = object.${fieldName}?.map((e) => ${readSnippet("e")}) || [];
1657
+ message.${fieldName} = object.${fieldName}?.map((e) => ${readSnippet("e")}) || ${fallback};
1642
1658
  `);
1643
1659
  }
1644
1660
  }
@@ -1657,11 +1673,11 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1657
1673
  }
1658
1674
  else if (readSnippet(`x`).toCodeString([]) == "x") {
1659
1675
  // An optimized case of the else below that works when `readSnippet` returns the plain input
1660
- const fallback = (0, types_1.isWithinOneOf)(field) ? "undefined" : (0, types_1.defaultValue)(ctx, field);
1676
+ const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
1661
1677
  chunks.push((0, ts_poet_1.code) `message.${fieldName} = object.${fieldName} ?? ${fallback};`);
1662
1678
  }
1663
1679
  else {
1664
- const fallback = (0, types_1.isWithinOneOf)(field) ? "undefined" : (0, types_1.defaultValue)(ctx, field);
1680
+ const fallback = (0, types_1.isWithinOneOf)(field) || noDefaultValue ? "undefined" : (0, types_1.defaultValue)(ctx, field);
1665
1681
  chunks.push((0, ts_poet_1.code) `
1666
1682
  message.${fieldName} = (object.${fieldName} !== undefined && object.${fieldName} !== null)
1667
1683
  ? ${readSnippet(`object.${fieldName}`)}
@@ -1675,13 +1691,47 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1675
1691
  return (0, ts_poet_1.joinCode)(chunks, { on: "\n" });
1676
1692
  }
1677
1693
  exports.contextTypeVar = "Context extends DataLoaders";
1678
- function maybeCastToNumber(ctx, messageDesc, field, variableName) {
1679
- const { keyType } = (0, types_1.detectMapType)(ctx, messageDesc, field);
1694
+ function convertFromObjectKey(ctx, messageDesc, field, variableName) {
1695
+ const { keyType, keyField } = (0, types_1.detectMapType)(ctx, messageDesc, field);
1680
1696
  if (keyType.toCodeString([]) === "string") {
1681
- return variableName;
1697
+ return (0, ts_poet_1.code) `${variableName}`;
1698
+ }
1699
+ else if ((0, types_1.isLong)(keyField) && ctx.options.useMapType) {
1700
+ if (ctx.options.forceLong === options_1.LongOption.LONG) {
1701
+ return (0, ts_poet_1.code) `${(0, case_1.capitalize)(keyType.toCodeString([]))}.fromValue(${variableName})`;
1702
+ }
1703
+ else if (ctx.options.forceLong === options_1.LongOption.BIGINT) {
1704
+ return (0, ts_poet_1.code) `BigInt(${variableName})`;
1705
+ }
1706
+ else if (ctx.options.forceLong === options_1.LongOption.STRING) {
1707
+ return (0, ts_poet_1.code) `String(${variableName})`;
1708
+ }
1709
+ else {
1710
+ return (0, ts_poet_1.code) `Number(${variableName})`;
1711
+ }
1712
+ }
1713
+ else {
1714
+ return (0, ts_poet_1.code) `Number(${variableName})`;
1715
+ }
1716
+ }
1717
+ function convertToObjectKey(ctx, messageDesc, field, variableName) {
1718
+ const { keyType, keyField } = (0, types_1.detectMapType)(ctx, messageDesc, field);
1719
+ if (keyType.toCodeString([]) === "string") {
1720
+ return (0, ts_poet_1.code) `${variableName}`;
1721
+ }
1722
+ else if ((0, types_1.isLong)(keyField) && ctx.options.useMapType) {
1723
+ if (ctx.options.forceLong === options_1.LongOption.LONG) {
1724
+ return (0, ts_poet_1.code) `${ctx.utils.longToNumber}(${variableName})`;
1725
+ }
1726
+ else if (ctx.options.forceLong === options_1.LongOption.BIGINT) {
1727
+ return (0, ts_poet_1.code) `${variableName}.toString()`;
1728
+ }
1729
+ else {
1730
+ return (0, ts_poet_1.code) `${variableName}`;
1731
+ }
1682
1732
  }
1683
1733
  else {
1684
- return `Number(${variableName})`;
1734
+ return (0, ts_poet_1.code) `${variableName}`;
1685
1735
  }
1686
1736
  }
1687
1737
  function maybeReadonly(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.144.1",
3
+ "version": "1.145.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",