ts-proto 1.82.4 → 1.83.2

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.83.2](https://github.com/stephenh/ts-proto/compare/v1.83.1...v1.83.2) (2021-10-26)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Add missing defaults to fromPartial if options.oneof is UNIONS ([#375](https://github.com/stephenh/ts-proto/issues/375)) ([21781e9](https://github.com/stephenh/ts-proto/commit/21781e98bb6117b540be8c3f2c38ac3ad5cbbb44))
7
+
8
+ ## [1.83.1](https://github.com/stephenh/ts-proto/compare/v1.83.0...v1.83.1) (2021-09-17)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * deprecated grpc and replace with @grpc/grpc-js ([#362](https://github.com/stephenh/ts-proto/issues/362)) ([1a11b97](https://github.com/stephenh/ts-proto/commit/1a11b97e9b5e92e79fdd4e22d3e8ea4536af243b))
14
+
15
+ # [1.83.0](https://github.com/stephenh/ts-proto/compare/v1.82.5...v1.83.0) (2021-09-12)
16
+
17
+
18
+ ### Features
19
+
20
+ * Service generation option ([#357](https://github.com/stephenh/ts-proto/issues/357)) ([7a2cf83](https://github.com/stephenh/ts-proto/commit/7a2cf831c3768e5afd76dea37f3165df4886136e))
21
+
22
+ ## [1.82.5](https://github.com/stephenh/ts-proto/compare/v1.82.4...v1.82.5) (2021-08-05)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * Field starting with '_' generates an interface property starting with 'undefined' ([#344](https://github.com/stephenh/ts-proto/issues/344)) ([fab354f](https://github.com/stephenh/ts-proto/commit/fab354f3f8f3aae51bb0377f98138bc80a1113e3))
28
+
1
29
  ## [1.82.4](https://github.com/stephenh/ts-proto/compare/v1.82.3...v1.82.4) (2021-08-04)
2
30
 
3
31
 
package/README.markdown CHANGED
@@ -230,7 +230,7 @@ Generated code will be placed in the Gradle build directory.
230
230
  The default behavior is `forceLong=number`, which will internally still use the `long` library to encode/decode values on the wire (so you will still see a `util.Long = Long` line in your output), but will convert the `long` values to `number` automatically for you. Note that a runtime error is thrown if, while doing this conversion, a 64-bit value is larger than can be correctly stored as a `number`.
231
231
 
232
232
  - With `--ts_proto_opt=esModuleInterop=true` changes output to be `esModuleInterop` compliant.
233
-
233
+
234
234
  Specifically the `Long` imports will be generated as `import Long from 'long'` instead of `import * as Long from 'long'`.
235
235
 
236
236
  - With `--ts_proto_opt=env=node` or `browser` or `both`, ts-proto will make environment-specific assumptions in your output. This defaults to `both`, which makes no environment-specific assumptions.
@@ -259,20 +259,20 @@ Generated code will be placed in the Gradle build directory.
259
259
  ```
260
260
 
261
261
  However, the type-safety of `useOptionals=false` is admittedly tedious if you have many inherently-unused fields, so you can use `useOptionals=true` if that trade-off makes sense for your project.
262
-
262
+
263
263
  You can also use the generated `SomeMessage.fromPartial` methods to opt into the optionality on a per-call-site basis. The `fromPartial` allows the creator/writer to have default values applied (i.e. `undefined` --> `0`), and the return value will still be the non-optional type that provides a consistent view (i.e. always `0`) to clients.
264
264
 
265
- Eventually if TypesCript supports [Exact Types](https://github.com/microsoft/TypeScript/issues/12936), that should allow ts-proto to switch to `useOptionals=true` as the default/only behavior, have the generated `Message.encode`/`Message.toPartial`/etc. methods accept `Exact<T>` versions of the message types, and the result would be both safe + succinct.
265
+ Eventually if TypeScript supports [Exact Types](https://github.com/microsoft/TypeScript/issues/12936), that should allow ts-proto to switch to `useOptionals=true` as the default/only behavior, have the generated `Message.encode`/`Message.toPartial`/etc. methods accept `Exact<T>` versions of the message types, and the result would be both safe + succinct.
266
266
 
267
267
  Also see the comment in [this issue](https://github.com/stephenh/ts-proto/issues/120#issuecomment-678375833) which explains the nuance behind making all fields optional (currently `useOptionals` only makes message fields optional), specifically that a message created with `const message: Message = { ...key not set... }` (so `key` is `undefined`) vs. `const message = Message.decode(...key not set...)` (so `key` is the default value) would look different to clients.
268
268
 
269
269
  Note that RPC methods, like `service.ping({ key: ... })`, accept `DeepPartial` versions of the request messages, because of the same rationale that it makes it easy for the writer call-site to get default values for free, and because the "reader" is the internal ts-proto serialization code, it can apply the defaults as necessary.
270
270
 
271
271
  - With `--ts_proto_opt=exportCommonSymbols=false`, utility types like `DeepPartial` won't be `export`d.
272
-
272
+
273
273
  This should make it possible to use create barrel imports of the generated output, i.e. `import * from ./foo` and `import * from ./bar`.
274
-
275
- Note that if you have the same message name used in multiple `*.proto` files, you will still get import conflicts.
274
+
275
+ Note that if you have the same message name used in multiple `*.proto` files, you will still get import conflicts.
276
276
 
277
277
  - With `--ts_proto_opt=oneof=unions`, `oneof` fields will be generated as ADTs.
278
278
 
@@ -336,6 +336,8 @@ Generated code will be placed in the Gradle build directory.
336
336
 
337
337
  - With `--ts_proto_opt=outputServices=generic-definitions`, ts-proto will output generic (framework-agnostic) service definitions.
338
338
 
339
+ - With `--ts_proto_opt=outputServices=false`, or `=none`, ts-proto will output NO service definitions.
340
+
339
341
  - With `--ts_proto_opt=emitImportedFiles=false`, ts-proto will not emit `google/protobuf/*` files unless you explicit add files to `protoc` like this
340
342
  `protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto my_message.proto google/protobuf/duration.proto`
341
343
 
@@ -410,7 +412,7 @@ If you want fields where you can model set/unset, see Wrapper Types.
410
412
  # Wrapper Types
411
413
 
412
414
  In core Protobuf, unset primitive fields become their respective default values (so you loose ability to distinguish "unset" from "default").
413
-
415
+
414
416
  However, unset message fields stay `null`.
415
417
 
416
418
  This allows a cute hack where you can model a logical `string | unset` by creating a field that is technically a message (i.e. so it can stay `null` for the unset case), but the message only has a single string field (i.e for storing the value in the set case).
@@ -426,9 +428,9 @@ This makes dealing with `string | unset` in your code much nicer, albeit it's un
426
428
  Numbers are by default assumed to be plain JavaScript `number`s.
427
429
 
428
430
  This is fine for Protobuf types like `int32` and `float`, but 64-bit types like `int64` can't be 100% represented by JavaScript's `number` type, because `int64` can have larger/smaller values than `number`.
429
-
431
+
430
432
  ts-proto's default configuration (which is `forceLong=number`) is to still use `number` for 64-bit fields, and then throw an error if a value (at runtime) is larger than `Number.MAX_SAFE_INTEGER`.
431
-
433
+
432
434
  If you expect to use 64-bit / higher-than-`MAX_SAFE_INTEGER` values, then you can use the ts-proto `forceLong` option, which uses the [long](https://www.npmjs.com/package/long) npm package to support the entire range of 64-bit values.
433
435
 
434
436
  The protobuf number types map to JavaScript types based on the `forceLong` config option:
package/build/case.js CHANGED
@@ -7,7 +7,8 @@ function maybeSnakeToCamel(s, options) {
7
7
  .split('_')
8
8
  .map((word, i) => {
9
9
  if (i === 0) {
10
- return word[0] + word.substring(1).toLowerCase();
10
+ // if first symbol is "_" then skip it
11
+ return word ? word[0] + word.substring(1).toLowerCase() : '';
11
12
  }
12
13
  else {
13
14
  return capitalize(word.toLowerCase());
@@ -10,7 +10,7 @@ function generateNestjsServiceController(ctx, fileDesc, sourceInfo, serviceDesc)
10
10
  var _a;
11
11
  const { options } = ctx;
12
12
  const chunks = [];
13
- const Metadata = options.outputServices === 'grpc-js' ? ts_poet_1.imp('Metadata@@grpc/grpc-js') : ts_poet_1.imp('Metadata@grpc');
13
+ const Metadata = ts_poet_1.imp('Metadata@@grpc/grpc-js');
14
14
  utils_1.maybeAddComment(sourceInfo, chunks, (_a = serviceDesc.options) === null || _a === void 0 ? void 0 : _a.deprecated);
15
15
  const t = options.context ? `<${main_1.contextTypeVar}>` : '';
16
16
  chunks.push(ts_poet_1.code `
@@ -73,7 +73,7 @@ exports.generateNestjsServiceController = generateNestjsServiceController;
73
73
  function generateNestjsServiceClient(ctx, fileDesc, sourceInfo, serviceDesc) {
74
74
  const { options } = ctx;
75
75
  const chunks = [];
76
- const Metadata = options.outputServices === 'grpc-js' ? ts_poet_1.imp('Metadata@@grpc/grpc-js') : ts_poet_1.imp('Metadata@grpc');
76
+ const Metadata = ts_poet_1.imp('Metadata@@grpc/grpc-js');
77
77
  utils_1.maybeAddComment(sourceInfo, chunks);
78
78
  const t = options.context ? `<${main_1.contextTypeVar}>` : ``;
79
79
  chunks.push(ts_poet_1.code `
@@ -48,7 +48,7 @@ function generateService(ctx, fileDesc, sourceInfo, serviceDesc) {
48
48
  params.push(ts_poet_1.code `metadata?: grpc.Metadata`);
49
49
  }
50
50
  else if (options.addGrpcMetadata) {
51
- const Metadata = ts_poet_1.imp('Metadata@grpc');
51
+ const Metadata = ts_poet_1.imp('Metadata@@grpc/grpc-js');
52
52
  const q = options.addNestjsRestParameter ? '' : '?';
53
53
  params.push(ts_poet_1.code `metadata${q}: ${Metadata}`);
54
54
  }
package/build/main.js CHANGED
@@ -107,13 +107,13 @@ function generateFile(ctx, fileDesc) {
107
107
  }
108
108
  chunks.push(ts_poet_1.code `export const ${serviceConstName} = "${serviceDesc.name}";`);
109
109
  }
110
- else if (options.outputServices === 'grpc-js') {
110
+ else if (options.outputServices === options_1.ServiceOption.GRPC) {
111
111
  chunks.push(generate_grpc_js_1.generateGrpcJsService(ctx, fileDesc, sInfo, serviceDesc));
112
112
  }
113
- else if (options.outputServices === 'generic-definitions') {
113
+ else if (options.outputServices === options_1.ServiceOption.GENERIC) {
114
114
  chunks.push(generate_generic_service_definition_1.generateGenericServiceDefinition(ctx, fileDesc, sInfo, serviceDesc));
115
115
  }
116
- else {
116
+ else if (options.outputServices === options_1.ServiceOption.DEFAULT) {
117
117
  // This service could be Twirp or grpc-web or JSON (maybe). So far all of their
118
118
  // interfaces are fairly similar so we share the same service interface.
119
119
  chunks.push(generate_services_1.generateService(ctx, fileDesc, sInfo, serviceDesc));
@@ -132,7 +132,7 @@ function generateFile(ctx, fileDesc) {
132
132
  }
133
133
  }
134
134
  });
135
- if (!options.outputServices && options.outputClientImpl && fileDesc.service.length > 0) {
135
+ if (options.outputServices === options_1.ServiceOption.DEFAULT && options.outputClientImpl && fileDesc.service.length > 0) {
136
136
  if (options.outputClientImpl === true) {
137
137
  chunks.push(generate_services_1.generateRpcType(ctx));
138
138
  }
@@ -239,6 +239,7 @@ function makeByteUtils() {
239
239
  const globalThis = ts_poet_1.conditionalOutput('globalThis', ts_poet_1.code `
240
240
  declare var self: any | undefined;
241
241
  declare var window: any | undefined;
242
+ declare var global: any | undefined;
242
243
  var globalThis: any = (() => {
243
244
  if (typeof globalThis !== "undefined") return globalThis;
244
245
  if (typeof self !== "undefined") return self;
@@ -1081,7 +1082,7 @@ function generateFromPartial(ctx, fullName, messageDesc) {
1081
1082
  chunks.push(ts_poet_1.code `message.${fieldName} = ${readSnippet(`object.${fieldName}`)};`);
1082
1083
  }
1083
1084
  }
1084
- if (!types_1.isRepeated(field) && options.oneof !== options_1.OneofOption.UNIONS) {
1085
+ if (!types_1.isRepeated(field) && !types_1.isWithinOneOfThatShouldBeUnion(options, field)) {
1085
1086
  chunks.push(ts_poet_1.code `} else {`);
1086
1087
  const v = types_1.isWithinOneOf(field) ? 'undefined' : types_1.defaultValue(ctx, field);
1087
1088
  chunks.push(ts_poet_1.code `message.${fieldName} = ${v}`);
package/build/options.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTsPoetOpts = exports.optionsFromParameter = exports.defaultOptions = exports.OneofOption = exports.EnvOption = exports.DateOption = exports.LongOption = void 0;
3
+ exports.getTsPoetOpts = exports.optionsFromParameter = exports.defaultOptions = exports.ServiceOption = exports.OneofOption = exports.EnvOption = exports.DateOption = exports.LongOption = void 0;
4
4
  var LongOption;
5
5
  (function (LongOption) {
6
6
  LongOption["NUMBER"] = "number";
@@ -24,6 +24,13 @@ var OneofOption;
24
24
  OneofOption["PROPERTIES"] = "properties";
25
25
  OneofOption["UNIONS"] = "unions";
26
26
  })(OneofOption = exports.OneofOption || (exports.OneofOption = {}));
27
+ var ServiceOption;
28
+ (function (ServiceOption) {
29
+ ServiceOption["GRPC"] = "grpc-js";
30
+ ServiceOption["GENERIC"] = "generic-definitions";
31
+ ServiceOption["DEFAULT"] = "default";
32
+ ServiceOption["NONE"] = "none";
33
+ })(ServiceOption = exports.ServiceOption || (exports.ServiceOption = {}));
27
34
  function defaultOptions() {
28
35
  return {
29
36
  context: false,
@@ -41,7 +48,7 @@ function defaultOptions() {
41
48
  stringEnums: false,
42
49
  constEnums: false,
43
50
  outputClientImpl: true,
44
- outputServices: false,
51
+ outputServices: ServiceOption.DEFAULT,
45
52
  returnObservable: false,
46
53
  addGrpcMetadata: false,
47
54
  addNestjsRestParameter: false,
@@ -80,6 +87,10 @@ function optionsFromParameter(parameter) {
80
87
  if (options.forceLong === true) {
81
88
  options.forceLong = LongOption.LONG;
82
89
  }
90
+ // Treat outputServices=false as NONE
91
+ if (options.outputServices === false) {
92
+ options.outputServices = ServiceOption.NONE;
93
+ }
83
94
  if (options.useDate === true) {
84
95
  // Treat useDate=true as DATE
85
96
  options.useDate = DateOption.DATE;
package/build/utils.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  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
+ const options_1 = require("./options");
5
6
  const case_1 = require("./case");
6
7
  function protoFilesToGenerate(request) {
7
8
  return request.protoFile.filter((f) => request.fileToGenerate.includes(f.name));
@@ -136,7 +137,7 @@ class FormattedMethodDescriptor {
136
137
  */
137
138
  static formatName(methodName, options) {
138
139
  let result = methodName;
139
- if (options.lowerCaseServiceMethods || options.outputServices === 'grpc-js') {
140
+ if (options.lowerCaseServiceMethods || options.outputServices === options_1.ServiceOption.GRPC) {
140
141
  result = case_1.camelCase(result);
141
142
  }
142
143
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.82.4",
3
+ "version": "1.83.2",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",