ts-proto 1.112.2 → 1.114.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,24 @@
1
+ ## [1.114.2](https://github.com/stephenh/ts-proto/compare/v1.114.1...v1.114.2) (2022-05-28)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Try combined workflow. ([c293c1f](https://github.com/stephenh/ts-proto/commit/c293c1f379cb69635c968d5b8094135931bcea54))
7
+
8
+ # [1.114.0](https://github.com/stephenh/ts-proto/compare/v1.113.0...v1.114.0) (2022-05-27)
9
+
10
+
11
+ ### Features
12
+
13
+ * Official Buf Plugin ([#573](https://github.com/stephenh/ts-proto/issues/573)) ([e6272c4](https://github.com/stephenh/ts-proto/commit/e6272c487f73ff96afb4146a7998a892c4b43f14))
14
+
15
+ # [1.113.0](https://github.com/stephenh/ts-proto/compare/v1.112.2...v1.113.0) (2022-05-27)
16
+
17
+
18
+ ### Features
19
+
20
+ * add options to schema output ([#437](https://github.com/stephenh/ts-proto/issues/437)) ([e8e4e39](https://github.com/stephenh/ts-proto/commit/e8e4e3937292e07280f5154b584e60124118f093))
21
+
1
22
  ## [1.112.2](https://github.com/stephenh/ts-proto/compare/v1.112.1...v1.112.2) (2022-05-18)
2
23
 
3
24
 
package/README.markdown CHANGED
@@ -13,17 +13,17 @@
13
13
  - [Table of contents](#table-of-contents)
14
14
  - [Overview](#overview)
15
15
  - [QuickStart](#quickstart)
16
- - [Buf](#buf)
16
+ - [Buf](#buf)
17
17
  - [Goals](#goals)
18
18
  - [Example Types](#example-types)
19
19
  - [Highlights](#highlights)
20
20
  - [Auto-Batching / N+1 Prevention](#auto-batching--n1-prevention)
21
21
  - [Usage](#usage)
22
- - [Supported options](#supported-options)
23
- - [Only Types](#only-types)
24
- - [NestJS Support](#nestjs-support)
25
- - [Watch Mode](#watch-mode)
26
- - [Basic gRPC implementation](#basic-grpc-implementation)
22
+ - [Supported options](#supported-options)
23
+ - [Only Types](#only-types)
24
+ - [NestJS Support](#nestjs-support)
25
+ - [Watch Mode](#watch-mode)
26
+ - [Basic gRPC implementation](#basic-grpc-implementation)
27
27
  - [Sponsors](#sponsors)
28
28
  - [Development](#development)
29
29
  - [Assumptions](#assumptions)
@@ -97,7 +97,16 @@ plugins:
97
97
  out: ../gen/ts
98
98
  strategy: all
99
99
  path: ../node_modules/ts-proto/protoc-gen-ts_proto
100
- ```
100
+ ```
101
+
102
+ You can also use the official plugin published to the Buf Registry.
103
+
104
+ ```yaml
105
+ version: v1
106
+ plugins:
107
+ - remote: buf.build/roundrock-io/plugins/ts-proto
108
+ out: ../gen/ts
109
+ ```
101
110
 
102
111
  # Goals
103
112
 
@@ -174,7 +183,7 @@ creating a class and calling the right getters/setters.
174
183
 
175
184
  (Configurable with the `useDate` parameter.)
176
185
 
177
- - `fromJSON`/`toJSON` use the [proto3 canonical JSON encoding format](https://developers.google.com/protocol-buffers/docs/proto3#json) (e.g. timestamps are ISO strings), unlike [`protobufjs`](https://github.com/protobufjs/protobuf.js/issues/1304).
186
+ - `fromJSON`/`toJSON` use the [proto3 canonical JSON encoding format](https://developers.google.com/protocol-buffers/docs/proto3#json) (e.g. timestamps are ISO strings), unlike [`protobufjs`](https://github.com/protobufjs/protobuf.js/issues/1304).
178
187
 
179
188
  - ObjectIds can be mapped as `mongodb.ObjectId`
180
189
 
@@ -220,7 +229,7 @@ protoc --plugin=node_modules/ts-proto/protoc-gen-ts_proto ./batching.proto -I.
220
229
 
221
230
  `ts-proto` can also be invoked with [Gradle](https://gradle.org) using the [protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin):
222
231
 
223
- ``` groovy
232
+ ```groovy
224
233
  protobuf {
225
234
  plugins {
226
235
  // `ts` can be replaced by any unused plugin name, e.g. `tsproto`
@@ -366,19 +375,19 @@ Generated code will be placed in the Gradle build directory.
366
375
 
367
376
  - With `--ts_proto_opt=metadataType=Foo@./some-file`, ts-proto add a generic (framework-agnostic) metadata field to the generic service definition.
368
377
 
369
- - With `--ts_proto_opt=outputServices=generic-definitions,outputServices=default`, ts-proto will output both generic definitions and interfaces. This is useful if you want to rely on the interfaces, but also have some reflection capabilities at runtime.
378
+ - With `--ts_proto_opt=outputServices=generic-definitions,outputServices=default`, ts-proto will output both generic definitions and interfaces. This is useful if you want to rely on the interfaces, but also have some reflection capabilities at runtime.
370
379
 
371
380
  - With `--ts_proto_opt=outputServices=false`, or `=none`, ts-proto will output NO service definitions.
372
381
 
373
382
  - With `--ts_proto_opt=emitImportedFiles=false`, ts-proto will not emit `google/protobuf/*` files unless you explicit add files to `protoc` like this
374
- `protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto my_message.proto google/protobuf/duration.proto`
383
+ `protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto my_message.proto google/protobuf/duration.proto`
375
384
 
376
- - 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.
385
+ - 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.
377
386
 
378
387
  - With `--ts_proto_opt=enumsAsLiterals=true`, the generated enum types will be enum-ish object with `as const`.
379
388
 
380
389
  - With `--ts_proto_opt=useExactTypes=false`, the generated `fromPartial` method will not use Exact types.
381
-
390
+
382
391
  The default behavior is `useExactTypes=true`, which makes `fromPartial` use Exact type for its argument to make TypeScript reject any unknown properties.
383
392
 
384
393
  - With `--ts_proto_opt=unknownFields=true`, all unknown fields will be parsed and output as arrays of buffers.
@@ -396,6 +405,7 @@ Generated code will be placed in the Gradle build directory.
396
405
  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.
397
406
 
398
407
  ### Only Types
408
+
399
409
  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.:
400
410
 
401
411
  `--ts_proto_opt=onlyTypes=true`.
@@ -417,7 +427,7 @@ If you want to run `ts-proto` on every change of a proto file, you'll need to us
417
427
 
418
428
  `ts-proto` is RPC framework agnostic - how you transmit your data to and from
419
429
  your data source is up to you. The generated client implementations all expect
420
- a `rpc` parameter, which type is defined like this:
430
+ a `rpc` parameter, which type is defined like this:
421
431
 
422
432
  ```ts
423
433
  interface Rpc {
@@ -425,7 +435,7 @@ interface Rpc {
425
435
  }
426
436
  ```
427
437
 
428
- If you're working with gRPC, a simple implementation could look like this:
438
+ If you're working with gRPC, a simple implementation could look like this:
429
439
 
430
440
  ```ts
431
441
  type RpcImpl = (service: string, method: string, data: Uint8Array) => Promise<Uint8Array>;
@@ -455,14 +465,14 @@ const sendRequest: RpcImpl = (service, method, data) => {
455
465
  });
456
466
  };
457
467
 
458
- const rpc: Rpc = { request: sendRequest }
468
+ const rpc: Rpc = { request: sendRequest };
459
469
  ```
460
470
 
461
471
  # Sponsors
462
472
 
463
473
  Kudos to our sponsors:
464
474
 
465
- * [ngrok](https://ngrok.com) funded ts-proto's initial grpc-web support.
475
+ - [ngrok](https://ngrok.com) funded ts-proto's initial grpc-web support.
466
476
 
467
477
  If you need ts-proto customizations or priority support for your company, you can ping me at [via email](mailto:stephen.haberman@gmail.com).
468
478
 
@@ -481,9 +491,10 @@ The commands below assume you have **Docker** installed. To use a **local** copy
481
491
  - Run `yarn install` to install the dependencies.
482
492
  - Run `yarn build:test` or `yarn build:test:local` to generate the test files.
483
493
  > _This runs the following commands:_
484
- > - `proto2bin` — Converts integration test `.proto` files to `.bin`.
485
- > - `bin2ts` — Runs `ts-proto` on the `.bin` files to generate `.ts` files.
486
- > - `proto2pbjs` — Generates a reference implementation using `pbjs` for testing compatibility.
494
+ >
495
+ > - `proto2bin` — Converts integration test `.proto` files to `.bin`.
496
+ > - `bin2ts` — Runs `ts-proto` on the `.bin` files to generate `.ts` files.
497
+ > - `proto2pbjs` — Generates a reference implementation using `pbjs` for testing compatibility.
487
498
  - Run `yarn test`
488
499
 
489
500
  **Workflow**
@@ -494,8 +505,8 @@ The commands below assume you have **Docker** installed. To use a **local** copy
494
505
  _Since the proto files were not changed, you only need to regenerate the typescript files._
495
506
  - Run `yarn test` to verify the typescript files are compatible with the reference implementation, and pass other tests.
496
507
  - Updating or adding `.proto` files in the integration directory:
497
- - Run `yarn watch` to automatically regenerate test files when proto files change.
498
- - Or run `yarn build:test` to regenerate all integration test files.
508
+ - Run `yarn watch` to automatically regenerate test files when proto files change.
509
+ - Or run `yarn build:test` to regenerate all integration test files.
499
510
  - Run `yarn test` to retest.
500
511
 
501
512
  **Contributing**
@@ -503,7 +514,7 @@ The commands below assume you have **Docker** installed. To use a **local** copy
503
514
  - Run `yarn build:test` and `yarn test` to make sure everything works.
504
515
  - Run `yarn prettier` to format the typescript files.
505
516
  - Commit the changes:
506
- - Also include the generated `.bin` files for the tests where you added or modified `.proto` files.
517
+ - Also include the generated `.bin` files for the tests where you added or modified `.proto` files.
507
518
  > These are checked into git so that the test suite can run without having to invoke the `protoc` build chain.
508
519
  - Also include the generated `.ts` files.
509
520
  - Create a pull request
@@ -594,7 +605,7 @@ Foo.encode({ bar: '' }); // => { }, writes an empty Foo object, in protobuf bina
594
605
  Reading JSON will also initialize the default values. Since senders may either omit unset fields, or set them to the default value, use `fromJSON` to normalize the input.
595
606
 
596
607
  ```typescript
597
- Foo.fromJSON({ }); // => { bar: '' }
608
+ Foo.fromJSON({}); // => { bar: '' }
598
609
  Foo.fromJSON({ bar: '' }); // => { bar: '' }
599
610
  Foo.fromJSON({ bar: 'baz' }); // => { bar: 'baz' }
600
611
  ```
@@ -603,7 +614,7 @@ When writing JSON, `ts-proto` currently does **not** normalize message when conv
603
614
 
604
615
  ```typescript
605
616
  // Current ts-proto behavior
606
- Foo.toJSON({ }); // => { }
617
+ Foo.toJSON({}); // => { }
607
618
  Foo.toJSON({ bar: undefined }); // => { }
608
619
  Foo.toJSON({ bar: '' }); // => { bar: '' } - note: this is the default value, but it's not omitted
609
620
  Foo.toJSON({ bar: 'baz' }); // => { bar: 'baz' }
@@ -611,13 +622,13 @@ Foo.toJSON({ bar: 'baz' }); // => { bar: 'baz' }
611
622
 
612
623
  ```typescript
613
624
  // Possible future behavior, where ts-proto would normalize message
614
- Foo.toJSON({ }); // => { }
625
+ Foo.toJSON({}); // => { }
615
626
  Foo.toJSON({ bar: undefined }); // => { }
616
627
  Foo.toJSON({ bar: '' }); // => { } - note: omitting the default value, as expected
617
628
  Foo.toJSON({ bar: 'baz' }); // => { bar: 'baz' }
618
629
  ```
619
630
 
620
- - Please open an issue if you need this behavior.
631
+ - Please open an issue if you need this behavior.
621
632
 
622
633
  # Well-Known Types
623
634
 
@@ -626,25 +637,24 @@ Their interpretation is defined by the Protobuf specification, and libraries are
626
637
 
627
638
  `ts-proto` currently automatically converts these messages to their corresponding native types.
628
639
 
629
- * [google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#boolvalue) &lrarr; `boolean`
630
- * [google.protobuf.BytesValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#bytesvalue) &lrarr; `Uint8Array`
631
- * [google.protobuf.DoubleValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#doublevalue) &lrarr; `number`
632
- * [google.protobuf.FieldMask](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask) &lrarr; `string[]`
633
- * [google.protobuf.FloatValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#floatvalue) &lrarr; `number`
634
- * [google.protobuf.Int32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#int32value) &lrarr; `number`
635
- * [google.protobuf.Int64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#int64value) &lrarr; `number`
636
- * [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#listvalue) &lrarr; `any[]`
637
- * [google.protobuf.UInt32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#uint32value) &lrarr; `number`
638
- * [google.protobuf.UInt64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#uint64value) &lrarr; `number`
639
- * [google.protobuf.StringValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#stringvalue) &lrarr; `string`
640
- * [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#value) &lrarr; `any` (i.e. `number | string | boolean | null | array | object`)
641
- * [google.protobuf.Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#struct) &lrarr; `{ [key: string]: any }`
640
+ - [google.protobuf.BoolValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#boolvalue) &lrarr; `boolean`
641
+ - [google.protobuf.BytesValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#bytesvalue) &lrarr; `Uint8Array`
642
+ - [google.protobuf.DoubleValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#doublevalue) &lrarr; `number`
643
+ - [google.protobuf.FieldMask](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask) &lrarr; `string[]`
644
+ - [google.protobuf.FloatValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#floatvalue) &lrarr; `number`
645
+ - [google.protobuf.Int32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#int32value) &lrarr; `number`
646
+ - [google.protobuf.Int64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#int64value) &lrarr; `number`
647
+ - [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#listvalue) &lrarr; `any[]`
648
+ - [google.protobuf.UInt32Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#uint32value) &lrarr; `number`
649
+ - [google.protobuf.UInt64Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#uint64value) &lrarr; `number`
650
+ - [google.protobuf.StringValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#stringvalue) &lrarr; `string`
651
+ - [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#value) &lrarr; `any` (i.e. `number | string | boolean | null | array | object`)
652
+ - [google.protobuf.Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#struct) &lrarr; `{ [key: string]: any }`
642
653
 
643
654
  ## Wrapper Types
644
655
 
645
656
  Wrapper Types are messages containing a single primitive field, and can be imported in `.proto` files with `import "google/protobuf/wrappers.proto"`.
646
657
 
647
-
648
658
  Since these are _messages_, their default value is `undefined`, allowing you to distinguish unset primitives from their default values, when using Wrapper Types.
649
659
  `ts-proto` generates these fields as `<primitive> | undefined`.
650
660
 
@@ -671,13 +681,13 @@ interface ExampleMessage {
671
681
  When encoding a message the primitive value is converted back to its corresponding wrapper type:
672
682
 
673
683
  ```typescript
674
- ExampleMessage.encode({ name: 'foo' }) // => { name: { value: 'foo' } }, in binary
684
+ ExampleMessage.encode({ name: 'foo' }); // => { name: { value: 'foo' } }, in binary
675
685
  ```
676
686
 
677
687
  When calling toJSON, the value is not converted, because wrapper types are idiomatic in JSON.
678
688
 
679
689
  ```typescript
680
- ExampleMessage.toJSON({ name: 'foo' }) // => { name: 'foo' }
690
+ ExampleMessage.toJSON({ name: 'foo' }); // => { name: 'foo' }
681
691
  ```
682
692
 
683
693
  ## JSON Types (Struct Types)
@@ -687,7 +697,7 @@ For this reason, Protobuf offers several additional types to represent arbitrary
687
697
 
688
698
  These are called Struct Types, and can be imported in `.proto` files with `import "google/protobuf/struct.proto"`.
689
699
 
690
- - [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Value) &lrarr; `any`
700
+ - [google.protobuf.Value](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#Value) &lrarr; `any`
691
701
  - This is the most general type, and can represent any JSON value (i.e. `number | string | boolean | null | array | object`).
692
702
  - [google.protobuf.ListValue](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#ListValue) &lrarr; `any[]`
693
703
  - To represent a JSON array
@@ -717,8 +727,9 @@ interface ExampleMessage {
717
727
  ```
718
728
 
719
729
  Encoding a JSON value embedded in a message, converts it to a Struct Type:
730
+
720
731
  ```typescript
721
- ExampleMessage.encode({ anything: { "name": "hello" } })
732
+ ExampleMessage.encode({ anything: { name: 'hello' } });
722
733
  /* Outputs the following structure, encoded in protobuf binary format:
723
734
  {
724
735
  anything: Value {
@@ -735,7 +746,7 @@ ExampleMessage.encode({ anything: { "name": "hello" } })
735
746
  }
736
747
  }*/
737
748
 
738
- ExampleMessage.encode({ anything: true })
749
+ ExampleMessage.encode({ anything: true });
739
750
  /* Outputs the following structure encoded in protobuf binary format:
740
751
  {
741
752
  anything: Value {
package/build/main.js CHANGED
@@ -453,7 +453,7 @@ function makeNiceGrpcServerStreamingMethodResult() {
453
453
  const NiceGrpcServerStreamingMethodResult = ts_poet_1.conditionalOutput('ServerStreamingMethodResult', ts_poet_1.code `
454
454
  export type ServerStreamingMethodResult<Response> = {
455
455
  [Symbol.asyncIterator](): AsyncIterator<Response, void>;
456
- };
456
+ };
457
457
  `);
458
458
  return { NiceGrpcServerStreamingMethodResult };
459
459
  }
@@ -1004,7 +1004,8 @@ function generateFromJson(ctx, fullName, fullTypeName, messageDesc) {
1004
1004
  return ts_poet_1.code `Long.fromValue(${from} as Long | string)`;
1005
1005
  }
1006
1006
  else if (types_1.isEnum(valueField)) {
1007
- return ts_poet_1.code `${from} as ${valueType}`;
1007
+ const fromJson = types_1.getEnumMethod(ctx, valueField.typeName, 'FromJSON');
1008
+ return ts_poet_1.code `${fromJson}(${from})`;
1008
1009
  }
1009
1010
  else {
1010
1011
  const cstr = case_1.capitalize(valueType.toCodeString());
package/build/schema.js CHANGED
@@ -5,16 +5,50 @@ const ts_proto_descriptors_1 = require("ts-proto-descriptors");
5
5
  const ts_poet_1 = require("ts-poet");
6
6
  const visit_1 = require("./visit");
7
7
  const utils_1 = require("./utils");
8
+ const types_1 = require("./types");
9
+ const minimal_1 = require("protobufjs/minimal");
8
10
  const fileDescriptorProto = ts_poet_1.imp('FileDescriptorProto@ts-proto-descriptors');
11
+ const extensionCache = {};
9
12
  function generateSchema(ctx, fileDesc, sourceInfo) {
10
13
  var _a;
11
14
  const { options } = ctx;
12
15
  const chunks = [];
16
+ fileDesc.extension.forEach((extension) => {
17
+ if (!(extension.extendee in extensionCache)) {
18
+ extensionCache[extension.extendee] = {};
19
+ }
20
+ extensionCache[extension.extendee][extension.number] = extension;
21
+ });
13
22
  chunks.push(ts_poet_1.code `
23
+ type ProtoMetaMessageOptions = {
24
+ options?: { [key: string]: any };
25
+ fields?: { [key: string]: { [key: string]: any } };
26
+ oneof?: { [key: string]: { [key: string]: any } };
27
+ nested?: { [key: string]: ProtoMetaMessageOptions };
28
+ };
29
+
14
30
  export interface ProtoMetadata {
15
31
  fileDescriptor: ${fileDescriptorProto};
16
32
  references: { [key: string]: any };
17
33
  dependencies?: ProtoMetadata[];
34
+ options?: {
35
+ options?: { [key: string]: any };
36
+ services?: {
37
+ [key: string]: {
38
+ options?: { [key: string]: any };
39
+ methods?: { [key: string]: { [key: string]: any } };
40
+ }
41
+ };
42
+ messages?: {
43
+ [key: string]: ProtoMetaMessageOptions;
44
+ };
45
+ enums?: {
46
+ [key: string]: {
47
+ options?: { [key: string]: any };
48
+ values?: { [key: string]: { [key: string]: any } };
49
+ };
50
+ };
51
+ };
18
52
  }
19
53
  `);
20
54
  const references = [];
@@ -42,13 +76,167 @@ function generateSchema(ctx, fileDesc, sourceInfo) {
42
76
  descriptor.sourceCodeInfo = {
43
77
  location: ((_a = descriptor.sourceCodeInfo) === null || _a === void 0 ? void 0 : _a.location.filter((loc) => loc['leadingComments'] || loc['trailingComments'])) || [],
44
78
  };
79
+ let fileOptions;
80
+ if (fileDesc.options) {
81
+ fileOptions = encodedOptionsToOptions(ctx, '.google.protobuf.FileOptions', fileDesc.options['_unknownFields']);
82
+ delete fileDesc.options['_unknownFields'];
83
+ }
84
+ const messagesOptions = [];
85
+ (fileDesc.messageType || []).forEach((message) => {
86
+ const resolvedMessage = resolveMessageOptions(ctx, message);
87
+ if (resolvedMessage) {
88
+ messagesOptions.push(resolvedMessage);
89
+ }
90
+ });
91
+ const servicesOptions = [];
92
+ (fileDesc.service || []).forEach((service) => {
93
+ const methodsOptions = [];
94
+ service.method.forEach((method) => {
95
+ if (method.options) {
96
+ const methodOptions = encodedOptionsToOptions(ctx, '.google.protobuf.MethodOptions', method.options['_unknownFields']);
97
+ delete method.options['_unknownFields'];
98
+ if (methodOptions) {
99
+ methodsOptions.push(ts_poet_1.code `'${method.name}': ${methodOptions}`);
100
+ }
101
+ }
102
+ });
103
+ let serviceOptions;
104
+ if (service.options) {
105
+ serviceOptions = encodedOptionsToOptions(ctx, '.google.protobuf.ServiceOptions', service.options['_unknownFields']);
106
+ delete service.options['_unknownFields'];
107
+ }
108
+ if (methodsOptions.length > 0 || serviceOptions) {
109
+ servicesOptions.push(ts_poet_1.code `
110
+ '${service.name}': {
111
+ options: ${serviceOptions},
112
+ methods: {${ts_poet_1.joinCode(methodsOptions, { on: ',' })}}
113
+ }
114
+ `);
115
+ }
116
+ });
117
+ const enumsOptions = [];
118
+ (fileDesc.enumType || []).forEach((Enum) => {
119
+ const valuesOptions = [];
120
+ Enum.value.forEach((value) => {
121
+ if (value.options) {
122
+ const valueOptions = encodedOptionsToOptions(ctx, '.google.protobuf.EnumValueOptions', value.options['_unknownFields']);
123
+ delete value.options['_unknownFields'];
124
+ if (valueOptions) {
125
+ valuesOptions.push(ts_poet_1.code `'${value.name}': ${valueOptions}`);
126
+ }
127
+ }
128
+ });
129
+ let enumOptions;
130
+ if (Enum.options) {
131
+ enumOptions = encodedOptionsToOptions(ctx, '.google.protobuf.EnumOptions', Enum.options['_unknownFields']);
132
+ delete Enum.options['_unknownFields'];
133
+ }
134
+ if (valuesOptions.length > 0 || enumOptions) {
135
+ enumsOptions.push(ts_poet_1.code `
136
+ '${Enum.name}': {
137
+ options: ${enumOptions},
138
+ values: {${ts_poet_1.joinCode(valuesOptions, { on: ',' })}}
139
+ }
140
+ `);
141
+ }
142
+ });
45
143
  chunks.push(ts_poet_1.code `
46
144
  export const ${ts_poet_1.def('protoMetadata')}: ProtoMetadata = {
47
145
  fileDescriptor: ${fileDescriptorProto}.fromPartial(${descriptor}),
48
146
  references: { ${ts_poet_1.joinCode(references, { on: ',' })} },
49
147
  dependencies: [${ts_poet_1.joinCode(dependencies, { on: ',' })}],
148
+ ${fileOptions || messagesOptions.length > 0 || servicesOptions.length > 0 || enumsOptions.length > 0
149
+ ? ts_poet_1.code `options: {
150
+ ${fileOptions ? ts_poet_1.code `options: ${fileOptions},` : ''}
151
+ ${messagesOptions.length > 0 ? ts_poet_1.code `messages: {${ts_poet_1.joinCode(messagesOptions, { on: ',' })}},` : ''}
152
+ ${servicesOptions.length > 0 ? ts_poet_1.code `services: {${ts_poet_1.joinCode(servicesOptions, { on: ',' })}},` : ''}
153
+ ${enumsOptions.length > 0 ? ts_poet_1.code `enums: {${ts_poet_1.joinCode(enumsOptions, { on: ',' })}}` : ''}
154
+ }`
155
+ : ''}
50
156
  }
51
157
  `);
52
158
  return chunks;
53
159
  }
54
160
  exports.generateSchema = generateSchema;
161
+ function getExtensionValue(ctx, extension, data) {
162
+ if (extension.type == ts_proto_descriptors_1.FieldDescriptorProto_Type.TYPE_MESSAGE) {
163
+ const typeName = types_1.basicTypeName(ctx, extension);
164
+ const resultBuffer = Buffer.concat(data.map((d) => {
165
+ // Skip length byte
166
+ const reader = new minimal_1.Reader(d);
167
+ reader.uint32();
168
+ return reader.buf.slice(reader.pos);
169
+ }));
170
+ const result = resultBuffer.toString('base64');
171
+ return ts_poet_1.code `'${extension.name}': ${typeName}.decode(Buffer.from('${result}', 'base64'))`;
172
+ }
173
+ else {
174
+ const reader = new minimal_1.Reader(data[0]);
175
+ let value = reader[types_1.toReaderCall(extension)]();
176
+ if (typeof value === 'string') {
177
+ value = ts_poet_1.code `"${value}"`;
178
+ }
179
+ return ts_poet_1.code `'${extension.name}': ${value}`;
180
+ }
181
+ }
182
+ /** Takes the protoc's input of options as proto-encoded messages, and turns them into embedded-able-in-source-code representations. */
183
+ function encodedOptionsToOptions(ctx, extendee, encodedOptions) {
184
+ if (!encodedOptions) {
185
+ return undefined;
186
+ }
187
+ const resultOptions = [];
188
+ for (const [key, value] of Object.entries(encodedOptions)) {
189
+ const extension = extensionCache[extendee][parseInt(key, 10) >>> 3];
190
+ resultOptions.push(getExtensionValue(ctx, extension, value));
191
+ }
192
+ if (resultOptions.length == 0) {
193
+ return undefined;
194
+ }
195
+ return ts_poet_1.code `{${ts_poet_1.joinCode(resultOptions, { on: ',' })}}`;
196
+ }
197
+ function resolveMessageOptions(ctx, message) {
198
+ const fieldsOptions = [];
199
+ message.field.forEach((field) => {
200
+ if (field.options) {
201
+ const fieldOptions = encodedOptionsToOptions(ctx, '.google.protobuf.FieldOptions', field.options['_unknownFields']);
202
+ delete field.options['_unknownFields'];
203
+ if (fieldOptions) {
204
+ fieldsOptions.push(ts_poet_1.code `'${field.name}': ${fieldOptions}`);
205
+ }
206
+ }
207
+ });
208
+ const oneOfsOptions = [];
209
+ message.oneofDecl.forEach((oneOf) => {
210
+ if (oneOf.options) {
211
+ const oneOfOptions = encodedOptionsToOptions(ctx, '.google.protobuf.OneofOptions', oneOf.options['_unknownFields']);
212
+ delete oneOf.options['_unknownFields'];
213
+ if (oneOfOptions) {
214
+ oneOfsOptions.push(ts_poet_1.code `'${oneOf.name}': ${oneOfOptions}`);
215
+ }
216
+ }
217
+ });
218
+ let nestedOptions = [];
219
+ if (message.nestedType && message.nestedType.length > 0) {
220
+ message.nestedType.forEach((nested) => {
221
+ const resolvedMessage = resolveMessageOptions(ctx, nested);
222
+ if (resolvedMessage) {
223
+ nestedOptions.push(resolvedMessage);
224
+ }
225
+ });
226
+ }
227
+ let messageOptions;
228
+ if (message.options) {
229
+ messageOptions = encodedOptionsToOptions(ctx, '.google.protobuf.MessageOptions', message.options['_unknownFields']);
230
+ delete message.options['_unknownFields'];
231
+ }
232
+ if (fieldsOptions.length > 0 || oneOfsOptions.length > 0 || nestedOptions.length > 0 || messageOptions) {
233
+ return ts_poet_1.code `
234
+ '${message.name}': {
235
+ ${messageOptions ? ts_poet_1.code `options: ${messageOptions},` : ''}
236
+ ${fieldsOptions.length > 0 ? ts_poet_1.code `fields: {${ts_poet_1.joinCode(fieldsOptions, { on: ',' })}},` : ''}
237
+ ${oneOfsOptions.length > 0 ? ts_poet_1.code `oneof: {${ts_poet_1.joinCode(oneOfsOptions, { on: ',' })}},` : ''}
238
+ ${nestedOptions.length > 0 ? ts_poet_1.code `nested: {${ts_poet_1.joinCode(nestedOptions, { on: ',' })}},` : ''}
239
+ }
240
+ `;
241
+ }
242
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-proto",
3
- "version": "1.112.2",
3
+ "version": "1.114.2",
4
4
  "description": "",
5
5
  "main": "build/plugin.js",
6
6
  "repository": "github:stephenh/ts-proto",
@@ -41,6 +41,7 @@
41
41
  "@nestjs/microservices": "^8.2.2",
42
42
  "@semantic-release/changelog": "^5.0.1",
43
43
  "@semantic-release/commit-analyzer": "^8.0.1",
44
+ "@semantic-release/exec": "^6.0.3",
44
45
  "@semantic-release/git": "^9.0.0",
45
46
  "@semantic-release/github": "^7.2.0",
46
47
  "@semantic-release/npm": "^7.1.0",