ts-proto 1.103.0 → 1.105.1

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,36 @@
1
+ ## [1.105.1](https://github.com/stephenh/ts-proto/compare/v1.105.0...v1.105.1) (2022-02-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * generate canonical JSON encoding for FieldMasks ([#510](https://github.com/stephenh/ts-proto/issues/510)) ([0ec4e97](https://github.com/stephenh/ts-proto/commit/0ec4e97a2649dc15af1c925f8a2ff6adf1e17d9b))
7
+
8
+ # [1.105.0](https://github.com/stephenh/ts-proto/compare/v1.104.1...v1.105.0) (2022-02-12)
9
+
10
+
11
+ ### Features
12
+
13
+ * Bump ts-proto-descriptors. ([#489](https://github.com/stephenh/ts-proto/issues/489)) ([d454448](https://github.com/stephenh/ts-proto/commit/d454448b1889b1576c1ebcc6964a55a03af7d921)), closes [#493](https://github.com/stephenh/ts-proto/issues/493)
14
+
15
+ ## [1.104.1](https://github.com/stephenh/ts-proto/compare/v1.104.0...v1.104.1) (2022-02-12)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * make struct types play well with type registry ([#503](https://github.com/stephenh/ts-proto/issues/503)) ([d62f854](https://github.com/stephenh/ts-proto/commit/d62f85478011c7eb3dbca196f79b452895406ece))
21
+
22
+ # [1.104.0](https://github.com/stephenh/ts-proto/compare/v1.103.0...v1.104.0) (2022-01-21)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * Leave mixed case in all words. ([#488](https://github.com/stephenh/ts-proto/issues/488)) ([8a26c9c](https://github.com/stephenh/ts-proto/commit/8a26c9cba4c9897700aafe1a7f59d0b0f537764b))
28
+
29
+
30
+ ### Features
31
+
32
+ * enable prototype for defaults for ts-proto-descriptors ([#487](https://github.com/stephenh/ts-proto/issues/487)) ([2b5640f](https://github.com/stephenh/ts-proto/commit/2b5640f582e6adb4e81797a9cec217896061aadb))
33
+
1
34
  # [1.103.0](https://github.com/stephenh/ts-proto/compare/v1.102.2...v1.103.0) (2022-01-20)
2
35
 
3
36
 
package/README.markdown CHANGED
@@ -331,7 +331,7 @@ Generated code will be placed in the Gradle build directory.
331
331
 
332
332
  (Note that this only uses the grpc-web runtime, you don't need to use any of their generated code, i.e. the ts-proto output replaces their `ts-protoc-gen` output.)
333
333
 
334
- You'll need to add the `@improbable-eng/grpc-web` and a transport to your project's `package.json`; see the `integration/grpc-web` directory for a working example.
334
+ You'll need to add the `@improbable-eng/grpc-web` and a transport to your project's `package.json`; see the `integration/grpc-web` directory for a working example. Also see [#504](https://github.com/stephenh/ts-proto/issues/504) for integrating with [grpc-web-devtools](https://github.com/SafetyCulture/grpc-web-devtools).
335
335
 
336
336
  - With `--ts_proto_opt=returnObservable=true`, the return type of service methods will be `Observable<T>` instead of `Promise<T>`.
337
337
 
@@ -376,11 +376,22 @@ Generated code will be placed in the Gradle build directory.
376
376
 
377
377
  - With `--ts_proto_opt=unknownFields=true`, all unknown fields will be parsed and output as arrays of buffers.
378
378
 
379
- ### Only Types
379
+ - With `--ts_proto_opt=onlyTypes=true`, only types will be emitted, and imports for `long` and `protobufjs/minimal` will be excluded.
380
+
381
+ Note: _This is a combination_ of `outputJsonMethods=false,outputEncodeMethods=false,outputClientImpl=false,nestJs=false`
382
+
383
+ - With `--ts_proto_opt=usePrototypeForDefaults=true`, the generated code will wrap new objects with `Object.create`.
384
+
385
+ This allows code to do hazzer checks to detect when default values have been applied, which due to proto3's behavior of not putting default values on the wire, is typically only useful for interacting with proto2 messages.
380
386
 
387
+ When enabled, default values are inherited from a prototype, and so code can use Object.keys().includes("someField") to detect if someField was actually decoded or not.
388
+
389
+ Note that, as indicated, this means Object.keys will not include set-by-default fields, so if you have code that iterates over messages keys in a generic fashion, it will have to also iterate over keys inherited from the prototype.
390
+
391
+ ### Only Types
381
392
  If you're looking for `ts-proto` to generate only types for your Protobuf types then passing all three of `outputEncodeMethods`, `outputJsonMethods`, and `outputClientImpl` as `false` is probably what you want, i.e.:
382
393
 
383
- `--ts_proto_opt=outputEncodeMethods=false,outputJsonMethods=false,outputClientImpl=false`.
394
+ `--ts_proto_opt=onlyTypes=true`.
384
395
 
385
396
  ### NestJS Support
386
397
 
package/build/case.js CHANGED
@@ -7,13 +7,9 @@ function maybeSnakeToCamel(s, options) {
7
7
  return s
8
8
  .split('_')
9
9
  .map((word, i) => {
10
- if (i === 0) {
11
- // if first symbol is "_" then skip it
12
- return word ? word[0] + (hasLowerCase ? word.substring(1) : word.substring(1).toLowerCase()) : '';
13
- }
14
- else {
15
- return capitalize(word.toLowerCase());
16
- }
10
+ // If the word is already mixed case, leave the exist case as-is
11
+ word = hasLowerCase ? word : word.toLowerCase();
12
+ return i === 0 ? word : capitalize(word);
17
13
  })
18
14
  .join('');
19
15
  }
package/build/main.js CHANGED
@@ -934,6 +934,9 @@ function generateFromJson(ctx, fullName, messageDesc) {
934
934
  else if (types_1.isAnyValueType(field) || types_1.isStructType(field)) {
935
935
  return ts_poet_1.code `${from}`;
936
936
  }
937
+ else if (types_1.isFieldMaskType(field)) {
938
+ return ts_poet_1.code `{paths: ${from}.split(",")}`;
939
+ }
937
940
  else if (types_1.isListValueType(field)) {
938
941
  return ts_poet_1.code `[...${from}]`;
939
942
  }
@@ -1151,6 +1154,9 @@ function generateToJson(ctx, fullName, messageDesc) {
1151
1154
  else if (types_1.isAnyValueType(field)) {
1152
1155
  return ts_poet_1.code `${from}`;
1153
1156
  }
1157
+ else if (types_1.isFieldMaskType(field)) {
1158
+ return ts_poet_1.code `${from}.paths.join()`;
1159
+ }
1154
1160
  else if (types_1.isMessage(field) && !types_1.isValueType(ctx, field) && !types_1.isMapType(ctx, messageDesc, field)) {
1155
1161
  const type = types_1.basicTypeName(ctx, field, { keepValueType: true });
1156
1162
  return ts_poet_1.code `${from} ? ${type}.toJSON(${from}) : ${types_1.defaultValue(ctx, field)}`;
@@ -1323,7 +1329,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1323
1329
  && object.${oneofName}?.${fieldName} !== null
1324
1330
  ) {
1325
1331
  message.${oneofName} = { $case: '${fieldName}', ${fieldName}: ${v} };
1326
- }
1332
+ }
1327
1333
  `);
1328
1334
  }
1329
1335
  else if (readSnippet(`x`).toCodeString() == 'x') {
@@ -1349,7 +1355,7 @@ function generateWrap(ctx, fullProtoTypeName) {
1349
1355
  const chunks = [];
1350
1356
  if (types_1.isStructTypeName(fullProtoTypeName)) {
1351
1357
  chunks.push(ts_poet_1.code `wrap(object: {[key: string]: any} | undefined): Struct {
1352
- const struct = Struct.fromPartial({});
1358
+ const struct = createBaseStruct();
1353
1359
  if (object !== undefined) {
1354
1360
  Object.keys(object).forEach(key => {
1355
1361
  struct.fields[key] = object[key];
@@ -1361,50 +1367,58 @@ function generateWrap(ctx, fullProtoTypeName) {
1361
1367
  if (types_1.isAnyValueTypeName(fullProtoTypeName)) {
1362
1368
  if (ctx.options.oneof === options_1.OneofOption.UNIONS) {
1363
1369
  chunks.push(ts_poet_1.code `wrap(value: any): Value {
1364
- if (value === null) {
1365
- return {kind: {$case: 'nullValue', nullValue: NullValue.NULL_VALUE}};
1366
- } else if (typeof value === 'boolean') {
1367
- return {kind: {$case: 'boolValue', boolValue: value}};
1368
- } else if (typeof value === 'number') {
1369
- return {kind: {$case: 'numberValue', numberValue: value}};
1370
- } else if (typeof value === 'string') {
1371
- return {kind: {$case: 'stringValue', stringValue: value}};
1372
- } else if (Array.isArray(value)) {
1373
- return {kind: {$case: 'listValue', listValue: value}};
1374
- } else if (typeof value === 'object') {
1375
- return {kind: {$case: 'structValue', structValue: value}};
1376
- } else if (typeof value === 'undefined') {
1377
- return {} as Value;
1378
- } else {
1379
- throw new Error('Unsupported any value type: ' + typeof value);
1380
- }
1370
+ const result = createBaseValue();
1371
+
1372
+ if (value === null) {
1373
+ result.kind = {$case: 'nullValue', nullValue: NullValue.NULL_VALUE};
1374
+ } else if (typeof value === 'boolean') {
1375
+ result.kind = {$case: 'boolValue', boolValue: value};
1376
+ } else if (typeof value === 'number') {
1377
+ result.kind = {$case: 'numberValue', numberValue: value};
1378
+ } else if (typeof value === 'string') {
1379
+ result.kind = {$case: 'stringValue', stringValue: value};
1380
+ } else if (Array.isArray(value)) {
1381
+ result.kind = {$case: 'listValue', listValue: value};
1382
+ } else if (typeof value === 'object') {
1383
+ result.kind = {$case: 'structValue', structValue: value};
1384
+ } else if (typeof value !== 'undefined') {
1385
+ throw new Error('Unsupported any value type: ' + typeof value);
1386
+ }
1387
+
1388
+ return result;
1381
1389
  }`);
1382
1390
  }
1383
1391
  else {
1384
1392
  chunks.push(ts_poet_1.code `wrap(value: any): Value {
1385
- if (value === null) {
1386
- return {nullValue: NullValue.NULL_VALUE} as Value;
1387
- } else if (typeof value === 'boolean') {
1388
- return {boolValue: value} as Value;
1389
- } else if (typeof value === 'number') {
1390
- return {numberValue: value} as Value;
1391
- } else if (typeof value === 'string') {
1392
- return {stringValue: value} as Value;
1393
- } else if (Array.isArray(value)) {
1394
- return {listValue: value} as Value;
1395
- } else if (typeof value === 'object') {
1396
- return {structValue: value} as Value;
1397
- } else if (typeof value === 'undefined') {
1398
- return {} as Value;
1399
- } else {
1400
- throw new Error('Unsupported any value type: ' + typeof value);
1401
- }
1393
+ const result = createBaseValue();
1394
+
1395
+ if (value === null) {
1396
+ result.nullValue = NullValue.NULL_VALUE;
1397
+ } else if (typeof value === 'boolean') {
1398
+ result.boolValue = value;
1399
+ } else if (typeof value === 'number') {
1400
+ result.numberValue = value;
1401
+ } else if (typeof value === 'string') {
1402
+ result.stringValue = value;
1403
+ } else if (Array.isArray(value)) {
1404
+ result.listValue = value;
1405
+ } else if (typeof value === 'object') {
1406
+ result.structValue = value;
1407
+ } else if (typeof value !== 'undefined') {
1408
+ throw new Error('Unsupported any value type: ' + typeof value);
1409
+ }
1410
+
1411
+ return result;
1402
1412
  }`);
1403
1413
  }
1404
1414
  }
1405
1415
  if (types_1.isListValueTypeName(fullProtoTypeName)) {
1406
1416
  chunks.push(ts_poet_1.code `wrap(value: Array<any> | undefined): ListValue {
1407
- return {values: value ?? []};
1417
+ const result = createBaseListValue();
1418
+
1419
+ result.values = value ?? [];
1420
+
1421
+ return result;
1408
1422
  }`);
1409
1423
  }
1410
1424
  return chunks;
package/build/schema.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateSchema = void 0;
4
+ const ts_proto_descriptors_1 = require("ts-proto-descriptors");
4
5
  const ts_poet_1 = require("ts-poet");
5
6
  const visit_1 = require("./visit");
6
7
  const utils_1 = require("./utils");
@@ -36,7 +37,7 @@ function generateSchema(ctx, fileDesc, sourceInfo) {
36
37
  return ts_poet_1.code `${ts_poet_1.imp(`protoMetadata@./${dep.replace('.proto', '')}`)}`;
37
38
  });
38
39
  // Use toObject so that we get enums as numbers (instead of the default toJSON behavior)
39
- const descriptor = { ...fileDesc };
40
+ const descriptor = ts_proto_descriptors_1.FileDescriptorProto.fromPartial(fileDesc);
40
41
  // Only keep locations that include comments
41
42
  descriptor.sourceCodeInfo = {
42
43
  location: ((_a = descriptor.sourceCodeInfo) === null || _a === void 0 ? void 0 : _a.location.filter((loc) => loc['leadingComments'] || loc['trailingComments'])) || [],
package/build/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.detectBatchMethod = exports.responsePromiseOrObservable = exports.responseObservable = exports.responsePromise = exports.responseType = exports.requestType = exports.rawRequestType = exports.detectMapType = exports.toTypeName = exports.getEnumMethod = exports.messageToTypeName = exports.wrapperTypeName = exports.valueTypeName = exports.isEmptyType = exports.isLongValueType = exports.isStructTypeName = exports.isStructType = exports.isListValueTypeName = exports.isListValueType = exports.isBytesValueType = exports.isAnyValueTypeName = exports.isAnyValueType = exports.isValueType = exports.isTimestamp = exports.isObjectId = exports.isMapType = exports.isWholeNumber = exports.isLong = exports.isRepeated = exports.isWithinOneOfThatShouldBeUnion = exports.isWithinOneOf = exports.isEnum = exports.isMessage = exports.isBytes = exports.isPrimitive = exports.isOptionalProperty = exports.isScalar = exports.createTypeMap = exports.notDefaultCheck = exports.defaultValue = exports.packedType = exports.toReaderCall = exports.basicTypeName = exports.basicLongWireType = exports.basicWireType = void 0;
3
+ exports.detectBatchMethod = exports.responsePromiseOrObservable = exports.responseObservable = exports.responsePromise = exports.responseType = exports.requestType = exports.rawRequestType = exports.detectMapType = exports.toTypeName = exports.getEnumMethod = exports.messageToTypeName = exports.wrapperTypeName = exports.valueTypeName = exports.isEmptyType = exports.isLongValueType = exports.isStructTypeName = exports.isStructType = exports.isListValueTypeName = exports.isListValueType = exports.isFieldMaskTypeName = exports.isFieldMaskType = exports.isBytesValueType = exports.isAnyValueTypeName = exports.isAnyValueType = exports.isValueType = exports.isTimestamp = exports.isObjectId = exports.isMapType = exports.isWholeNumber = exports.isLong = exports.isRepeated = exports.isWithinOneOfThatShouldBeUnion = exports.isWithinOneOf = exports.isEnum = exports.isMessage = exports.isBytes = exports.isPrimitive = exports.isOptionalProperty = exports.isScalar = exports.createTypeMap = exports.notDefaultCheck = exports.defaultValue = exports.packedType = exports.toReaderCall = exports.basicTypeName = exports.basicLongWireType = exports.basicWireType = void 0;
4
4
  const ts_proto_descriptors_1 = require("ts-proto-descriptors");
5
5
  const ts_poet_1 = require("ts-poet");
6
6
  const options_1 = require("./options");
@@ -403,6 +403,14 @@ function isBytesValueType(field) {
403
403
  return field.typeName === '.google.protobuf.BytesValue';
404
404
  }
405
405
  exports.isBytesValueType = isBytesValueType;
406
+ function isFieldMaskType(field) {
407
+ return isFieldMaskTypeName(field.typeName);
408
+ }
409
+ exports.isFieldMaskType = isFieldMaskType;
410
+ function isFieldMaskTypeName(typeName) {
411
+ return typeName === 'google.protobuf.FieldMask' || typeName === '.google.protobuf.FieldMask';
412
+ }
413
+ exports.isFieldMaskTypeName = isFieldMaskTypeName;
406
414
  function isListValueType(field) {
407
415
  return isListValueTypeName(field.typeName);
408
416
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.103.0",
3
+ "version": "1.105.1",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",
@@ -64,6 +64,6 @@
64
64
  "object-hash": "^1.3.1",
65
65
  "protobufjs": "^6.8.8",
66
66
  "ts-poet": "^4.5.0",
67
- "ts-proto-descriptors": "1.3.1"
67
+ "ts-proto-descriptors": "1.6.0"
68
68
  }
69
69
  }