ts-proto 1.153.3 → 1.155.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 CHANGED
@@ -728,26 +728,15 @@ Foo.fromJSON({ bar: "" }); // => { bar: '' }
728
728
  Foo.fromJSON({ bar: "baz" }); // => { bar: 'baz' }
729
729
  ```
730
730
 
731
- When writing JSON, `ts-proto` currently does **not** normalize message when converting to JSON, other than omitting unset fields, but it may do so in the future.
731
+ When writing JSON, `ts-proto` normalizes messages by omitting unset fields and fields set to their default values.
732
732
 
733
733
  ```typescript
734
- // Current ts-proto behavior
735
- Foo.toJSON({}); // => { }
736
- Foo.toJSON({ bar: undefined }); // => { }
737
- Foo.toJSON({ bar: "" }); // => { bar: '' } - note: this is the default value, but it's not omitted
738
- Foo.toJSON({ bar: "baz" }); // => { bar: 'baz' }
739
- ```
740
-
741
- ```typescript
742
- // Possible future behavior, where ts-proto would normalize message
743
734
  Foo.toJSON({}); // => { }
744
735
  Foo.toJSON({ bar: undefined }); // => { }
745
736
  Foo.toJSON({ bar: "" }); // => { } - note: omitting the default value, as expected
746
737
  Foo.toJSON({ bar: "baz" }); // => { bar: 'baz' }
747
738
  ```
748
739
 
749
- - Please open an issue if you need this behavior.
750
-
751
740
  # Well-Known Types
752
741
 
753
742
  Protobuf comes with several predefined message definitions, called "[Well-Known Types](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf)".
package/build/main.js CHANGED
@@ -310,29 +310,13 @@ function makeProtobufStructWrapper(options) {
310
310
  function makeLongUtils(options, bytes) {
311
311
  // Regardless of which `forceLong` config option we're using, we always use
312
312
  // the `long` library to either represent or at least sanity-check 64-bit values
313
- const util = (0, utils_1.impFile)(options, "util@protobufjs/minimal");
314
- const configure = (0, utils_1.impFile)(options, "configure@protobufjs/minimal");
315
- // Before esModuleInterop, we had to use 'import * as Long from long` b/c long is
316
- // an `export =` module and exports only the Long constructor (which is callable).
317
- // See https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require.
318
- //
319
- // With esModuleInterop on, `* as Long` is no longer the constructor, it's the module,
320
- // so we want to go back to `import { Long } from long`, which is specifically forbidden
321
- // due to `export =` w/o esModuleInterop.
322
- //
323
- // I.e there is not an import for long that "just works" in both esModuleInterop and
324
- // not esModuleInterop.
325
- const LongImp = options.esModuleInterop ? (0, ts_poet_1.imp)("Long=long") : (0, ts_poet_1.imp)("Long*long");
326
- const disclaimer = options.esModuleInterop
327
- ? ""
328
- : `
329
- // If you get a compile-error about 'Constructor<Long> and ... have no overlap',
330
- // add '--ts_proto_opt=esModuleInterop=true' as a flag when calling 'protoc'.`;
313
+ const util = (0, utils_1.impFile)(options, `util@protobufjs/minimal`);
314
+ const configure = (0, utils_1.impFile)(options, `configure@protobufjs/minimal`);
315
+ const LongImp = (0, ts_poet_1.imp)("Long=long");
331
316
  // Instead of exposing `LongImp` directly, let callers think that they are getting the
332
317
  // `imp(Long)` but really it is that + our long initialization snippet. This means the
333
318
  // initialization code will only be emitted in files that actually use the Long import.
334
319
  const Long = (0, ts_poet_1.conditionalOutput)("Long", (0, ts_poet_1.code) `
335
- ${disclaimer}
336
320
  if (${util}.Long !== ${LongImp}) {
337
321
  ${util}.Long = ${LongImp} as any;
338
322
  ${configure}();
@@ -1662,9 +1646,7 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1662
1646
  const readSnippet = (from) => {
1663
1647
  if ((0, types_1.isEnum)(field)) {
1664
1648
  const toJson = (0, types_1.getEnumMethod)(ctx, field.typeName, "ToJSON");
1665
- return (0, types_1.isWithinOneOf)(field)
1666
- ? (0, ts_poet_1.code) `${from} !== undefined ? ${toJson}(${from}) : undefined`
1667
- : (0, ts_poet_1.code) `${toJson}(${from})`;
1649
+ return (0, ts_poet_1.code) `${toJson}(${from})`;
1668
1650
  }
1669
1651
  else if ((0, types_1.isObjectId)(field) && options.useMongoObjectId) {
1670
1652
  return (0, ts_poet_1.code) `${from}.toString()`;
@@ -1729,19 +1711,13 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1729
1711
  }
1730
1712
  else if ((0, types_1.isMessage)(field) && !(0, types_1.isValueType)(ctx, field) && !(0, types_1.isMapType)(ctx, messageDesc, field)) {
1731
1713
  const type = (0, types_1.basicTypeName)(ctx, field, { keepValueType: true });
1732
- return (0, ts_poet_1.code) `${from} ? ${type}.toJSON(${from}) : ${(0, types_1.defaultValue)(ctx, field)}`;
1714
+ return (0, ts_poet_1.code) `${type}.toJSON(${from})`;
1733
1715
  }
1734
1716
  else if ((0, types_1.isBytes)(field)) {
1735
- if ((0, types_1.isWithinOneOf)(field)) {
1736
- return (0, ts_poet_1.code) `${from} !== undefined ? ${utils.base64FromBytes}(${from}) : undefined`;
1737
- }
1738
- else {
1739
- return (0, ts_poet_1.code) `${utils.base64FromBytes}(${from} !== undefined ? ${from} : ${(0, types_1.defaultValue)(ctx, field)})`;
1740
- }
1717
+ return (0, ts_poet_1.code) `${utils.base64FromBytes}(${from})`;
1741
1718
  }
1742
1719
  else if ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.LONG) {
1743
- const v = (0, types_1.isWithinOneOf)(field) ? "undefined" : (0, types_1.defaultValue)(ctx, field);
1744
- return (0, ts_poet_1.code) `(${from} || ${v}).toString()`;
1720
+ return (0, ts_poet_1.code) `(${from} || ${(0, types_1.defaultValue)(ctx, field)}).toString()`;
1745
1721
  }
1746
1722
  else if ((0, types_1.isLong)(field) && options.forceLong === options_1.LongOption.BIGINT) {
1747
1723
  return (0, ts_poet_1.code) `${from}.toString()`;
@@ -1758,8 +1734,8 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1758
1734
  const i = convertToObjectKey(ctx, messageDesc, field, "k");
1759
1735
  if (ctx.options.useMapType) {
1760
1736
  chunks.push((0, ts_poet_1.code) `
1761
- ${jsonProperty} = {};
1762
- if (message.${fieldName}) {
1737
+ if (message.${fieldName}?.size) {
1738
+ ${jsonProperty} = {};
1763
1739
  message.${fieldName}.forEach((v, k) => {
1764
1740
  ${jsonProperty}[${i}] = ${readSnippet("v")};
1765
1741
  });
@@ -1768,34 +1744,46 @@ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1768
1744
  }
1769
1745
  else {
1770
1746
  chunks.push((0, ts_poet_1.code) `
1771
- ${jsonProperty} = {};
1772
- if (message.${fieldName}) {
1773
- Object.entries(message.${fieldName}).forEach(([k, v]) => {
1774
- ${jsonProperty}[${i}] = ${readSnippet("v")};
1775
- });
1747
+ if (message.${fieldName}) {
1748
+ const entries = Object.entries(message.${fieldName});
1749
+ if (entries.length > 0) {
1750
+ ${jsonProperty} = {};
1751
+ entries.forEach(([k, v]) => {
1752
+ ${jsonProperty}[${i}] = ${readSnippet("v")};
1753
+ });
1754
+ }
1776
1755
  }
1777
1756
  `);
1778
1757
  }
1779
1758
  }
1780
1759
  else if ((0, types_1.isRepeated)(field)) {
1781
1760
  // Arrays might need their elements transformed
1761
+ const transformElement = readSnippet("e");
1762
+ const maybeMap = transformElement.toCodeString([]) !== "e" ? (0, ts_poet_1.code) `.map(e => ${transformElement})` : "";
1782
1763
  chunks.push((0, ts_poet_1.code) `
1783
- if (message.${fieldName}) {
1784
- ${jsonProperty} = message.${fieldName}.map(e => ${readSnippet("e")});
1785
- } else {
1786
- ${jsonProperty} = [];
1764
+ if (message.${fieldName}?.length) {
1765
+ ${jsonProperty} = message.${fieldName}${maybeMap};
1787
1766
  }
1788
1767
  `);
1789
1768
  }
1790
1769
  else if ((0, types_1.isWithinOneOfThatShouldBeUnion)(options, field)) {
1791
1770
  // oneofs in a union are only output as `oneof name = ...`
1792
1771
  const oneofName = (0, case_1.maybeSnakeToCamel)(messageDesc.oneofDecl[field.oneofIndex].name, options);
1793
- const v = readSnippet(`message.${oneofName}?.${fieldName}`);
1794
- chunks.push((0, ts_poet_1.code) `message.${oneofName}?.$case === '${fieldName}' && (${jsonProperty} = ${v});`);
1772
+ chunks.push((0, ts_poet_1.code) `
1773
+ if (message.${oneofName}?.$case === '${fieldName}') {
1774
+ ${jsonProperty} = ${readSnippet(`message.${oneofName}.${fieldName}`)};
1775
+ }
1776
+ `);
1795
1777
  }
1796
1778
  else {
1797
- const v = readSnippet(`message.${fieldName}`);
1798
- chunks.push((0, ts_poet_1.code) `message.${fieldName} !== undefined && (${jsonProperty} = ${v});`);
1779
+ const check = ((0, types_1.isScalar)(field) || (0, types_1.isEnum)(field)) && !(0, types_1.isWithinOneOf)(field)
1780
+ ? (0, types_1.notDefaultCheck)(ctx, field, messageDesc.options, `message.${fieldName}`)
1781
+ : `message.${fieldName} !== undefined`;
1782
+ chunks.push((0, ts_poet_1.code) `
1783
+ if (${check}) {
1784
+ ${jsonProperty} = ${readSnippet(`message.${fieldName}`)};
1785
+ }
1786
+ `);
1799
1787
  }
1800
1788
  });
1801
1789
  chunks.push((0, ts_poet_1.code) `return obj;`);
package/build/options.js CHANGED
@@ -202,12 +202,15 @@ function parseParameter(parameter) {
202
202
  function parseParamValue(value) {
203
203
  return value === "true" ? true : value === "false" ? false : value;
204
204
  }
205
- function getTsPoetOpts(_options) {
206
- const imports = ["protobufjs/minimal" + _options.importSuffix];
205
+ function getTsPoetOpts(options) {
206
+ const { importSuffix, esModuleInterop } = options;
207
+ const pbjs = "protobufjs/minimal" + importSuffix;
207
208
  return {
208
209
  prefix: `/* eslint-disable */`,
209
210
  dprintOptions: { preferSingleLine: true, lineWidth: 120 },
210
- ...(_options.esModuleInterop ? { forceDefaultImport: imports } : { forceModuleImport: imports }),
211
+ forceRequireImport: esModuleInterop ? [] : ["long"],
212
+ forceDefaultImport: esModuleInterop ? [pbjs] : [],
213
+ forceModuleImport: esModuleInterop ? [] : [pbjs],
211
214
  };
212
215
  }
213
216
  exports.getTsPoetOpts = getTsPoetOpts;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.153.3",
3
+ "version": "1.155.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",
@@ -67,8 +67,8 @@
67
67
  "dependencies": {
68
68
  "case-anything": "^2.1.13",
69
69
  "protobufjs": "^7.2.4",
70
- "ts-poet": "^6.4.1",
71
- "ts-proto-descriptors": "1.12.0"
70
+ "ts-poet": "^6.5.0",
71
+ "ts-proto-descriptors": "1.13.0"
72
72
  },
73
73
  "packageManager": "yarn@3.6.0"
74
74
  }