ts-proto 1.92.2 → 1.93.3

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,31 @@
1
+ ## [1.93.3](https://github.com/stephenh/ts-proto/compare/v1.93.2...v1.93.3) (2021-12-13)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * support mutliple options in snakeToCamel flag ([#429](https://github.com/stephenh/ts-proto/issues/429)) ([cff6674](https://github.com/stephenh/ts-proto/commit/cff667406cba21676546fd91b04cf2cbc571ed7d)), closes [#423](https://github.com/stephenh/ts-proto/issues/423)
7
+
8
+ ## [1.93.2](https://github.com/stephenh/ts-proto/compare/v1.93.1...v1.93.2) (2021-12-09)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * standalone dockerized protoc alias ([#438](https://github.com/stephenh/ts-proto/issues/438)) ([466f7d9](https://github.com/stephenh/ts-proto/commit/466f7d91551c6297fc1b9677f7a5839f8cdba0c6))
14
+
15
+ ## [1.93.1](https://github.com/stephenh/ts-proto/compare/v1.93.0...v1.93.1) (2021-12-08)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * Unwrap google.protobuf.BytesValue to Buffer when env=node ([#439](https://github.com/stephenh/ts-proto/issues/439)) ([73aa836](https://github.com/stephenh/ts-proto/commit/73aa8368300818068f3cddc5f046d990c66ab4f2))
21
+
22
+ # [1.93.0](https://github.com/stephenh/ts-proto/compare/v1.92.2...v1.93.0) (2021-12-08)
23
+
24
+
25
+ ### Features
26
+
27
+ * Allow optional suffix for generated files ([#431](https://github.com/stephenh/ts-proto/issues/431)) ([d826966](https://github.com/stephenh/ts-proto/commit/d826966f22830920444963b3894ffc0be9b7c319))
28
+
1
29
  ## [1.92.2](https://github.com/stephenh/ts-proto/compare/v1.92.1...v1.92.2) (2021-12-08)
2
30
 
3
31
 
package/README.markdown CHANGED
@@ -289,9 +289,7 @@ Generated code will be placed in the Gradle build directory.
289
289
 
290
290
  - With `--ts_proto_opt=lowerCaseServiceMethods=true`, the method names of service methods will be lowered/camel-case, i.e. `service.findFoo` instead of `service.FindFoo`.
291
291
 
292
- - With `--ts_proto_opt=snakeToCamel=false`, fields will be kept snake case.
293
-
294
- Defaults to `true`.
292
+ - With `--ts_proto_opt=snakeToCamel=false`, fields will be kept snake case. `snakeToCamel` can also be set as string with `--ts_proto_opt=snakeToCamel=keys,json`. `keys` will keep field names as camelCase and `json` will keep json field names as camelCase. Empty string will keep field names as snake_case.
295
293
 
296
294
  - With `--ts_proto_opt=outputEncodeMethods=false`, the `Message.encode` and `Message.decode` methods for working with protobuf-encoded/binary data will not be output.
297
295
 
@@ -348,6 +346,8 @@ Generated code will be placed in the Gradle build directory.
348
346
  - With `--ts_proto_opt=emitImportedFiles=false`, ts-proto will not emit `google/protobuf/*` files unless you explicit add files to `protoc` like this
349
347
  `protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto my_message.proto google/protobuf/duration.proto`
350
348
 
349
+ - With `--ts_proto_opt=fileSuffix=<SUFFIX>`, ts-proto will emit generated files using the specified suffix. A `helloworld.proto` file with `fileSuffix=.pb` would be generated as `helloworld.pb.ts`. This is common behavior in other protoc plugins and provides a way to quickly glob all the generated files.
350
+
351
351
  ### Only Types
352
352
 
353
353
  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.:
package/build/case.js CHANGED
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.camelCase = exports.capitalize = exports.camelToSnake = exports.maybeSnakeToCamel = void 0;
3
+ exports.camelCase = exports.capitalize = exports.camelToSnake = exports.stringToSnakeCase = exports.maybeSnakeToCamel = void 0;
4
4
  function maybeSnakeToCamel(s, options) {
5
- if (options.snakeToCamel && s.includes('_')) {
5
+ const fromStringSnakeToCamel = typeof options.snakeToCamel === 'string' && options.snakeToCamel.includes('keys');
6
+ const fromBooleanSnakeToCamel = options.snakeToCamel === true;
7
+ if ((fromBooleanSnakeToCamel || fromStringSnakeToCamel) && s.includes('_')) {
6
8
  return s
7
9
  .split('_')
8
10
  .map((word, i) => {
@@ -21,6 +23,10 @@ function maybeSnakeToCamel(s, options) {
21
23
  }
22
24
  }
23
25
  exports.maybeSnakeToCamel = maybeSnakeToCamel;
26
+ function stringToSnakeCase(s) {
27
+ return s.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
28
+ }
29
+ exports.stringToSnakeCase = stringToSnakeCase;
24
30
  function camelToSnake(s) {
25
31
  return s
26
32
  .replace(/[\w]([A-Z])/g, function (m) {
package/build/encode.js CHANGED
@@ -4,24 +4,25 @@ exports.generateDecoder = exports.generateEncoder = void 0;
4
4
  const ts_poet_1 = require("ts-poet");
5
5
  const types_1 = require("./types");
6
6
  const options_1 = require("./options");
7
+ const utils_1 = require("./utils");
7
8
  function generateEncoder(ctx, typeName) {
8
9
  const name = types_1.wrapperTypeName(typeName);
9
10
  if (!name) {
10
11
  return ts_poet_1.code `${types_1.messageToTypeName(ctx, typeName, { keepValueType: true })}.encode(value).finish()`;
11
12
  }
12
13
  if (name == 'Timestamp') {
13
- const TimestampValue = ts_poet_1.imp(`${name}@./google/protobuf/timestamp`);
14
+ const TimestampValue = utils_1.impProto(ctx.options, 'google/protobuf/timestamp', name);
14
15
  return ts_poet_1.code `${TimestampValue}.encode(${ctx.utils.toTimestamp}(value)).finish()`;
15
16
  }
16
17
  if (name == 'Struct') {
17
- const StructType = ts_poet_1.imp(`${name}@./google/protobuf/struct`);
18
+ const StructType = utils_1.impProto(ctx.options, 'google/protobuf/struct', name);
18
19
  return ts_poet_1.code `${StructType}.encode(${StructType}.wrap(value)).finish()`;
19
20
  }
20
21
  if (name == 'ListValue') {
21
- const ListValueType = ts_poet_1.imp(`${name}@./google/protobuf/struct`);
22
+ const ListValueType = utils_1.impProto(ctx.options, 'google/protobuf/struct', name);
22
23
  return ts_poet_1.code `${ListValueType}.encode({values: value ?? []}).finish()`;
23
24
  }
24
- const TypeValue = ts_poet_1.imp(`${name}@./google/protobuf/wrappers`);
25
+ const TypeValue = utils_1.impProto(ctx.options, 'google/protobuf/wrappers', name);
25
26
  switch (name) {
26
27
  case 'StringValue':
27
28
  return ts_poet_1.code `${TypeValue}.encode({value: value ?? ""}).finish()`;
@@ -45,20 +46,21 @@ function generateEncoder(ctx, typeName) {
45
46
  }
46
47
  exports.generateEncoder = generateEncoder;
47
48
  function generateDecoder(ctx, typeName) {
49
+ const { options } = ctx;
48
50
  let name = types_1.wrapperTypeName(typeName);
49
51
  if (!name) {
50
52
  return ts_poet_1.code `${types_1.messageToTypeName(ctx, typeName, { keepValueType: true })}.decode(value)`;
51
53
  }
52
54
  let TypeValue;
53
55
  if (name == 'Timestamp') {
54
- TypeValue = ts_poet_1.imp(`${name}@./google/protobuf/timestamp`);
56
+ TypeValue = utils_1.impProto(ctx.options, 'google/protobuf/timestamp', name);
55
57
  return ts_poet_1.code `${TypeValue}.decode(value)`;
56
58
  }
57
59
  if (name == 'Struct' || name == 'ListValue') {
58
- TypeValue = ts_poet_1.imp(`${name}@./google/protobuf/struct`);
60
+ TypeValue = utils_1.impProto(ctx.options, 'google/protobuf/struct', name);
59
61
  return ts_poet_1.code `${TypeValue}.unwrap(${TypeValue}.decode(value))`;
60
62
  }
61
- TypeValue = ts_poet_1.imp(`${name}@./google/protobuf/wrappers`);
63
+ TypeValue = utils_1.impProto(ctx.options, 'google/protobuf/wrappers', name);
62
64
  return ts_poet_1.code `${TypeValue}.decode(value).value`;
63
65
  }
64
66
  exports.generateDecoder = generateDecoder;
package/build/main.js CHANGED
@@ -30,7 +30,8 @@ function generateFile(ctx, fileDesc) {
30
30
  //
31
31
  // We'll also assume that the fileDesc.name is already the `company/foo.proto` path, with
32
32
  // the package already implicitly in it, so we won't re-append/strip/etc. it out/back in.
33
- const moduleName = fileDesc.name.replace('.proto', '.ts');
33
+ const suffix = `${options.fileSuffix}.ts`;
34
+ const moduleName = fileDesc.name.replace('.proto', suffix);
34
35
  const chunks = [];
35
36
  // Indicate this file's source protobuf package for reflective use with google.protobuf.Any
36
37
  if (options.exportCommonSymbols) {
@@ -316,7 +317,7 @@ function makeDeepPartial(options, longs) {
316
317
  return { Builtin, DeepPartial, Exact };
317
318
  }
318
319
  function makeTimestampMethods(options, longs) {
319
- const Timestamp = ts_poet_1.imp('Timestamp@./google/protobuf/timestamp');
320
+ const Timestamp = utils_1.impProto(options, 'google/protobuf/timestamp', 'Timestamp');
320
321
  let seconds = 'date.getTime() / 1_000';
321
322
  let toNumberCode = 't.seconds';
322
323
  if (options.forceLong === options_1.LongOption.LONG) {
@@ -530,7 +531,7 @@ function generateDecode(ctx, fullName, messageDesc) {
530
531
  }
531
532
  else if (types_1.isEnum(field)) {
532
533
  if (options.stringEnums) {
533
- const fromJson = types_1.getEnumMethod(typeMap, field.typeName, 'FromJSON');
534
+ const fromJson = types_1.getEnumMethod(ctx, field.typeName, 'FromJSON');
534
535
  readSnippet = ts_poet_1.code `${fromJson}(${readSnippet})`;
535
536
  }
536
537
  else {
@@ -629,7 +630,7 @@ function generateEncode(ctx, fullName, messageDesc) {
629
630
  let writeSnippet;
630
631
  if (types_1.isEnum(field) && options.stringEnums) {
631
632
  const tag = ((field.number << 3) | types_1.basicWireType(field.type)) >>> 0;
632
- const toNumber = types_1.getEnumMethod(typeMap, field.typeName, 'ToNumber');
633
+ const toNumber = types_1.getEnumMethod(ctx, field.typeName, 'ToNumber');
633
634
  writeSnippet = (place) => ts_poet_1.code `writer.uint32(${tag}).${types_1.toReaderCall(field)}(${toNumber}(${place}))`;
634
635
  }
635
636
  else if (types_1.isScalar(field) || types_1.isEnum(field)) {
@@ -691,7 +692,7 @@ function generateEncode(ctx, fullName, messageDesc) {
691
692
  // embedded inside of it, and we want to drop that so that we can encode it packed
692
693
  // (i.e. just one tag and multiple values).
693
694
  const tag = ((field.number << 3) | 2) >>> 0;
694
- const toNumber = types_1.getEnumMethod(typeMap, field.typeName, 'ToNumber');
695
+ const toNumber = types_1.getEnumMethod(ctx, field.typeName, 'ToNumber');
695
696
  chunks.push(ts_poet_1.code `
696
697
  writer.uint32(${tag}).fork();
697
698
  for (const v of message.${fieldName}) {
@@ -771,7 +772,7 @@ function generateFromJson(ctx, fullName, messageDesc) {
771
772
  // get a generic 'reader.doSomething' bit that is specific to the basic type
772
773
  const readSnippet = (from) => {
773
774
  if (types_1.isEnum(field)) {
774
- const fromJson = types_1.getEnumMethod(typeMap, field.typeName, 'FromJSON');
775
+ const fromJson = types_1.getEnumMethod(ctx, field.typeName, 'FromJSON');
775
776
  return ts_poet_1.code `${fromJson}(${from})`;
776
777
  }
777
778
  else if (types_1.isPrimitive(field)) {
@@ -943,7 +944,7 @@ function generateToJson(ctx, fullName, messageDesc) {
943
944
  const jsonName = utils_1.determineFieldJsonName(field, options);
944
945
  const readSnippet = (from) => {
945
946
  if (types_1.isEnum(field)) {
946
- const toJson = types_1.getEnumMethod(typeMap, field.typeName, 'ToJSON');
947
+ const toJson = types_1.getEnumMethod(ctx, field.typeName, 'ToJSON');
947
948
  return types_1.isWithinOneOf(field)
948
949
  ? ts_poet_1.code `${from} !== undefined ? ${toJson}(${from}) : undefined`
949
950
  : ts_poet_1.code `${toJson}(${from})`;
@@ -961,7 +962,7 @@ function generateToJson(ctx, fullName, messageDesc) {
961
962
  // For map types, drill-in and then admittedly re-hard-code our per-value-type logic
962
963
  const valueType = typeMap.get(field.typeName)[2].field[1];
963
964
  if (types_1.isEnum(valueType)) {
964
- const toJson = types_1.getEnumMethod(typeMap, valueType.typeName, 'ToJSON');
965
+ const toJson = types_1.getEnumMethod(ctx, valueType.typeName, 'ToJSON');
965
966
  return ts_poet_1.code `${toJson}(${from})`;
966
967
  }
967
968
  else if (types_1.isBytes(valueType)) {
@@ -1052,7 +1053,7 @@ function generateToJson(ctx, fullName, messageDesc) {
1052
1053
  function generateFromPartial(ctx, fullName, messageDesc) {
1053
1054
  const { options, utils, typeMap } = ctx;
1054
1055
  const chunks = [];
1055
- const Timestamp = ts_poet_1.imp('Timestamp@./google/protobuf/timestamp');
1056
+ const Timestamp = utils_1.impProto(options, 'google/protobuf/timestamp', 'Timestamp');
1056
1057
  // create the basic function declaration
1057
1058
  const paramName = messageDesc.field.length > 0 ? 'object' : '_';
1058
1059
  chunks.push(ts_poet_1.code `
package/build/options.js CHANGED
@@ -40,6 +40,7 @@ function defaultOptions() {
40
40
  useDate: DateOption.DATE,
41
41
  oneof: OneofOption.PROPERTIES,
42
42
  esModuleInterop: false,
43
+ fileSuffix: '',
43
44
  lowerCaseServiceMethods: false,
44
45
  outputEncodeMethods: true,
45
46
  outputJsonMethods: true,
package/build/types.js CHANGED
@@ -411,7 +411,7 @@ function valueTypeName(ctx, typeName) {
411
411
  case '.google.protobuf.BoolValue':
412
412
  return ts_poet_1.code `boolean`;
413
413
  case '.google.protobuf.BytesValue':
414
- return ts_poet_1.code `Uint8Array`;
414
+ return ctx.options.env === options_1.EnvOption.NODE ? ts_poet_1.code `Buffer` : ts_poet_1.code `Uint8Array`;
415
415
  case '.google.protobuf.ListValue':
416
416
  return ts_poet_1.code `Array<any>`;
417
417
  case '.google.protobuf.Value':
@@ -481,16 +481,16 @@ function messageToTypeName(ctx, protoType, typeOptions = {}) {
481
481
  }
482
482
  }
483
483
  const [module, type] = toModuleAndType(typeMap, protoType);
484
- return ts_poet_1.code `${ts_poet_1.imp(`${type}@./${module}`)}`;
484
+ return ts_poet_1.code `${utils_1.impProto(options, module, type)}`;
485
485
  }
486
486
  exports.messageToTypeName = messageToTypeName;
487
487
  /** Breaks `.some_proto_namespace.Some.Message` into `['some_proto_namespace', 'Some_Message', Descriptor]. */
488
488
  function toModuleAndType(typeMap, protoType) {
489
489
  return typeMap.get(protoType) || utils_1.fail(`No type found for ${protoType}`);
490
490
  }
491
- function getEnumMethod(typeMap, enumProtoType, methodSuffix) {
492
- const [module, type] = toModuleAndType(typeMap, enumProtoType);
493
- return ts_poet_1.imp(`${case_1.camelCase(type)}${methodSuffix}@./${module}`);
491
+ function getEnumMethod(ctx, enumProtoType, methodSuffix) {
492
+ const [module, type] = toModuleAndType(ctx.typeMap, enumProtoType);
493
+ return utils_1.impProto(ctx.options, module, `${case_1.camelCase(type)}${methodSuffix}`);
494
494
  }
495
495
  exports.getEnumMethod = getEnumMethod;
496
496
  /** Return the TypeName for any field (primitive/message/etc.) as exposed in the interface. */
package/build/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.determineFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.prefixDisableLinter = exports.maybeAddComment = exports.upperFirst = exports.lowerFirst = exports.singular = exports.fail = exports.readToBuffer = exports.protoFilesToGenerate = void 0;
3
+ exports.impProto = exports.determineFieldJsonName = exports.FormattedMethodDescriptor = exports.assertInstanceOf = exports.maybePrefixPackage = exports.prefixDisableLinter = exports.maybeAddComment = exports.upperFirst = exports.lowerFirst = exports.singular = exports.fail = exports.readToBuffer = exports.protoFilesToGenerate = void 0;
4
4
  const ts_poet_1 = require("ts-poet");
5
5
  const options_1 = require("./options");
6
6
  const case_1 = require("./case");
@@ -147,9 +147,15 @@ exports.FormattedMethodDescriptor = FormattedMethodDescriptor;
147
147
  function determineFieldJsonName(field, options) {
148
148
  // By default jsonName is camelCased by the protocol compilier unless the user has
149
149
  // set a "json_name" option on this field.
150
- if (field.jsonName.length > 0) {
150
+ const fromStringSnakeToCamel = typeof options.snakeToCamel === 'string' && options.snakeToCamel.includes('json');
151
+ const fromBooleanSnakeToCamel = options.snakeToCamel === true;
152
+ if (fromBooleanSnakeToCamel || fromStringSnakeToCamel) {
151
153
  return field.jsonName;
152
154
  }
153
- return case_1.maybeSnakeToCamel(field.name, options);
155
+ return case_1.stringToSnakeCase(field.name);
154
156
  }
155
157
  exports.determineFieldJsonName = determineFieldJsonName;
158
+ function impProto(options, module, type) {
159
+ return ts_poet_1.imp(`${type}@./${module}${options.fileSuffix}`);
160
+ }
161
+ exports.impProto = impProto;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.92.2",
3
+ "version": "1.93.3",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",