ts-proto 1.107.0 → 1.108.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.108.0](https://github.com/stephenh/ts-proto/compare/v1.107.0...v1.108.0) (2022-03-07)
2
+
3
+
4
+ ### Features
5
+
6
+ * represent field masks as `string[]` ([#525](https://github.com/stephenh/ts-proto/issues/525)) ([903b216](https://github.com/stephenh/ts-proto/commit/903b216238db025e24ec3cfb2d20063aec1a40ed))
7
+
1
8
  # [1.107.0](https://github.com/stephenh/ts-proto/compare/v1.106.2...v1.107.0) (2022-03-04)
2
9
 
3
10
 
package/README.markdown CHANGED
@@ -622,24 +622,19 @@ Their interpretation is defined by the Protobuf specification, and libraries are
622
622
 
623
623
  `ts-proto` currently automatically converts these messages to their corresponding native types.
624
624
 
625
- - Wrapper Types:
626
-
627
- * [google.protobuf.DoubleValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#DoubleValue) ⇆ `number | undefined`
628
- * [google.protobuf.FloatValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#FloatValue) ⇆ `number | undefined`
629
- * [google.protobuf.Int64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Int64Value) ⇆ `number | undefined`
630
- * [google.protobuf.UInt64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#UInt64Value) ⇆ `number | undefined`
631
- * [google.protobuf.Int32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Int32Value) ⇆ `number | undefined`
632
- * [google.protobuf.UInt32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#UInt32Value) ⇆ `number | undefined`
633
- * [google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#BoolValue) ⇆ `boolean | undefined`
634
- * [google.protobuf.StringValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#StringValue) ⇆ `string | undefined`
635
- * [google.protobuf.BytesValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.BytesValue) ⇆ `Uint8Array | undefined`
636
-
637
- - JSON Types (Struct Types):
638
-
639
- * [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Value) ⇆ `any | undefined` (i.e. `number | string | boolean | null | array | object`)
640
- * [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#ListValue) ⇆ `any[]`
641
- * [google.protobuf.Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Struct) ⇆ `{ [key: string]: any } | undefined`
642
- * [google.protobuf.FieldMask](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask) ⇆ `string[]` (only in the JSON, `FieldMask` is still a message)
625
+ * [google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#boolvalue) ⇆ `boolean`
626
+ * [google.protobuf.BytesValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#bytesvalue) ⇆ `Uint8Array`
627
+ * [google.protobuf.DoubleValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#doublevalue) ⇆ `number`
628
+ * [google.protobuf.FieldMask](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask) ⇆ `string[]`
629
+ * [google.protobuf.FloatValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#floatvalue) ⇆ `number`
630
+ * [google.protobuf.Int32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#int32value) ⇆ `number`
631
+ * [google.protobuf.Int64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#int64value) ⇆ `number`
632
+ * [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#listvalue) ⇆ `any[]`
633
+ * [google.protobuf.UInt32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#uint32value) ⇆ `number`
634
+ * [google.protobuf.UInt64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#uint64value) ⇆ `number`
635
+ * [google.protobuf.StringValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#stringvalue) ⇆ `string`
636
+ * [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#value) ⇆ `any` (i.e. `number | string | boolean | null | array | object`)
637
+ * [google.protobuf.Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#struct) ⇆ `{ [key: string]: any }`
643
638
 
644
639
  ## Wrapper Types
645
640
 
package/build/main.js CHANGED
@@ -80,8 +80,8 @@ function generateFile(ctx, fileDesc) {
80
80
  staticMembers.push(generateDecode(ctx, fullName, message));
81
81
  }
82
82
  if (options.outputJsonMethods) {
83
- staticMembers.push(generateFromJson(ctx, fullName, message));
84
- staticMembers.push(generateToJson(ctx, fullName, message));
83
+ staticMembers.push(generateFromJson(ctx, fullName, fullTypeName, message));
84
+ staticMembers.push(generateToJson(ctx, fullName, fullTypeName, message));
85
85
  }
86
86
  if (options.outputPartialMethods) {
87
87
  staticMembers.push(generateFromPartial(ctx, fullName, message));
@@ -604,7 +604,7 @@ function generateDecode(ctx, fullName, messageDesc) {
604
604
  else if (types_1.isValueType(ctx, field)) {
605
605
  const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
606
606
  const unwrap = (decodedValue) => {
607
- if (types_1.isListValueType(field) || types_1.isStructType(field) || types_1.isAnyValueType(field)) {
607
+ if (types_1.isListValueType(field) || types_1.isStructType(field) || types_1.isAnyValueType(field) || types_1.isFieldMaskType(field)) {
608
608
  return ts_poet_1.code `${type}.unwrap(${decodedValue})`;
609
609
  }
610
610
  return ts_poet_1.code `${decodedValue}.value`;
@@ -729,7 +729,7 @@ function generateEncode(ctx, fullName, messageDesc) {
729
729
  const maybeTypeField = options.outputTypeRegistry ? `$type: '${field.typeName.slice(1)}',` : '';
730
730
  const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
731
731
  const wrappedValue = (place) => {
732
- if (types_1.isAnyValueType(field) || types_1.isListValueType(field) || types_1.isStructType(field)) {
732
+ if (types_1.isAnyValueType(field) || types_1.isListValueType(field) || types_1.isStructType(field) || types_1.isFieldMaskType(field)) {
733
733
  return ts_poet_1.code `${type}.wrap(${place})`;
734
734
  }
735
735
  return ts_poet_1.code `{${maybeTypeField} value: ${place}!}`;
@@ -887,7 +887,7 @@ function generateEncode(ctx, fullName, messageDesc) {
887
887
  * This is very similar to decode, we loop through looking for properties, with
888
888
  * a few special cases for https://developers.google.com/protocol-buffers/docs/proto3#json.
889
889
  * */
890
- function generateFromJson(ctx, fullName, messageDesc) {
890
+ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
891
891
  const { options, utils, typeMap } = ctx;
892
892
  const chunks = [];
893
893
  // create the basic function declaration
@@ -899,8 +899,18 @@ function generateFromJson(ctx, fullName, messageDesc) {
899
899
  chunks.push(ts_poet_1.code `$type: ${fullName}.$type,`);
900
900
  }
901
901
  const oneofFieldsCases = messageDesc.oneofDecl.map((oneof, oneofIndex) => messageDesc.field.filter(types_1.isWithinOneOf).filter((field) => field.oneofIndex === oneofIndex));
902
+ const canonicalFromJson = {
903
+ ['google.protobuf.FieldMask']: {
904
+ paths: (from) => ts_poet_1.code `typeof(${from}) === 'string'
905
+ ? ${from}.split(",").filter(Boolean)
906
+ : Array.isArray(${from}?.paths)
907
+ ? ${from}.paths.map(String)
908
+ : []`,
909
+ },
910
+ };
902
911
  // add a check for each incoming field
903
912
  messageDesc.field.forEach((field) => {
913
+ var _a;
904
914
  const fieldName = case_1.maybeSnakeToCamel(field.name, options);
905
915
  const jsonName = utils_1.getFieldJsonName(field, options);
906
916
  const jsonProperty = utils_1.getPropertyAccessor('object', jsonName);
@@ -944,7 +954,8 @@ function generateFromJson(ctx, fullName, messageDesc) {
944
954
  return ts_poet_1.code `${from}`;
945
955
  }
946
956
  else if (types_1.isFieldMaskType(field)) {
947
- return ts_poet_1.code `{paths: ${from}.split(",")}`;
957
+ const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
958
+ return ts_poet_1.code `${type}.unwrap(${type}.fromJSON(${from}))`;
948
959
  }
949
960
  else if (types_1.isListValueType(field)) {
950
961
  return ts_poet_1.code `[...${from}]`;
@@ -1017,7 +1028,10 @@ function generateFromJson(ctx, fullName, messageDesc) {
1017
1028
  }
1018
1029
  };
1019
1030
  // and then use the snippet to handle repeated fields if necessary
1020
- if (types_1.isRepeated(field)) {
1031
+ if ((_a = canonicalFromJson[fullTypeName]) === null || _a === void 0 ? void 0 : _a[fieldName]) {
1032
+ chunks.push(ts_poet_1.code `${fieldName}: ${canonicalFromJson[fullTypeName][fieldName]('object')},`);
1033
+ }
1034
+ else if (types_1.isRepeated(field)) {
1021
1035
  if (types_1.isMapType(ctx, messageDesc, field)) {
1022
1036
  const fieldType = types_1.toTypeName(ctx, messageDesc, field);
1023
1037
  const i = maybeCastToNumber(ctx, messageDesc, field, 'key');
@@ -1090,9 +1104,24 @@ function generateFromJson(ctx, fullName, messageDesc) {
1090
1104
  chunks.push(ts_poet_1.code `}`);
1091
1105
  return ts_poet_1.joinCode(chunks, { on: '\n' });
1092
1106
  }
1093
- function generateToJson(ctx, fullName, messageDesc) {
1107
+ function generateCanonicalToJson(fullName, fullProtobufTypeName) {
1108
+ if (types_1.isFieldMaskTypeName(fullProtobufTypeName)) {
1109
+ return ts_poet_1.code `
1110
+ toJSON(message: ${fullName}): string {
1111
+ return message.paths.join(',');
1112
+ }
1113
+ `;
1114
+ }
1115
+ return undefined;
1116
+ }
1117
+ function generateToJson(ctx, fullName, fullProtobufTypeName, messageDesc) {
1094
1118
  const { options, utils, typeMap } = ctx;
1095
1119
  const chunks = [];
1120
+ const canonicalToJson = generateCanonicalToJson(fullName, fullProtobufTypeName);
1121
+ if (canonicalToJson) {
1122
+ chunks.push(canonicalToJson);
1123
+ return ts_poet_1.joinCode(chunks, { on: '\n' });
1124
+ }
1096
1125
  // create the basic function declaration
1097
1126
  chunks.push(ts_poet_1.code `
1098
1127
  toJSON(${messageDesc.field.length > 0 ? 'message' : '_'}: ${fullName}): unknown {
@@ -1165,7 +1194,8 @@ function generateToJson(ctx, fullName, messageDesc) {
1165
1194
  return ts_poet_1.code `${from}`;
1166
1195
  }
1167
1196
  else if (types_1.isFieldMaskType(field)) {
1168
- return ts_poet_1.code `${from}.paths.join()`;
1197
+ const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
1198
+ return ts_poet_1.code `${type}.toJSON(${type}.wrap(${from}))`;
1169
1199
  }
1170
1200
  else if (types_1.isMessage(field) && !types_1.isValueType(ctx, field) && !types_1.isMapType(ctx, messageDesc, field)) {
1171
1201
  const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
@@ -1431,6 +1461,11 @@ function generateWrap(ctx, fullProtoTypeName) {
1431
1461
  return result;
1432
1462
  }`);
1433
1463
  }
1464
+ if (types_1.isFieldMaskTypeName(fullProtoTypeName)) {
1465
+ chunks.push(ts_poet_1.code `wrap(paths: string[]): FieldMask {
1466
+ return {paths: paths};
1467
+ }`);
1468
+ }
1434
1469
  return chunks;
1435
1470
  }
1436
1471
  function generateUnwrap(ctx, fullProtoTypeName) {
@@ -1488,6 +1523,11 @@ function generateUnwrap(ctx, fullProtoTypeName) {
1488
1523
  return message.values;
1489
1524
  }`);
1490
1525
  }
1526
+ if (types_1.isFieldMaskTypeName(fullProtoTypeName)) {
1527
+ chunks.push(ts_poet_1.code `unwrap(message: FieldMask): string[] {
1528
+ return message.paths;
1529
+ }`);
1530
+ }
1491
1531
  return chunks;
1492
1532
  }
1493
1533
  exports.contextTypeVar = 'Context extends DataLoaders';
package/build/types.js CHANGED
@@ -458,6 +458,8 @@ function valueTypeName(ctx, typeName) {
458
458
  return ts_poet_1.code `any`;
459
459
  case '.google.protobuf.Struct':
460
460
  return ts_poet_1.code `{[key: string]: any}`;
461
+ case '.google.protobuf.FieldMask':
462
+ return ts_poet_1.code `string[]`;
461
463
  default:
462
464
  return undefined;
463
465
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.107.0",
3
+ "version": "1.108.0",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",
@@ -11,6 +11,7 @@
11
11
  "build": "yarn tsc",
12
12
  "build:test": "yarn proto2bin && yarn proto2pbjs && yarn bin2ts",
13
13
  "build:test:local": "yarn proto2bin:local && yarn proto2pbjs:local && yarn bin2ts:local",
14
+ "prepare": "yarn build",
14
15
  "proto2bin": "docker-compose run --rm protoc update-bins.sh",
15
16
  "proto2bin-node": "docker-compose run --rm node update-bins.sh",
16
17
  "proto2pbjs": "docker-compose run --rm protoc pbjs.sh",